diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index adf1b05be2a825..c2bf65a1c27bcf 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,7 +1,7 @@ # Contribution ## Introduction -It is assumed that you know a little about node.js and git. If not, [here's some help to get started with git](https://help.github.com/en/github/using-git) and [here’s some help to get started with node.js.](https://nodejs.org/en/docs/guides/getting-started-guide/) +It is assumed that you know a little about Node.js and Git. If not, [here's some help to get started with Git](https://help.github.com/en/github/using-git) and [here’s some help to get started with Node.js.](https://nodejs.org/en/docs/guides/getting-started-guide/) * Install [Node.js](https://nodejs.org/) * Install [Git](https://git-scm.com/) @@ -26,25 +26,20 @@ As per the npm standard, ‘start’ is the place to begin the package. npm start -This script will start a local server similar to [threejs.org](https://threejs.org/), but instead will be hosted on your local machine. Browse to http://localhost:8080/ to check it out. It also automatically creates the ‘build/three.js’ and ‘build/three.module.js’ scripts anytime there is a change within your three.js directory. +This script will start a local server similar to [threejs.org](https://threejs.org/), but instead will be hosted on your local machine. Browse to https://localhost:8080/ to check it out. It also automatically creates the `build/three.module.js` script anytime there is a change `src` directory. -The next most important script runs all the appropriate testing. The E-2-E testing is intended to be run by github actions. +Next scripts run all the appropriate testing. -Run this command from the root folder to install test dependencies. - - npm install --prefix test - -And run tests. - - npm test +- `npm run test` - Lint testing and unit testing (individually being `npm run lint` and `npm run test-unit`) +- `npm run test-e2e` - E2E testing. This one can take quite a long time and installs ~200 MB Chromium browser - it is primarily intended to be run only by GitHub Actions The linting is there to keep a consistent code style across all of the code and the testing is there to help catch bugs and check that the code behaves as expected. It is important that neither of these steps comes up with any errors due to your changes. -Many linting errors can be fixed automatically by running +Most linting errors can be fixed automatically by running - npm lint-fix + npm run lint-fix -If you’d like to make a minified version of the build files i.e. ‘build/three.min.js’ run: +If you’d like to make a build of the source files (e.g. `build/three.module.js`) run: npm run build @@ -72,16 +67,12 @@ When you’ve decided to make changes, start with the following: * Don't include any build files in your commit. * Not all new features will need a new example. Simpler features could be incorporated into an existing example. Bigger features may be asked to add an example demonstrating the feature. * Making changes may require changes to the documentation. To update the docs in other languages, simply copy the English to begin with. -* it's good to also add an example and screenshot for it, for showing how it's used and for end-to-end testing. +* It's good to also add an example and screenshot for it, for showing how it's used and for end-to-end testing. * If you modify existing code, run relevant examples to check they didn't break and there wasn't performance regress. * If you add some assets for the examples (models, textures, sounds, etc), make sure they have a proper license allowing for their use here, less restrictive the better. It is unlikely for large assets to be accepted. * If some issue is relevant to the patch/feature, please mention it with a hash (e.g. #2774) in a commit message to get cross-reference in GitHub. -* If you modify files in `examples/jsm` directory, then don't perform any changes in the `examples/js`, non-module files are auto-generated by running `npm run build-examples`. -* If the end-to-end test failed in Travis and you are sure that all is correct, make a new screenshot with - - npm run make-screenshot ... - -* Once done with a patch/feature do not add more commits to a feature branch +* If the end-to-end test failed and you are sure that all is correct, follow the instructions it outputs. +* Once done with a patch/feature do not add more commits to a feature branch. * Create separate branches per patch or feature. * If you make a PR but it is not actually ready to be pulled into the dev branch then please [convert it to a draft PR](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/changing-the-stage-of-a-pull-request#converting-a-pull-request-to-a-draft). 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 deleted file mode 100644 index e402d12b901109..00000000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -name: Bug report -about: Report a reproducible bug or regression. -title: '' -labels: '' -assignees: '' - ---- - - - -**Describe the bug** - -A clear and concise description of what the bug is. Before submitting, please remove unnecessary sections. - -**To Reproduce** - -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. See error - -***Code*** - -```js -// code goes here -``` - -***Live example*** - -* [jsfiddle-latest-release](https://jsfiddle.net/hyok6tvj/) -* [jsfiddle-dev](https://jsfiddle.net/c5m1kazu/) - -**Expected behavior** - -A clear and concise description of what you expected to happen. - -**Screenshots** - -If applicable, add screenshots to help explain your problem (drag and drop the image). - -**Platform:** - - - Device: [Desktop, Mobile] - - OS: [Windows, MacOS, Linux, Android, iOS] - - Browser: [Chrome, Firefox, Safari, Edge] - - Three.js version: [dev, r???] diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000000000..176ed7e4a3058d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,85 @@ +name: Bug Report +description: File a reproducible bug or regression. +body: + - type: textarea + id: description + attributes: + label: Description + description: A clear and concise description of what the bug is. + validations: + required: true + - type: textarea + id: repro + attributes: + label: Reproduction steps + description: How do you trigger this bug? Please walk us through it step by step. + value: | + 1. + 2. + 3. + validations: + required: true + - type: textarea + id: code + attributes: + label: Code + value: | + ```js + // code goes here + ``` + validations: + required: true + - type: textarea + id: example + attributes: + label: Live example + value: | + * [jsfiddle-latest-release](https://jsfiddle.net/g3atw6k5/) + * [jsfiddle-dev](https://jsfiddle.net/hjqw94c5/) + validations: + required: true + - type: textarea + id: screenshots + attributes: + label: Screenshots + description: If applicable, add screenshots to help explain your problem (drag and drop the image). + validations: + required: false + - type: input + id: version + attributes: + label: Version + description: What version of the library are you using? + placeholder: r + validations: + required: true + - type: dropdown + id: device + attributes: + label: Device + multiple: true + options: + - Desktop + - Mobile + - Headset + - type: dropdown + id: browser + attributes: + label: Browser + multiple: true + options: + - Chrome + - Firefox + - Safari + - Edge + - type: dropdown + id: os + attributes: + label: OS + multiple: true + options: + - Windows + - MacOS + - Linux + - Android + - iOS diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 5bf95474b6f2da..00000000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for the project. -title: '' -labels: '' -assignees: '' - ---- - - - -**Is your feature request related to a problem? Please describe.** - -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** - -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** - -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** - -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000000000..ca123042741f5a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,34 @@ +name: Feature request +description: Suggest an idea for the project. +body: + - type: textarea + id: description + attributes: + label: Description + description: Is your feature request related to a problem? Please describe. + placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + validations: + required: true + - type: textarea + id: solution + attributes: + label: Solution + description: Describe the solution you'd like. + placeholder: A clear and concise description of what you want to happen. + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Alternatives + description: Describe alternatives you've considered. + placeholder: A clear and concise description of any alternative solutions or features you've considered. + validations: + required: true + - type: textarea + id: additional + attributes: + label: Additional context + description: Add any other context about the feature request here. + validations: + required: false diff --git a/.github/codeql-config.yml b/.github/codeql-config.yml new file mode 100644 index 00000000000000..d397d52e1bf691 --- /dev/null +++ b/.github/codeql-config.yml @@ -0,0 +1,7 @@ +paths-ignore: + - "docs/prettify/**/*.*" + - "editor/js/libs/**/*.*" + - "examples/jsm/libs/**/*.*" + - "examples/jsm/loaders/ifc/**/*.*" + - "build/*.*" + - "manual/3rdparty/**/*.*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bff19c28c5aacc..b8bac271f4951b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,15 +12,17 @@ on: - 'docs/**' - 'files/**' -jobs: +permissions: + contents: read +jobs: lint: - name: "Linting" + name: "Lint testing" runs-on: ubuntu-latest steps: - name: Git checkout uses: actions/checkout@v2 - - name: Install node + - name: Install Node uses: actions/setup-node@v2 with: node-version: 16 @@ -28,7 +30,7 @@ jobs: - name: Install packages run: npm ci - - name: === Linting === + - name: === Lint testing === run: npm run lint unit: @@ -37,15 +39,13 @@ jobs: steps: - name: Git checkout uses: actions/checkout@v2 - - name: Install node + - name: Install Node uses: actions/setup-node@v2 with: node-version: 16 cache: 'npm' - name: Install packages - run: | - npm ci - npm ci --prefix test + run: npm ci - name: Build run: npm run build @@ -54,9 +54,11 @@ jobs: e2e: name: "E2E testing" - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: + os: [ windows-latest, ubuntu-latest ] CI: [ 0, 1, 2, 3, 4, 5, 6, 7 ] env: CI: ${{ matrix.CI }} @@ -64,29 +66,26 @@ jobs: steps: - name: Git checkout uses: actions/checkout@v2 - - name: Install node + - name: Install Node uses: actions/setup-node@v2 with: node-version: 16 cache: 'npm' - name: Install packages - run: | - npm ci - npm ci --prefix test - sudo apt-get install xvfb + run: npm ci - name: Build run: npm run build - name: === E2E testing === - run: xvfb-run --auto-servernum npm run test-e2e + run: npm run test-e2e e2e-cov: - name: "Ready for release" + name: "Examples ready for release" runs-on: ubuntu-latest steps: - name: Git checkout uses: actions/checkout@v2 - - name: Install node + - name: Install Node uses: actions/setup-node@v2 with: node-version: 16 @@ -94,5 +93,5 @@ jobs: - name: Install packages run: npm ci - - name: === Ready for release === + - name: === Examples ready for release === run: npm run test-e2e-cov diff --git a/.github/workflows/codeql-code-scanning.yml b/.github/workflows/codeql-code-scanning.yml new file mode 100644 index 00000000000000..dfd9bf36c79bc4 --- /dev/null +++ b/.github/workflows/codeql-code-scanning.yml @@ -0,0 +1,45 @@ +name: "CodeQL" + +on: + push: + branches: [ "dev" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "dev" ] + schedule: + - cron: '29 23 * * 0' + workflow_dispatch: + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql-config.yml + queries: security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.gitignore b/.gitignore index 81c965b1d6a06f..6895a6a437988c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,21 +7,11 @@ npm-debug.log .jshintrc .vs/ -# The command'npm install --prefix test' adds files in the test folder (https://docs.npmjs.com/configuring-npm/folders.html#executables). -# There are 2 kinds of files, those without extension and those with cmd extension. -# To ignore files without a extension, following procedure is nessecary: -# - ignore all files in the test folder -# - unignore all files in subdirectories of the test folder -# - unignore all files with an extension in the test folder -test/* -!test/*/ -!test/*.* -test/*.cmd test/unit/build test/treeshake/index.bundle.js test/treeshake/index.bundle.min.js test/treeshake/index-src.bundle.min.js test/treeshake/stats.html - +test/e2e/chromium **/node_modules \ No newline at end of file diff --git a/.lgtm.yml b/.lgtm.yml deleted file mode 100644 index 19321e09943a2b..00000000000000 --- a/.lgtm.yml +++ /dev/null @@ -1,13 +0,0 @@ -path_classifiers: - library: - - "editor/js/libs/**/*.*" - - "examples/jsm/libs/**/*.*" - - "examples/js/libs/**/*.*" - - "examples/jsm/loaders/ifc/**/*.*" - - "examples/js/loaders/ifc/**/*.*" - test: - - exclude: / - docs: - - exclude: / - generated: - - "build/*.*" \ No newline at end of file diff --git a/LICENSE b/LICENSE index b90fa96a3200d2..d07e209686512b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright © 2010-2022 three.js authors +Copyright © 2010-2023 three.js authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 418af5fd91042e..a032a35c7a140f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -three.js -======== +# three.js [![NPM Package][npm]][npm-url] [![Build Size][build-size]][build-size-url] @@ -7,19 +6,20 @@ three.js [![DeepScan][deepscan]][deepscan-url] [![Discord][discord]][discord-url] -#### JavaScript 3D library #### +#### 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 ### +### Usage This code creates a scene, a camera, and a geometric cube, and it adds the cube to the scene. It then creates a `WebGL` renderer for the scene and camera, and it adds that viewport to the `document.body` element. Finally, it animates the cube within the scene for the camera. @@ -58,7 +58,7 @@ function animation( time ) { If everything went well, you should see [this](https://jsfiddle.net/7u84j6kp/). -### Cloning this repository ### +### Cloning this repository Cloning the repo with all its history results in a ~2 GB download. If you don't need the whole history you can use the `depth` parameter to significantly reduce download size. @@ -66,7 +66,7 @@ Cloning the repo with all its history results in a ~2 GB download. If you don't git clone --depth=1 https://github.com/mrdoob/three.js.git ``` -### Change log ### +### Change log [Releases](https://github.com/mrdoob/three.js/releases) diff --git a/build/three.cjs b/build/three.cjs index 17e23ca92a1f27..559a30276c06c5 100644 --- a/build/three.cjs +++ b/build/three.cjs @@ -1,27 +1,13 @@ /** * @license - * Copyright 2010-2022 Three.js Authors + * Copyright 2010-2023 Three.js Authors * SPDX-License-Identifier: MIT */ 'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); - -const REVISION = '141dev'; -const MOUSE = { - LEFT: 0, - MIDDLE: 1, - RIGHT: 2, - ROTATE: 0, - DOLLY: 1, - PAN: 2 -}; -const TOUCH = { - ROTATE: 0, - PAN: 1, - DOLLY_PAN: 2, - DOLLY_ROTATE: 3 -}; +const REVISION = '150dev'; +const MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 }; +const TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 }; const CullFaceNone = 0; const CullFaceBack = 1; const CullFaceFront = 2; @@ -33,8 +19,7 @@ const VSMShadowMap = 3; const FrontSide = 0; const BackSide = 1; const DoubleSide = 2; -const FlatShading = 1; -const SmoothShading = 2; +const TwoPassDoubleSide = 2; // r149 const NoBlending = 0; const NormalBlending = 1; const AdditiveBlending = 2; @@ -74,6 +59,7 @@ const ReinhardToneMapping = 2; const CineonToneMapping = 3; const ACESFilmicToneMapping = 4; const CustomToneMapping = 5; + const UVMapping = 300; const CubeReflectionMapping = 301; const CubeRefractionMapping = 302; @@ -105,7 +91,6 @@ const UnsignedShort4444Type = 1017; const UnsignedShort5551Type = 1018; const UnsignedInt248Type = 1020; const AlphaFormat = 1021; -const RGBFormat = 1022; const RGBAFormat = 1023; const LuminanceFormat = 1024; const LuminanceAlphaFormat = 1025; @@ -116,6 +101,7 @@ const RedIntegerFormat = 1029; const RGFormat = 1030; const RGIntegerFormat = 1031; const RGBAIntegerFormat = 1033; + const RGB_S3TC_DXT1_Format = 33776; const RGBA_S3TC_DXT1_Format = 33777; const RGBA_S3TC_DXT3_Format = 33778; @@ -142,6 +128,10 @@ const RGBA_ASTC_10x10_Format = 37819; const RGBA_ASTC_12x10_Format = 37820; const RGBA_ASTC_12x12_Format = 37821; const RGBA_BPTC_Format = 36492; +const RED_RGTC1_Format = 36283; +const SIGNED_RED_RGTC1_Format = 36284; +const RED_GREEN_RGTC2_Format = 36285; +const SIGNED_RED_GREEN_RGTC2_Format = 36286; const LoopOnce = 2200; const LoopRepeat = 2201; const LoopPingPong = 2202; @@ -161,11 +151,13 @@ 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'; + const ZeroStencilOp = 0; const KeepStencilOp = 7680; const ReplaceStencilOp = 7681; @@ -174,6 +166,7 @@ const DecrementStencilOp = 7683; const IncrementWrapStencilOp = 34055; const DecrementWrapStencilOp = 34056; const InvertStencilOp = 5386; + const NeverStencilFunc = 512; const LessStencilFunc = 513; const EqualStencilFunc = 514; @@ -182,6 +175,7 @@ const GreaterStencilFunc = 516; const NotEqualStencilFunc = 517; const GreaterEqualStencilFunc = 518; const AlwaysStencilFunc = 519; + const StaticDrawUsage = 35044; const DynamicDrawUsage = 35048; const StreamDrawUsage = 35040; @@ -191,924 +185,1260 @@ const StreamReadUsage = 35041; const StaticCopyUsage = 35046; const DynamicCopyUsage = 35050; const StreamCopyUsage = 35042; + const GLSL1 = '100'; const GLSL3 = '300 es'; + const _SRGBAFormat = 1035; // fallback for WebGL 1 /** * https://github.com/mrdoob/eventdispatcher.js/ */ + class EventDispatcher { - addEventListener(type, listener) { - if (this._listeners === undefined) this._listeners = {}; + + addEventListener( type, listener ) { + + if ( this._listeners === undefined ) this._listeners = {}; + const listeners = this._listeners; - if (listeners[type] === undefined) { - listeners[type] = []; + if ( listeners[ type ] === undefined ) { + + listeners[ type ] = []; + } - if (listeners[type].indexOf(listener) === -1) { - listeners[type].push(listener); + if ( listeners[ type ].indexOf( listener ) === - 1 ) { + + listeners[ type ].push( listener ); + } + } - hasEventListener(type, listener) { - if (this._listeners === undefined) return false; + hasEventListener( type, listener ) { + + if ( this._listeners === undefined ) return false; + const listeners = this._listeners; - return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1; + + return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1; + } - removeEventListener(type, listener) { - if (this._listeners === undefined) return; + removeEventListener( type, listener ) { + + if ( this._listeners === undefined ) return; + const listeners = this._listeners; - const listenerArray = listeners[type]; + const listenerArray = listeners[ type ]; + + if ( listenerArray !== undefined ) { + + const index = listenerArray.indexOf( listener ); + + if ( index !== - 1 ) { - if (listenerArray !== undefined) { - const index = listenerArray.indexOf(listener); + listenerArray.splice( index, 1 ); - if (index !== -1) { - listenerArray.splice(index, 1); } + } + } - dispatchEvent(event) { - if (this._listeners === undefined) return; + dispatchEvent( event ) { + + if ( this._listeners === undefined ) return; + const listeners = this._listeners; - const listenerArray = listeners[event.type]; + const listenerArray = listeners[ event.type ]; - if (listenerArray !== undefined) { - event.target = this; // Make a copy, in case listeners are removed while iterating. + if ( listenerArray !== undefined ) { - const array = listenerArray.slice(0); + 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 ); - for (let i = 0, l = array.length; i < l; i++) { - array[i].call(this, event); } event.target = null; + } + } } -const _lut = []; - -for (let i = 0; i < 256; i++) { - _lut[i] = (i < 16 ? '0' : '') + i.toString(16); -} +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 ) ); + } -function clamp(value, min, max) { - return Math.max(min, Math.min(max, value)); -} // compute euclidean modulo of m % n +// 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 +function mapLinear( x, a1, a2, b1, b2 ) { -function euclideanModulo(n, m) { - return (n % m + m) % m; -} // Linear mapping from range to range + return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 ); + +} +// https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/ +function inverseLerp( x, y, value ) { -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/ + if ( x !== y ) { + return ( value - x ) / ( y - x ); -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/ +function damp( x, y, lambda, dt ) { + + return lerp( x, y, 1 - Math.exp( - lambda * dt ) ); + +} + +// https://www.desmos.com/calculator/vcsjnyz7x4 +function pingpong( x, length = 1 ) { -function lerp(x, y, t) { - return (1 - t) * x + t * y; -} // http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/ + return length - Math.abs( euclideanModulo( x, length * 2 ) - length ); +} + +// http://en.wikipedia.org/wiki/Smoothstep +function smoothstep( x, min, max ) { + + if ( x <= min ) return 0; + if ( x >= max ) return 1; + + x = ( x - min ) / ( max - min ); + + return x * x * ( 3 - 2 * x ); + +} + +function smootherstep( x, min, max ) { -function damp(x, y, lambda, dt) { - return lerp(x, y, 1 - Math.exp(-lambda * dt)); -} // https://www.desmos.com/calculator/vcsjnyz7x4 + if ( x <= min ) return 0; + if ( x >= max ) return 1; + x = ( x - min ) / ( max - min ); -function pingpong(x, length = 1) { - return length - Math.abs(euclideanModulo(x, length * 2) - length); -} // http://en.wikipedia.org/wiki/Smoothstep + return x * x * x * ( x * ( x * 6 - 15 ) + 10 ); +} + +// Random integer from interval +function randInt( low, high ) { + + return low + Math.floor( Math.random() * ( high - low + 1 ) ); -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 float from interval +function randFloat( low, high ) { + return low + Math.random() * ( high - low ); -function randInt(low, high) { - return low + Math.floor(Math.random() * (high - low + 1)); -} // Random float from interval +} +// Random float from <-range/2, range/2> interval +function randFloatSpread( range ) { -function randFloat(low, high) { - return low + Math.random() * (high - low); -} // Random float from <-range/2, range/2> interval + return range * ( 0.5 - Math.random() ); +} -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; -function seededRandom(s) { - if (s !== undefined) _seed = s; // Mulberry32 generator + // 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; + + 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) { +function degToRad( degrees ) { + return degrees * DEG2RAD; + } -function radToDeg(radians) { +function radToDeg( radians ) { + return radians * RAD2DEG; + } -function isPowerOfTwo(value) { - return (value & value - 1) === 0 && value !== 0; +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 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 floorPowerOfTwo( value ) { + + return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) ); + } -function setQuaternionFromProperEuler(q, a, b, c, order) { +function setQuaternionFromProperEuler( q, a, b, c, order ) { + // Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles + // rotations are applied to the axes in the order specified by 'order' // rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c' // angles are in radians + const cos = Math.cos; const sin = Math.sin; - const c2 = cos(b / 2); - const s2 = sin(b / 2); - const c13 = cos((a + c) / 2); - const s13 = sin((a + c) / 2); - const c1_3 = cos((a - c) / 2); - const s1_3 = sin((a - c) / 2); - const c3_1 = cos((c - a) / 2); - const s3_1 = sin((c - a) / 2); - - switch (order) { + + const c2 = cos( b / 2 ); + const s2 = sin( b / 2 ); + + const c13 = cos( ( a + c ) / 2 ); + const s13 = sin( ( a + c ) / 2 ); + + const c1_3 = cos( ( a - c ) / 2 ); + const s1_3 = sin( ( a - c ) / 2 ); + + const c3_1 = cos( ( c - a ) / 2 ); + const s3_1 = sin( ( c - a ) / 2 ); + + switch ( order ) { + case 'XYX': - q.set(c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13); + 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); + 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); + 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); + 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); + 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); + q.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 ); break; default: - console.warn('THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order); + console.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order ); + } + } -function denormalize$1(value, array) { - switch (array.constructor) { +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); + + return Math.max( value / 32767.0, - 1.0 ); case Int8Array: - return Math.max(value / 127.0, -1.0); + + return Math.max( value / 127.0, - 1.0 ); default: - throw new Error('Invalid component type.'); + + throw new Error( 'Invalid component type.' ); + } + } -function normalize(value, array) { - switch (array.constructor) { +function normalize( value, array ) { + + switch ( array.constructor ) { + case Float32Array: + return value; case Uint16Array: - return Math.round(value * 65535.0); + + return Math.round( value * 65535.0 ); case Uint8Array: - return Math.round(value * 255.0); + + return Math.round( value * 255.0 ); case Int16Array: - return Math.round(value * 32767.0); + + return Math.round( value * 32767.0 ); case Int8Array: - return Math.round(value * 127.0); + + return Math.round( value * 127.0 ); default: - throw new Error('Invalid component type.'); + + throw new Error( 'Invalid component type.' ); + } + } var MathUtils = /*#__PURE__*/Object.freeze({ __proto__: null, DEG2RAD: DEG2RAD, RAD2DEG: RAD2DEG, - generateUUID: generateUUID, + ceilPowerOfTwo: ceilPowerOfTwo, clamp: clamp, + damp: damp, + degToRad: degToRad, + denormalize: denormalize, euclideanModulo: euclideanModulo, - mapLinear: mapLinear, + floorPowerOfTwo: floorPowerOfTwo, + generateUUID: generateUUID, inverseLerp: inverseLerp, + isPowerOfTwo: isPowerOfTwo, lerp: lerp, - damp: damp, + mapLinear: mapLinear, + normalize: normalize, pingpong: pingpong, - smoothstep: smoothstep, - smootherstep: smootherstep, - randInt: randInt, + radToDeg: radToDeg, randFloat: randFloat, randFloatSpread: randFloatSpread, + randInt: randInt, seededRandom: seededRandom, - degToRad: degToRad, - radToDeg: radToDeg, - isPowerOfTwo: isPowerOfTwo, - ceilPowerOfTwo: ceilPowerOfTwo, - floorPowerOfTwo: floorPowerOfTwo, setQuaternionFromProperEuler: setQuaternionFromProperEuler, - normalize: normalize, - denormalize: denormalize$1 + smootherstep: smootherstep, + smoothstep: smoothstep }); class Vector2 { - constructor(x = 0, y = 0) { - this.isVector2 = true; + + constructor( x = 0, y = 0 ) { + + Vector2.prototype.isVector2 = true; + this.x = x; this.y = y; + } get width() { + return this.x; + } - set width(value) { + set width( value ) { + this.x = value; + } get height() { + return this.y; + } - set height(value) { + set height( value ) { + this.y = value; + } - set(x, y) { + set( x, y ) { + this.x = x; this.y = y; + return this; + } - setScalar(scalar) { + setScalar( scalar ) { + this.x = scalar; this.y = scalar; + return this; + } - setX(x) { + setX( x ) { + this.x = x; + return this; + } - setY(y) { + setY( y ) { + this.y = y; + return this; + } - setComponent(index, value) { - switch (index) { - case 0: - this.x = value; - break; + setComponent( index, value ) { - case 1: - this.y = value; - break; + switch ( index ) { + + case 0: this.x = value; break; + case 1: this.y = value; break; + default: throw new Error( 'index is out of range: ' + index ); - default: - throw new Error('index is out of range: ' + index); } return this; + } - getComponent(index) { - switch (index) { - case 0: - return this.x; + getComponent( index ) { - case 1: - return this.y; + switch ( index ) { + + case 0: return this.x; + case 1: return this.y; + default: throw new Error( 'index is out of range: ' + index ); - default: - throw new Error('index is out of range: ' + index); } + } clone() { - return new this.constructor(this.x, this.y); + + return new this.constructor( this.x, this.y ); + } - copy(v) { + copy( v ) { + this.x = v.x; this.y = v.y; + return this; + } - add(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.'); - return this.addVectors(v, w); - } + add( v ) { this.x += v.x; this.y += v.y; + return this; + } - addScalar(s) { + addScalar( s ) { + this.x += s; this.y += s; + return this; + } - addVectors(a, b) { + addVectors( a, b ) { + this.x = a.x + b.x; this.y = a.y + b.y; + return this; + } - addScaledVector(v, s) { + addScaledVector( v, s ) { + this.x += v.x * s; this.y += v.y * s; + return this; + } - sub(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.'); - return this.subVectors(v, w); - } + sub( v ) { this.x -= v.x; this.y -= v.y; + return this; + } - subScalar(s) { + subScalar( s ) { + this.x -= s; this.y -= s; + return this; + } - subVectors(a, b) { + subVectors( a, b ) { + this.x = a.x - b.x; this.y = a.y - b.y; + return this; + } - multiply(v) { + multiply( v ) { + this.x *= v.x; this.y *= v.y; + return this; + } - multiplyScalar(scalar) { + multiplyScalar( scalar ) { + this.x *= scalar; this.y *= scalar; + return this; + } - divide(v) { + divide( v ) { + this.x /= v.x; this.y /= v.y; + return this; + } - divideScalar(scalar) { - return this.multiplyScalar(1 / scalar); + divideScalar( scalar ) { + + return this.multiplyScalar( 1 / scalar ); + } - applyMatrix3(m) { - const x = this.x, - y = this.y; + applyMatrix3( m ) { + + const x = this.x, 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]; + + 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); + 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); + max( v ) { + + this.x = Math.max( this.x, v.x ); + this.y = Math.max( this.y, v.y ); + return this; + } - clamp(min, max) { + 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.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)); + 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) { + clampLength( min, max ) { + const length = this.length(); - return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, 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.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); + + 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); + + 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); + + 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; + + this.x = - this.x; + this.y = - this.y; + return this; + } - dot(v) { + dot( v ) { + return this.x * v.x + this.y * v.y; + } - cross(v) { + 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); + + return Math.sqrt( this.x * this.x + this.y * this.y ); + } manhattanLength() { - return Math.abs(this.x) + Math.abs(this.y); + + return Math.abs( this.x ) + Math.abs( this.y ); + } normalize() { - return this.divideScalar(this.length() || 1); + + 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; + + const angle = Math.atan2( - this.y, - this.x ) + Math.PI; + return angle; + } - distanceTo(v) { - return Math.sqrt(this.distanceToSquared(v)); + distanceTo( v ) { + + return Math.sqrt( this.distanceToSquared( v ) ); + } - distanceToSquared(v) { - const dx = this.x - v.x, - dy = this.y - v.y; + distanceToSquared( v ) { + + const dx = this.x - v.x, 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); + manhattanDistanceTo( v ) { + + return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ); + } - setLength(length) { - return this.normalize().multiplyScalar(length); + setLength( length ) { + + return this.normalize().multiplyScalar( length ); + } - lerp(v, alpha) { - this.x += (v.x - this.x) * alpha; - this.y += (v.y - this.y) * alpha; + 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; + 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; + equals( v ) { + + return ( ( v.x === this.x ) && ( v.y === this.y ) ); + } - fromArray(array, offset = 0) { - this.x = array[offset]; - this.y = array[offset + 1]; + 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; + toArray( array = [], offset = 0 ) { + + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + return array; + } - fromBufferAttribute(attribute, index, offset) { - if (offset !== undefined) { - console.warn('THREE.Vector2: offset has been removed from .fromBufferAttribute().'); - } + fromBufferAttribute( attribute, index ) { + + this.x = attribute.getX( index ); + this.y = attribute.getY( 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); + rotateAround( center, angle ) { + + const c = Math.cos( 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]() { + *[ Symbol.iterator ]() { + yield this.x; yield this.y; + } } class Matrix3 { + constructor() { - this.isMatrix3 = true; - this.elements = [1, 0, 0, 0, 1, 0, 0, 0, 1]; - if (arguments.length > 0) { - console.error('THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.'); - } + 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) { + set( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { + const te = this.elements; - te[0] = n11; - te[1] = n21; - te[2] = n31; - te[3] = n12; - te[4] = n22; - te[5] = n32; - te[6] = n13; - te[7] = n23; - te[8] = n33; + + te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; + te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; + te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; + return this; + } identity() { - this.set(1, 0, 0, 0, 1, 0, 0, 0, 1); + + this.set( + + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 + + ); + return this; + } - copy(m) { + copy( m ) { + const te = this.elements; const me = m.elements; - te[0] = me[0]; - te[1] = me[1]; - te[2] = me[2]; - te[3] = me[3]; - te[4] = me[4]; - te[5] = me[5]; - te[6] = me[6]; - te[7] = me[7]; - te[8] = me[8]; + + te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; + te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; + te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ]; + return this; + } - extractBasis(xAxis, yAxis, zAxis) { - xAxis.setFromMatrix3Column(this, 0); - yAxis.setFromMatrix3Column(this, 1); - zAxis.setFromMatrix3Column(this, 2); + extractBasis( xAxis, yAxis, zAxis ) { + + xAxis.setFromMatrix3Column( this, 0 ); + yAxis.setFromMatrix3Column( this, 1 ); + zAxis.setFromMatrix3Column( this, 2 ); + return this; + } - setFromMatrix4(m) { + 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]); + + 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); + multiply( m ) { + + return this.multiplyMatrices( this, m ); + } - premultiply(m) { - return this.multiplyMatrices(m, this); + premultiply( m ) { + + return this.multiplyMatrices( m, this ); + } - multiplyMatrices(a, b) { + multiplyMatrices( a, b ) { + const ae = a.elements; const be = b.elements; const te = this.elements; - const a11 = ae[0], - a12 = ae[3], - a13 = ae[6]; - const a21 = ae[1], - a22 = ae[4], - a23 = ae[7]; - const a31 = ae[2], - a32 = ae[5], - a33 = ae[8]; - const b11 = be[0], - b12 = be[3], - b13 = be[6]; - const b21 = be[1], - b22 = be[4], - b23 = be[7]; - const b31 = be[2], - b32 = be[5], - b33 = be[8]; - te[0] = a11 * b11 + a12 * b21 + a13 * b31; - te[3] = a11 * b12 + a12 * b22 + a13 * b32; - te[6] = a11 * b13 + a12 * b23 + a13 * b33; - te[1] = a21 * b11 + a22 * b21 + a23 * b31; - te[4] = a21 * b12 + a22 * b22 + a23 * b32; - te[7] = a21 * b13 + a22 * b23 + a23 * b33; - te[2] = a31 * b11 + a32 * b21 + a33 * b31; - te[5] = a31 * b12 + a32 * b22 + a33 * b32; - te[8] = a31 * b13 + a32 * b23 + a33 * b33; - return this; - } - - multiplyScalar(s) { + + const a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; + const a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; + const a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; + + const b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; + const b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; + const b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; + + te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; + te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; + te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; + + te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; + te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; + te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; + + te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; + te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; + te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; + + return this; + + } + + multiplyScalar( s ) { + const te = this.elements; - te[0] *= s; - te[3] *= s; - te[6] *= s; - te[1] *= s; - te[4] *= s; - te[7] *= s; - te[2] *= s; - te[5] *= s; - te[8] *= s; + + te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; + te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; + te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; + return this; + } determinant() { + const te = this.elements; - const a = te[0], - b = te[1], - c = te[2], - d = te[3], - e = te[4], - f = te[5], - g = te[6], - h = te[7], - i = te[8]; + + const a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], + d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], + g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; + return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; + } invert() { + const te = this.elements, - n11 = te[0], - n21 = te[1], - n31 = te[2], - n12 = te[3], - n22 = te[4], - n32 = te[5], - n13 = te[6], - n23 = te[7], - n33 = te[8], - t11 = n33 * n22 - n32 * n23, - t12 = n32 * n13 - n33 * n12, - t13 = n23 * n12 - n22 * n13, - det = n11 * t11 + n21 * t12 + n31 * t13; - if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0); + + n11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ], + n12 = te[ 3 ], n22 = te[ 4 ], n32 = te[ 5 ], + n13 = te[ 6 ], n23 = te[ 7 ], n33 = te[ 8 ], + + t11 = n33 * n22 - n32 * n23, + t12 = n32 * n13 - n33 * n12, + t13 = n23 * n12 - n22 * n13, + + det = n11 * t11 + n21 * t12 + n31 * t13; + + if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + const detInv = 1 / det; - te[0] = t11 * detInv; - te[1] = (n31 * n23 - n33 * n21) * detInv; - te[2] = (n32 * n21 - n31 * n22) * detInv; - te[3] = t12 * detInv; - te[4] = (n33 * n11 - n31 * n13) * detInv; - te[5] = (n31 * n12 - n32 * n11) * detInv; - te[6] = t13 * detInv; - te[7] = (n21 * n13 - n23 * n11) * detInv; - te[8] = (n22 * n11 - n21 * n12) * detInv; + + te[ 0 ] = t11 * detInv; + te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; + te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; + + te[ 3 ] = t12 * detInv; + te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; + te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; + + te[ 6 ] = t13 * detInv; + te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; + te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; + return this; + } transpose() { + let tmp; const m = this.elements; - tmp = m[1]; - m[1] = m[3]; - m[3] = tmp; - tmp = m[2]; - m[2] = m[6]; - m[6] = tmp; - tmp = m[5]; - m[5] = m[7]; - m[7] = tmp; + + tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; + tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; + tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; + return this; + } - getNormalMatrix(matrix4) { - return this.setFromMatrix4(matrix4).invert().transpose(); + getNormalMatrix( matrix4 ) { + + return this.setFromMatrix4( matrix4 ).invert().transpose(); + } - transposeIntoArray(r) { + transposeIntoArray( r ) { + const m = this.elements; - r[0] = m[0]; - r[1] = m[3]; - r[2] = m[6]; - r[3] = m[1]; - r[4] = m[4]; - r[5] = m[7]; - r[6] = m[2]; - r[7] = m[5]; - r[8] = m[8]; + + r[ 0 ] = m[ 0 ]; + r[ 1 ] = m[ 3 ]; + r[ 2 ] = m[ 6 ]; + r[ 3 ] = m[ 1 ]; + r[ 4 ] = m[ 4 ]; + r[ 5 ] = m[ 7 ]; + r[ 6 ] = m[ 2 ]; + r[ 7 ] = m[ 5 ]; + r[ 8 ] = m[ 8 ]; + return this; + } - setUvTransform(tx, ty, sx, sy, rotation, cx, cy) { - const c = Math.cos(rotation); - const s = Math.sin(rotation); - this.set(sx * c, sx * s, -sx * (c * cx + s * cy) + cx + tx, -sy * s, sy * c, -sy * (-s * cx + c * cy) + cy + ty, 0, 0, 1); + setUvTransform( tx, ty, sx, sy, rotation, cx, cy ) { + + const c = Math.cos( rotation ); + const s = Math.sin( rotation ); + + this.set( + sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, + - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, + 0, 0, 1 + ); + return this; + } - scale(sx, sy) { - const te = this.elements; - te[0] *= sx; - te[3] *= sx; - te[6] *= sx; - te[1] *= sy; - te[4] *= sy; - te[7] *= sy; + // + + scale( sx, sy ) { + + this.premultiply( _m3.makeScale( sx, sy ) ); + return this; + } - rotate(theta) { - const c = Math.cos(theta); - const s = Math.sin(theta); - const te = this.elements; - const a11 = te[0], - a12 = te[3], - a13 = te[6]; - const a21 = te[1], - a22 = te[4], - a23 = te[7]; - te[0] = c * a11 + s * a21; - te[3] = c * a12 + s * a22; - te[6] = c * a13 + s * a23; - te[1] = -s * a11 + c * a21; - te[4] = -s * a12 + c * a22; - te[7] = -s * a13 + c * a23; - return this; - } - - translate(tx, ty) { - const te = this.elements; - te[0] += tx * te[2]; - te[3] += tx * te[5]; - te[6] += tx * te[8]; - te[1] += ty * te[2]; - te[4] += ty * te[5]; - te[7] += ty * te[8]; + 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 ); + + this.set( + + c, - s, 0, + s, c, 0, + 0, 0, 1 + + ); + + return this; + + } + + makeScale( x, y ) { + + this.set( + + x, 0, 0, + 0, y, 0, + 0, 0, 1 + + ); + + return this; + } - equals(matrix) { + // + + equals( matrix ) { + const te = this.elements; const me = matrix.elements; - for (let i = 0; i < 9; i++) { - if (te[i] !== me[i]) return false; + 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]; + fromArray( array, offset = 0 ) { + + for ( let i = 0; i < 9; i ++ ) { + + this.elements[ i ] = array[ i + offset ]; + } return this; + } - toArray(array = [], offset = 0) { + toArray( array = [], offset = 0 ) { + const te = this.elements; - array[offset] = te[0]; - array[offset + 1] = te[1]; - array[offset + 2] = te[2]; - array[offset + 3] = te[3]; - array[offset + 4] = te[4]; - array[offset + 5] = te[5]; - array[offset + 6] = te[6]; - array[offset + 7] = te[7]; - array[offset + 8] = te[8]; + + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; + + array[ offset + 3 ] = te[ 3 ]; + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; + + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; + array[ offset + 8 ] = te[ 8 ]; + return array; + } clone() { - return new this.constructor().fromArray(this.elements); + + return new this.constructor().fromArray( this.elements ); + } } -function arrayNeedsUint32(array) { +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; + + for ( let i = array.length - 1; i >= 0; -- i ) { + + if ( array[ i ] >= 65535 ) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 + } return false; + } const TYPED_ARRAYS = { @@ -1123,636 +1453,685 @@ const TYPED_ARRAYS = { Float64Array: Float64Array }; -function getTypedArray(type, buffer) { - return new TYPED_ARRAYS[type](buffer); +function getTypedArray( type, buffer ) { + + return new TYPED_ARRAYS[ type ]( buffer ); + } -function createElementNS(name) { - return document.createElementNS('http://www.w3.org/1999/xhtml', name); +function createElementNS( name ) { + + return document.createElementNS( 'http://www.w3.org/1999/xhtml', name ); + } -function SRGBToLinear(c) { - return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4); +function SRGBToLinear( c ) { + + return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 ); + } -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. +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. const FN = { - [SRGBColorSpace]: { - [LinearSRGBColorSpace]: SRGBToLinear - }, - [LinearSRGBColorSpace]: { - [SRGBColorSpace]: LinearToSRGB - } + [ SRGBColorSpace ]: { [ LinearSRGBColorSpace ]: SRGBToLinear }, + [ LinearSRGBColorSpace ]: { [ SRGBColorSpace ]: LinearToSRGB }, }; + const ColorManagement = { + legacyMode: true, get workingColorSpace() { + return LinearSRGBColorSpace; + }, - set workingColorSpace(colorSpace) { - console.warn('THREE.ColorManagement: .workingColorSpace is readonly.'); + set workingColorSpace( colorSpace ) { + + console.warn( 'THREE.ColorManagement: .workingColorSpace is readonly.' ); + }, - convert: function (color, sourceColorSpace, targetColorSpace) { - if (this.legacyMode || sourceColorSpace === targetColorSpace || !sourceColorSpace || !targetColorSpace) { + 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); - color.g = fn(color.g); - color.b = fn(color.b); + if ( FN[ sourceColorSpace ] && FN[ sourceColorSpace ][ targetColorSpace ] !== undefined ) { + + const fn = FN[ sourceColorSpace ][ targetColorSpace ]; + + color.r = fn( color.r ); + color.g = fn( color.g ); + color.b = fn( color.b ); + return color; + } - throw new Error('Unsupported color space conversion.'); + throw new Error( 'Unsupported color space conversion.' ); + }, - fromWorkingColorSpace: function (color, targetColorSpace) { - return this.convert(color, this.workingColorSpace, targetColorSpace); + + fromWorkingColorSpace: function ( color, targetColorSpace ) { + + return this.convert( color, this.workingColorSpace, targetColorSpace ); + + }, + + toWorkingColorSpace: function ( color, sourceColorSpace ) { + + return this.convert( color, sourceColorSpace, this.workingColorSpace ); + }, - toWorkingColorSpace: function (color, sourceColorSpace) { - return this.convert(color, sourceColorSpace, this.workingColorSpace); - } -}; -const _colorKeywords = { - 'aliceblue': 0xF0F8FF, - 'antiquewhite': 0xFAEBD7, - 'aqua': 0x00FFFF, - 'aquamarine': 0x7FFFD4, - 'azure': 0xF0FFFF, - 'beige': 0xF5F5DC, - 'bisque': 0xFFE4C4, - 'black': 0x000000, - 'blanchedalmond': 0xFFEBCD, - 'blue': 0x0000FF, - 'blueviolet': 0x8A2BE2, - 'brown': 0xA52A2A, - 'burlywood': 0xDEB887, - 'cadetblue': 0x5F9EA0, - 'chartreuse': 0x7FFF00, - 'chocolate': 0xD2691E, - 'coral': 0xFF7F50, - 'cornflowerblue': 0x6495ED, - 'cornsilk': 0xFFF8DC, - 'crimson': 0xDC143C, - 'cyan': 0x00FFFF, - 'darkblue': 0x00008B, - 'darkcyan': 0x008B8B, - 'darkgoldenrod': 0xB8860B, - 'darkgray': 0xA9A9A9, - 'darkgreen': 0x006400, - 'darkgrey': 0xA9A9A9, - 'darkkhaki': 0xBDB76B, - 'darkmagenta': 0x8B008B, - 'darkolivegreen': 0x556B2F, - 'darkorange': 0xFF8C00, - 'darkorchid': 0x9932CC, - 'darkred': 0x8B0000, - 'darksalmon': 0xE9967A, - 'darkseagreen': 0x8FBC8F, - 'darkslateblue': 0x483D8B, - 'darkslategray': 0x2F4F4F, - 'darkslategrey': 0x2F4F4F, - 'darkturquoise': 0x00CED1, - 'darkviolet': 0x9400D3, - 'deeppink': 0xFF1493, - 'deepskyblue': 0x00BFFF, - 'dimgray': 0x696969, - 'dimgrey': 0x696969, - 'dodgerblue': 0x1E90FF, - 'firebrick': 0xB22222, - 'floralwhite': 0xFFFAF0, - 'forestgreen': 0x228B22, - 'fuchsia': 0xFF00FF, - 'gainsboro': 0xDCDCDC, - 'ghostwhite': 0xF8F8FF, - 'gold': 0xFFD700, - 'goldenrod': 0xDAA520, - 'gray': 0x808080, - 'green': 0x008000, - 'greenyellow': 0xADFF2F, - 'grey': 0x808080, - 'honeydew': 0xF0FFF0, - 'hotpink': 0xFF69B4, - 'indianred': 0xCD5C5C, - 'indigo': 0x4B0082, - 'ivory': 0xFFFFF0, - 'khaki': 0xF0E68C, - 'lavender': 0xE6E6FA, - 'lavenderblush': 0xFFF0F5, - 'lawngreen': 0x7CFC00, - 'lemonchiffon': 0xFFFACD, - 'lightblue': 0xADD8E6, - 'lightcoral': 0xF08080, - 'lightcyan': 0xE0FFFF, - 'lightgoldenrodyellow': 0xFAFAD2, - 'lightgray': 0xD3D3D3, - 'lightgreen': 0x90EE90, - 'lightgrey': 0xD3D3D3, - 'lightpink': 0xFFB6C1, - 'lightsalmon': 0xFFA07A, - 'lightseagreen': 0x20B2AA, - 'lightskyblue': 0x87CEFA, - 'lightslategray': 0x778899, - 'lightslategrey': 0x778899, - 'lightsteelblue': 0xB0C4DE, - 'lightyellow': 0xFFFFE0, - 'lime': 0x00FF00, - 'limegreen': 0x32CD32, - 'linen': 0xFAF0E6, - 'magenta': 0xFF00FF, - 'maroon': 0x800000, - 'mediumaquamarine': 0x66CDAA, - 'mediumblue': 0x0000CD, - 'mediumorchid': 0xBA55D3, - 'mediumpurple': 0x9370DB, - 'mediumseagreen': 0x3CB371, - 'mediumslateblue': 0x7B68EE, - 'mediumspringgreen': 0x00FA9A, - 'mediumturquoise': 0x48D1CC, - 'mediumvioletred': 0xC71585, - 'midnightblue': 0x191970, - 'mintcream': 0xF5FFFA, - 'mistyrose': 0xFFE4E1, - 'moccasin': 0xFFE4B5, - 'navajowhite': 0xFFDEAD, - 'navy': 0x000080, - 'oldlace': 0xFDF5E6, - 'olive': 0x808000, - 'olivedrab': 0x6B8E23, - 'orange': 0xFFA500, - 'orangered': 0xFF4500, - 'orchid': 0xDA70D6, - 'palegoldenrod': 0xEEE8AA, - 'palegreen': 0x98FB98, - 'paleturquoise': 0xAFEEEE, - 'palevioletred': 0xDB7093, - 'papayawhip': 0xFFEFD5, - 'peachpuff': 0xFFDAB9, - 'peru': 0xCD853F, - 'pink': 0xFFC0CB, - 'plum': 0xDDA0DD, - 'powderblue': 0xB0E0E6, - 'purple': 0x800080, - 'rebeccapurple': 0x663399, - 'red': 0xFF0000, - 'rosybrown': 0xBC8F8F, - 'royalblue': 0x4169E1, - 'saddlebrown': 0x8B4513, - 'salmon': 0xFA8072, - 'sandybrown': 0xF4A460, - 'seagreen': 0x2E8B57, - 'seashell': 0xFFF5EE, - 'sienna': 0xA0522D, - 'silver': 0xC0C0C0, - 'skyblue': 0x87CEEB, - 'slateblue': 0x6A5ACD, - 'slategray': 0x708090, - 'slategrey': 0x708090, - 'snow': 0xFFFAFA, - 'springgreen': 0x00FF7F, - 'steelblue': 0x4682B4, - 'tan': 0xD2B48C, - 'teal': 0x008080, - 'thistle': 0xD8BFD8, - 'tomato': 0xFF6347, - 'turquoise': 0x40E0D0, - 'violet': 0xEE82EE, - 'wheat': 0xF5DEB3, - 'white': 0xFFFFFF, - 'whitesmoke': 0xF5F5F5, - 'yellow': 0xFFFF00, - 'yellowgreen': 0x9ACD32 -}; -const _rgb = { - r: 0, - g: 0, - b: 0 -}; -const _hslA = { - h: 0, - s: 0, - l: 0 -}; -const _hslB = { - h: 0, - s: 0, - l: 0 }; -function hue2rgb(p, q, t) { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t); +const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, + 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, + 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, + 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, + 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, + 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, + 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, + 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, + 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, + 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, + 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, + 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, + 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, + 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, + 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, + 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, + 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, + 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, + 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, + 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, + 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, + 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, + 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, + 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; + +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 }; + +function hue2rgb( p, q, t ) { + + if ( t < 0 ) t += 1; + if ( t > 1 ) t -= 1; + if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; + if ( t < 1 / 2 ) return q; + if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); return p; + } -function toComponents(source, target) { +function toComponents( source, target ) { + target.r = source.r; target.g = source.g; target.b = source.b; + return target; + } class Color { - constructor(r, g, b) { + + constructor( r, g, b ) { + this.isColor = true; + this.r = 1; this.g = 1; this.b = 1; - if (g === undefined && b === undefined) { + if ( g === undefined && b === undefined ) { + // r is THREE.Color, hex or string - return this.set(r); + return this.set( r ); + } - return this.setRGB(r, g, b); + return this.setRGB( r, g, b ); + } - set(value) { - if (value && value.isColor) { - this.copy(value); - } else if (typeof value === 'number') { - this.setHex(value); - } else if (typeof value === 'string') { - this.setStyle(value); + set( value ) { + + if ( value && value.isColor ) { + + this.copy( value ); + + } else if ( typeof value === 'number' ) { + + this.setHex( value ); + + } else if ( typeof value === 'string' ) { + + this.setStyle( value ); + } return this; + } - setScalar(scalar) { + 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; - this.g = (hex >> 8 & 255) / 255; - this.b = (hex & 255) / 255; - ColorManagement.toWorkingColorSpace(this, colorSpace); + setHex( hex, colorSpace = SRGBColorSpace ) { + + hex = Math.floor( hex ); + + this.r = ( hex >> 16 & 255 ) / 255; + this.g = ( hex >> 8 & 255 ) / 255; + this.b = ( hex & 255 ) / 255; + + 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); + + 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); + h = euclideanModulo( h, 1 ); + s = clamp( s, 0, 1 ); + l = clamp( l, 0, 1 ); + + if ( s === 0 ) { - if (s === 0) { this.r = this.g = this.b = l; + } else { - const p = l <= 0.5 ? l * (1 + s) : l + s - l * s; - const q = 2 * l - p; - this.r = hue2rgb(q, p, h + 1 / 3); - this.g = hue2rgb(q, p, h); - this.b = hue2rgb(q, p, h - 1 / 3); + + const p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); + const q = ( 2 * l ) - p; + + this.r = hue2rgb( q, p, h + 1 / 3 ); + this.g = hue2rgb( q, p, h ); + this.b = hue2rgb( q, p, h - 1 / 3 ); + } - ColorManagement.toWorkingColorSpace(this, colorSpace); + ColorManagement.toWorkingColorSpace( this, colorSpace ); + return this; + } - setStyle(style, colorSpace = SRGBColorSpace) { - function handleAlpha(string) { - if (string === undefined) return; + 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.' ); - if (parseFloat(string) < 1) { - console.warn('THREE.Color: Alpha component of ' + style + ' will be ignored.'); } + } + let m; - if (m = /^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec(style)) { + if ( m = /^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec( style ) ) { + // rgb / hsl + let color; - const name = m[1]; - const components = m[2]; + const name = m[ 1 ]; + const components = m[ 2 ]; + + switch ( name ) { - switch (name) { case 'rgb': case 'rgba': - if (color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { + + if ( color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { + // rgb(255,0,0) rgba(255,0,0,0.5) - this.r = Math.min(255, parseInt(color[1], 10)) / 255; - this.g = Math.min(255, parseInt(color[2], 10)) / 255; - this.b = Math.min(255, parseInt(color[3], 10)) / 255; - ColorManagement.toWorkingColorSpace(this, colorSpace); - handleAlpha(color[4]); + this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255; + this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255; + this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255; + + ColorManagement.toWorkingColorSpace( this, colorSpace ); + + handleAlpha( color[ 4 ] ); + return this; + } - if (color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { + 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; - this.g = Math.min(100, parseInt(color[2], 10)) / 100; - this.b = Math.min(100, parseInt(color[3], 10)) / 100; - ColorManagement.toWorkingColorSpace(this, colorSpace); - handleAlpha(color[4]); + this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100; + this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100; + this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100; + + ColorManagement.toWorkingColorSpace( this, colorSpace ); + + 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; - handleAlpha(color[4]); - return this.setHSL(h, s, l, colorSpace); + const h = parseFloat( color[ 1 ] ) / 360; + 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)) { + + } else if ( m = /^\#([A-Fa-f\d]+)$/.exec( style ) ) { + // hex color - const hex = m[1]; + + const hex = m[ 1 ]; const size = hex.length; - if (size === 3) { + if ( size === 3 ) { + // #ff0 - this.r = parseInt(hex.charAt(0) + hex.charAt(0), 16) / 255; - this.g = parseInt(hex.charAt(1) + hex.charAt(1), 16) / 255; - this.b = parseInt(hex.charAt(2) + hex.charAt(2), 16) / 255; - ColorManagement.toWorkingColorSpace(this, colorSpace); + this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255; + this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255; + this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255; + + ColorManagement.toWorkingColorSpace( this, colorSpace ); + return this; - } else if (size === 6) { + + } else if ( size === 6 ) { + // #ff0000 - this.r = parseInt(hex.charAt(0) + hex.charAt(1), 16) / 255; - this.g = parseInt(hex.charAt(2) + hex.charAt(3), 16) / 255; - this.b = parseInt(hex.charAt(4) + hex.charAt(5), 16) / 255; - ColorManagement.toWorkingColorSpace(this, colorSpace); + this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255; + this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255; + this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255; + + ColorManagement.toWorkingColorSpace( this, colorSpace ); + return this; + } + } - if (style && style.length > 0) { - return this.setColorName(style, colorSpace); + if ( style && style.length > 0 ) { + + return this.setColorName( style, colorSpace ); + } return this; + } - setColorName(style, colorSpace = SRGBColorSpace) { + setColorName( style, colorSpace = SRGBColorSpace ) { + // color keywords - const hex = _colorKeywords[style.toLowerCase()]; + const hex = _colorKeywords[ style.toLowerCase() ]; + + if ( hex !== undefined ) { - if (hex !== undefined) { // red - this.setHex(hex, colorSpace); + this.setHex( hex, colorSpace ); + } else { + // unknown color - console.warn('THREE.Color: Unknown color ' + style); + console.warn( 'THREE.Color: Unknown color ' + style ); + } return this; + } clone() { - return new this.constructor(this.r, this.g, this.b); + + return new this.constructor( this.r, this.g, this.b ); + } - copy(color) { + 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); + 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); + copyLinearToSRGB( color ) { + + this.r = LinearToSRGB( color.r ); + this.g = LinearToSRGB( color.g ); + this.b = LinearToSRGB( color.b ); + return this; + } convertSRGBToLinear() { - this.copySRGBToLinear(this); + + this.copySRGBToLinear( this ); + return this; + } convertLinearToSRGB() { - this.copyLinearToSRGB(this); + + 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; + getHex( colorSpace = SRGBColorSpace ) { + + 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); + 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; - const max = Math.max(r, g, b); - const min = Math.min(r, g, 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; + const lightness = ( min + max ) / 2.0; + + if ( min === max ) { - 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; + saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); - case g: - hue = (b - r) / delta + 2; - break; + 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; - 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); + getStyle( colorSpace = SRGBColorSpace ) { + + ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb$1 ), colorSpace ); + + if ( colorSpace !== SRGBColorSpace ) { - 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; - _hslA.s += s; - _hslA.l += l; - this.setHSL(_hslA.h, _hslA.s, _hslA.l); + offsetHSL( h, s, l ) { + + this.getHSL( _hslA ); + + _hslA.h += h; _hslA.s += s; _hslA.l += l; + + this.setHSL( _hslA.h, _hslA.s, _hslA.l ); + return this; + } - add(color) { + add( color ) { + this.r += color.r; this.g += color.g; this.b += color.b; + return this; + } - addColors(color1, color2) { + 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) { + 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); + 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) { + multiply( color ) { + this.r *= color.r; this.g *= color.g; this.b *= color.b; + return this; + } - multiplyScalar(s) { + 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; + 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; + 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); - const h = lerp(_hslA.h, _hslB.h, alpha); - const s = lerp(_hslA.s, _hslB.s, alpha); - const l = lerp(_hslA.l, _hslB.l, alpha); - this.setHSL(h, s, l); + lerpHSL( color, alpha ) { + + this.getHSL( _hslA ); + color.getHSL( _hslB ); + + const h = lerp( _hslA.h, _hslB.h, alpha ); + const s = lerp( _hslA.s, _hslB.s, alpha ); + const l = lerp( _hslA.l, _hslB.l, alpha ); + + this.setHSL( h, s, l ); + return this; + } - equals(c) { - return c.r === this.r && c.g === this.g && c.b === this.b; + 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]; + 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; + 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); + fromBufferAttribute( attribute, index ) { - if (attribute.normalized === true) { - // assuming Uint8Array - this.r /= 255; - this.g /= 255; - this.b /= 255; - } + this.r = attribute.getX( index ); + this.g = attribute.getY( index ); + this.b = attribute.getZ( index ); return this; + } toJSON() { + return this.getHex(); + } - *[Symbol.iterator]() { + *[ Symbol.iterator ]() { + yield this.r; yield this.g; yield this.b; + } } @@ -1762,69 +2141,109 @@ Color.NAMES = _colorKeywords; let _canvas; class ImageUtils { - static getDataURL(image) { - if (/^data:/i.test(image.src)) { + + static getDataURL( image ) { + + if ( /^data:/i.test( image.src ) ) { + return image.src; + } - if (typeof HTMLCanvasElement == 'undefined') { + if ( typeof HTMLCanvasElement == 'undefined' ) { + return image.src; + } let canvas; - if (image instanceof HTMLCanvasElement) { + if ( image instanceof HTMLCanvasElement ) { + canvas = image; + } else { - if (_canvas === undefined) _canvas = createElementNS('canvas'); + + if ( _canvas === undefined ) _canvas = createElementNS( 'canvas' ); + _canvas.width = image.width; _canvas.height = image.height; - const context = _canvas.getContext('2d'); + const context = _canvas.getContext( '2d' ); + + if ( image instanceof ImageData ) { + + context.putImageData( image, 0, 0 ); - if (image instanceof ImageData) { - context.putImageData(image, 0, 0); } else { - context.drawImage(image, 0, 0, image.width, image.height); + + 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); + 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 ); + } else { - return canvas.toDataURL('image/png'); + + 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'); + 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' ); + canvas.width = image.width; canvas.height = image.height; - const context = canvas.getContext('2d'); - context.drawImage(image, 0, 0, image.width, image.height); - const imageData = context.getImageData(0, 0, image.width, image.height); + + const context = canvas.getContext( '2d' ); + 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; + for ( let i = 0; i < data.length; i ++ ) { + + data[ i ] = SRGBToLinear( data[ i ] / 255 ) * 255; + } - context.putImageData(imageData, 0, 0); + 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 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]); + + data[ i ] = SRGBToLinear( data[ i ] ); + } + } return { @@ -1832,782 +2251,1068 @@ class ImageUtils { width: image.width, height: image.height }; + } else { - console.warn('THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.'); + + console.warn( 'THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.' ); return image; + } + } } class Source { - constructor(data = null) { + + constructor( data = null ) { + this.isSource = true; + this.uuid = generateUUID(); + this.data = data; + this.version = 0; + } - set needsUpdate(value) { - if (value === true) this.version++; + set needsUpdate( value ) { + + if ( value === true ) this.version ++; + } - toJSON(meta) { - const isRootObject = meta === undefined || typeof meta === 'string'; + toJSON( meta ) { + + const isRootObject = ( meta === undefined || typeof meta === 'string' ); + + if ( ! isRootObject && meta.images[ this.uuid ] !== undefined ) { + + return meta.images[ this.uuid ]; - 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) { + if ( data !== null ) { + let url; - if (Array.isArray(data)) { + if ( Array.isArray( data ) ) { + // cube texture + url = []; - for (let i = 0, l = data.length; i < l; i++) { - if (data[i].isDataTexture) { - url.push(serializeImage(data[i].image)); + for ( let i = 0, l = data.length; i < l; i ++ ) { + + if ( data[ i ].isDataTexture ) { + + url.push( serializeImage( data[ i ].image ) ); + } else { - url.push(serializeImage(data[i])); + + url.push( serializeImage( data[ i ] ) ); + } + } + } else { + // texture - url = serializeImage(data); + + url = serializeImage( data ); + } output.url = url; + } - if (!isRootObject) { - meta.images[this.uuid] = output; + 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) { +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); + + return ImageUtils.getDataURL( image ); + } else { - if (image.data) { + + if ( image.data ) { + // images of DataTexture + return { - data: Array.prototype.slice.call(image.data), + data: Array.from( image.data ), width: image.width, height: image.height, type: image.data.constructor.name }; + } else { - console.warn('THREE.Texture: Unable to serialize Texture.'); + + console.warn( 'THREE.Texture: Unable to serialize Texture.' ); return {}; + } + } + } 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', { - value: textureId++ - }); + + Object.defineProperty( this, 'id', { value: textureId ++ } ); + this.uuid = generateUUID(); + this.name = ''; - this.source = new Source(image); + + this.source = new Source( image ); this.mipmaps = []; + this.mapping = mapping; + this.wrapS = wrapS; this.wrapT = wrapT; + this.magFilter = magFilter; this.minFilter = minFilter; + this.anisotropy = anisotropy; + this.format = format; this.internalFormat = null; this.type = type; - this.offset = new Vector2(0, 0); - this.repeat = new Vector2(1, 1); - this.center = new Vector2(0, 0); + + this.offset = new Vector2( 0, 0 ); + this.repeat = new Vector2( 1, 1 ); + this.center = new Vector2( 0, 0 ); this.rotation = 0; + this.matrixAutoUpdate = true; this.matrix = new Matrix3(); + this.generateMipmaps = true; this.premultiplyAlpha = false; this.flipY = true; - this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) + 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.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) { + 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); + + 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); + + return new this.constructor().copy( this ); + } - copy(source) { + copy( source ) { + this.name = source.name; + this.source = source.source; - this.mipmaps = source.mipmaps.slice(0); + this.mipmaps = source.mipmaps.slice( 0 ); + this.mapping = source.mapping; + this.wrapS = source.wrapS; this.wrapT = source.wrapT; + this.magFilter = source.magFilter; this.minFilter = source.minFilter; + this.anisotropy = source.anisotropy; + this.format = source.format; this.internalFormat = source.internalFormat; this.type = source.type; - this.offset.copy(source.offset); - this.repeat.copy(source.repeat); - this.center.copy(source.center); + + this.offset.copy( source.offset ); + this.repeat.copy( source.repeat ); + this.center.copy( source.center ); this.rotation = source.rotation; + this.matrixAutoUpdate = source.matrixAutoUpdate; - this.matrix.copy(source.matrix); + this.matrix.copy( source.matrix ); + this.generateMipmaps = source.generateMipmaps; this.premultiplyAlpha = source.premultiplyAlpha; this.flipY = source.flipY; this.unpackAlignment = source.unpackAlignment; this.encoding = source.encoding; - this.userData = JSON.parse(JSON.stringify(source.userData)); + + this.userData = JSON.parse( JSON.stringify( source.userData ) ); + this.needsUpdate = true; + return this; + } - toJSON(meta) { - const isRootObject = meta === undefined || typeof meta === 'string'; + toJSON( meta ) { + + const isRootObject = ( meta === undefined || typeof meta === 'string' ); + + if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) { + + return meta.textures[ this.uuid ]; - if (!isRootObject && meta.textures[this.uuid] !== undefined) { - return meta.textures[this.uuid]; } const output = { + metadata: { version: 4.5, type: 'Texture', generator: 'Texture.toJSON' }, + uuid: this.uuid, name: this.name, - image: this.source.toJSON(meta).uuid, + + image: this.source.toJSON( meta ).uuid, + mapping: this.mapping, - repeat: [this.repeat.x, this.repeat.y], - offset: [this.offset.x, this.offset.y], - center: [this.center.x, this.center.y], + + repeat: [ this.repeat.x, this.repeat.y ], + offset: [ this.offset.x, this.offset.y ], + center: [ this.center.x, this.center.y ], rotation: this.rotation, - wrap: [this.wrapS, this.wrapT], + + wrap: [ this.wrapS, this.wrapT ], + format: this.format, type: this.type, encoding: this.encoding, + minFilter: this.minFilter, magFilter: this.magFilter, anisotropy: this.anisotropy, + flipY: this.flipY, + + generateMipmaps: this.generateMipmaps, premultiplyAlpha: this.premultiplyAlpha, unpackAlignment: this.unpackAlignment + }; - if (JSON.stringify(this.userData) !== '{}') output.userData = this.userData; - if (!isRootObject) { - meta.textures[this.uuid] = output; + if ( Object.keys( this.userData ).length > 0 ) output.userData = this.userData; + + if ( ! isRootObject ) { + + meta.textures[ this.uuid ] = output; + } return output; + } dispose() { - this.dispatchEvent({ - type: 'dispose' - }); + + this.dispatchEvent( { type: 'dispose' } ); + } - transformUv(uv) { - if (this.mapping !== UVMapping) return uv; - uv.applyMatrix3(this.matrix); + transformUv( uv ) { + + if ( this.mapping !== UVMapping ) return uv; + + uv.applyMatrix3( this.matrix ); + + if ( uv.x < 0 || uv.x > 1 ) { + + switch ( this.wrapS ) { - if (uv.x < 0 || uv.x > 1) { - switch (this.wrapS) { case RepeatWrapping: - uv.x = uv.x - Math.floor(uv.x); + + 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; + + 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); + + uv.x = uv.x - Math.floor( uv.x ); + } break; + } + } - if (uv.y < 0 || uv.y > 1) { - switch (this.wrapT) { + if ( uv.y < 0 || uv.y > 1 ) { + + switch ( this.wrapT ) { + case RepeatWrapping: - uv.y = uv.y - Math.floor(uv.y); + + 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; + + 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); + + uv.y = uv.y - Math.floor( uv.y ); + } break; + } + } - if (this.flipY) { + if ( this.flipY ) { + uv.y = 1 - uv.y; + } return uv; + } - set needsUpdate(value) { - if (value === true) { - this.version++; + 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) { - this.isVector4 = true; + + constructor( x = 0, y = 0, z = 0, w = 1 ) { + + Vector4.prototype.isVector4 = true; + this.x = x; this.y = y; this.z = z; this.w = w; + } get width() { + return this.z; + } - set width(value) { + set width( value ) { + this.z = value; + } get height() { + return this.w; + } - set height(value) { + set height( value ) { + this.w = value; + } - set(x, y, z, w) { + set( x, y, z, w ) { + this.x = x; this.y = y; this.z = z; this.w = w; + return this; + } - setScalar(scalar) { + setScalar( scalar ) { + this.x = scalar; this.y = scalar; this.z = scalar; this.w = scalar; + return this; + } - setX(x) { + setX( x ) { + this.x = x; + return this; + } - setY(y) { + setY( y ) { + this.y = y; + return this; + } - setZ(z) { + setZ( z ) { + this.z = z; + return this; + } - setW(w) { + setW( w ) { + this.w = w; + return this; - } - setComponent(index, value) { - switch (index) { - case 0: - this.x = value; - break; + } - case 1: - this.y = value; - break; + setComponent( index, value ) { - case 2: - this.z = value; - break; + switch ( index ) { - case 3: - this.w = value; - break; + 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 ); - 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; + getComponent( index ) { - case 2: - return this.z; + switch ( index ) { - case 3: - return this.w; + 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 ); - default: - throw new Error('index is out of range: ' + index); } + } clone() { - return new this.constructor(this.x, this.y, this.z, this.w); + + return new this.constructor( this.x, this.y, this.z, this.w ); + } - copy(v) { + copy( v ) { + this.x = v.x; this.y = v.y; this.z = v.z; - this.w = v.w !== undefined ? v.w : 1; + this.w = ( v.w !== undefined ) ? v.w : 1; + return this; + } - add(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.'); - return this.addVectors(v, w); - } + add( v ) { this.x += v.x; this.y += v.y; this.z += v.z; this.w += v.w; + return this; + } - addScalar(s) { + addScalar( s ) { + this.x += s; this.y += s; this.z += s; this.w += s; + return this; + } - addVectors(a, b) { + addVectors( a, b ) { + this.x = a.x + b.x; this.y = a.y + b.y; this.z = a.z + b.z; this.w = a.w + b.w; + return this; + } - addScaledVector(v, s) { + addScaledVector( v, s ) { + this.x += v.x * s; this.y += v.y * s; this.z += v.z * s; this.w += v.w * s; + return this; + } - sub(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.'); - return this.subVectors(v, w); - } + sub( v ) { this.x -= v.x; this.y -= v.y; this.z -= v.z; this.w -= v.w; + return this; + } - subScalar(s) { + subScalar( s ) { + this.x -= s; this.y -= s; this.z -= s; this.w -= s; + return this; + } - subVectors(a, b) { + subVectors( a, b ) { + this.x = a.x - b.x; this.y = a.y - b.y; this.z = a.z - b.z; this.w = a.w - b.w; + return this; + } - multiply(v) { + multiply( v ) { + this.x *= v.x; this.y *= v.y; this.z *= v.z; this.w *= v.w; + return this; + } - multiplyScalar(scalar) { + multiplyScalar( scalar ) { + this.x *= scalar; this.y *= scalar; this.z *= scalar; this.w *= scalar; + return this; + } - applyMatrix4(m) { - const x = this.x, - y = this.y, - z = this.z, - w = this.w; + applyMatrix4( m ) { + + const x = this.x, 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; - this.z = e[2] * x + e[6] * y + e[10] * z + e[14] * w; - this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w; + + this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; + this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; + this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; + this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; + return this; + } - divideScalar(scalar) { - return this.multiplyScalar(1 / scalar); + divideScalar( scalar ) { + + return this.multiplyScalar( 1 / scalar ); + } - setAxisAngleFromQuaternion(q) { + 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.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; this.z = 0; + } else { + this.x = q.x / s; this.y = q.y / s; this.z = q.z / s; + } return this; + } - setAxisAngleFromRotationMatrix(m) { + 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 + 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 ]; + + if ( ( Math.abs( m12 - m21 ) < epsilon ) && + ( Math.abs( m13 - m31 ) < epsilon ) && + ( Math.abs( m23 - m32 ) < epsilon ) ) { - 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]; - - 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) { + + 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); + + 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; - const yy = (m22 + 1) / 2; - const zz = (m33 + 1) / 2; - const xy = (m12 + m21) / 4; - const xz = (m13 + m31) / 4; - const yz = (m23 + m32) / 4; - - if (xx > yy && xx > zz) { + + const xx = ( m11 + 1 ) / 2; + const yy = ( m22 + 1 ) / 2; + const zz = ( m33 + 1 ) / 2; + 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) { + + if ( xx < epsilon ) { + x = 0; y = 0.707106781; z = 0.707106781; + } else { - x = Math.sqrt(xx); + + x = Math.sqrt( xx ); y = xy / x; z = xz / x; + } - } else if (yy > zz) { + + } else if ( yy > zz ) { + // m22 is the largest diagonal term - if (yy < epsilon) { + + if ( yy < epsilon ) { + x = 0.707106781; y = 0; z = 0.707106781; + } else { - y = Math.sqrt(yy); + + y = Math.sqrt( yy ); x = xy / y; z = yz / y; + } + } else { + // m33 is the largest diagonal term so base result on this - if (zz < epsilon) { + + if ( zz < epsilon ) { + x = 0.707106781; y = 0.707106781; z = 0; + } else { - z = Math.sqrt(zz); + + z = Math.sqrt( zz ); x = xz / z; y = yz / z; + } + } - this.set(x, y, z, angle); + 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 + 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; - this.y = (m13 - m31) / s; - this.z = (m21 - m12) / s; - this.w = Math.acos((m11 + m22 + m33 - 1) / 2); + this.x = ( m32 - m23 ) / s; + this.y = ( m13 - m31 ) / s; + this.z = ( m21 - m12 ) / s; + this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); + return this; + } - min(v) { - this.x = Math.min(this.x, v.x); - this.y = Math.min(this.y, v.y); - this.z = Math.min(this.z, v.z); - this.w = Math.min(this.w, v.w); + min( v ) { + + this.x = Math.min( this.x, v.x ); + this.y = Math.min( this.y, v.y ); + this.z = Math.min( this.z, v.z ); + this.w = Math.min( this.w, v.w ); + return this; + } - max(v) { - this.x = Math.max(this.x, v.x); - this.y = Math.max(this.y, v.y); - this.z = Math.max(this.z, v.z); - this.w = Math.max(this.w, v.w); + max( v ) { + + this.x = Math.max( this.x, v.x ); + this.y = Math.max( this.y, v.y ); + this.z = Math.max( this.z, v.z ); + this.w = Math.max( this.w, v.w ); + return this; + } - clamp(min, max) { + 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)); + + 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)); - this.z = Math.max(minVal, Math.min(maxVal, this.z)); - this.w = Math.max(minVal, Math.min(maxVal, this.w)); + clampScalar( minVal, maxVal ) { + + this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); + this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); + this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); + this.w = Math.max( minVal, Math.min( maxVal, this.w ) ); + return this; + } - clampLength(min, max) { + clampLength( min, max ) { + const length = this.length(); - return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, 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); - this.w = Math.floor(this.w); + + this.x = Math.floor( this.x ); + this.y = Math.floor( this.y ); + this.z = Math.floor( this.z ); + this.w = Math.floor( this.w ); + return this; + } ceil() { - this.x = Math.ceil(this.x); - this.y = Math.ceil(this.y); - this.z = Math.ceil(this.z); - this.w = Math.ceil(this.w); + + this.x = Math.ceil( this.x ); + this.y = Math.ceil( this.y ); + this.z = Math.ceil( this.z ); + this.w = Math.ceil( this.w ); + return this; + } round() { - this.x = Math.round(this.x); - this.y = Math.round(this.y); - this.z = Math.round(this.z); - this.w = Math.round(this.w); + + this.x = Math.round( this.x ); + this.y = Math.round( this.y ); + this.z = Math.round( this.z ); + this.w = Math.round( this.w ); + return this; + } roundToZero() { - this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x); - this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y); - this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z); - this.w = this.w < 0 ? Math.ceil(this.w) : Math.floor(this.w); + + this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); + this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); + this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); + this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); + return this; + } negate() { - this.x = -this.x; - this.y = -this.y; - this.z = -this.z; - this.w = -this.w; + + this.x = - this.x; + this.y = - this.y; + this.z = - this.z; + this.w = - this.w; + return this; + } - dot(v) { + 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); + + 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); + + return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); + } normalize() { - return this.divideScalar(this.length() || 1); + + return this.divideScalar( this.length() || 1 ); + } - setLength(length) { - return this.normalize().multiplyScalar(length); + 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; - this.w += (v.w - this.w) * alpha; + lerp( v, alpha ) { + + this.x += ( v.x - this.x ) * alpha; + this.y += ( v.y - this.y ) * alpha; + this.z += ( v.z - this.z ) * alpha; + this.w += ( v.w - this.w ) * alpha; + return this; + } - lerpVectors(v1, v2, alpha) { - this.x = v1.x + (v2.x - v1.x) * alpha; - this.y = v1.y + (v2.y - v1.y) * alpha; - this.z = v1.z + (v2.z - v1.z) * alpha; - this.w = v1.w + (v2.w - v1.w) * alpha; + lerpVectors( v1, v2, alpha ) { + + this.x = v1.x + ( v2.x - v1.x ) * alpha; + this.y = v1.y + ( v2.y - v1.y ) * alpha; + this.z = v1.z + ( v2.z - v1.z ) * alpha; + this.w = v1.w + ( v2.w - v1.w ) * alpha; + return this; + } - equals(v) { - return v.x === this.x && v.y === this.y && v.z === this.z && v.w === this.w; + 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]; - this.z = array[offset + 2]; - this.w = array[offset + 3]; + fromArray( array, offset = 0 ) { + + this.x = array[ offset ]; + this.y = array[ offset + 1 ]; + this.z = array[ offset + 2 ]; + this.w = array[ offset + 3 ]; + return this; + } - toArray(array = [], offset = 0) { - array[offset] = this.x; - array[offset + 1] = this.y; - array[offset + 2] = this.z; - array[offset + 3] = this.w; + toArray( array = [], offset = 0 ) { + + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + array[ offset + 2 ] = this.z; + array[ offset + 3 ] = this.w; + return array; + } - fromBufferAttribute(attribute, index, offset) { - if (offset !== undefined) { - console.warn('THREE.Vector4: offset has been removed from .fromBufferAttribute().'); - } + fromBufferAttribute( attribute, index ) { + + this.x = attribute.getX( index ); + this.y = attribute.getY( index ); + this.z = attribute.getZ( index ); + this.w = attribute.getW( index ); - this.x = attribute.getX(index); - this.y = attribute.getY(index); - this.z = attribute.getZ(index); - this.w = attribute.getW(index); return this; + } random() { + this.x = Math.random(); this.y = Math.random(); this.z = Math.random(); this.w = Math.random(); + return this; + } - *[Symbol.iterator]() { + *[ Symbol.iterator ]() { + yield this.x; yield this.y; yield this.z; yield this.w; + } } @@ -2617,111 +3322,149 @@ 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; this.height = height; this.depth = 1; - this.scissor = new Vector4(0, 0, width, height); + + this.scissor = new Vector4( 0, 0, width, height ); this.scissorTest = false; - this.viewport = new Vector4(0, 0, width, height); - const image = { - width: width, - height: height, - depth: 1 - }; - this.texture = new Texture(image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); + + this.viewport = new Vector4( 0, 0, width, height ); + + const image = { width: width, height: height, depth: 1 }; + + this.texture = new Texture( image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); this.texture.isRenderTargetTexture = true; + this.texture.flipY = false; this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; this.texture.internalFormat = options.internalFormat !== undefined ? options.internalFormat : null; this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; + this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false; + this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; + this.samples = options.samples !== undefined ? options.samples : 0; + } - setSize(width, height, depth = 1) { - if (this.width !== width || this.height !== height || this.depth !== depth) { + setSize( width, height, depth = 1 ) { + + if ( this.width !== width || this.height !== height || this.depth !== depth ) { + this.width = width; this.height = height; this.depth = depth; + this.texture.image.width = width; this.texture.image.height = height; this.texture.image.depth = depth; + this.dispose(); + } - this.viewport.set(0, 0, width, height); - this.scissor.set(0, 0, width, height); + this.viewport.set( 0, 0, width, height ); + this.scissor.set( 0, 0, width, height ); + } clone() { - return new this.constructor().copy(this); + + return new this.constructor().copy( this ); + } - copy(source) { + copy( source ) { + this.width = source.width; this.height = source.height; this.depth = source.depth; - this.viewport.copy(source.viewport); + + 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 ); - const image = Object.assign({}, source.texture.image); - this.texture.source = new Source(image); this.depthBuffer = source.depthBuffer; this.stencilBuffer = source.stencilBuffer; - if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone(); + + if ( source.depthTexture !== null ) this.depthTexture = source.depthTexture.clone(); + this.samples = source.samples; + return this; + } dispose() { - this.dispatchEvent({ - type: 'dispose' - }); + + this.dispatchEvent( { type: 'dispose' } ); + } } class DataArrayTexture extends Texture { - constructor(data = null, width = 1, height = 1, depth = 1) { - super(null); + + constructor( data = null, width = 1, height = 1, depth = 1 ) { + + super( null ); + this.isDataArrayTexture = true; - this.image = { - data, - width, - height, - depth - }; + + this.image = { data, width, height, depth }; + this.magFilter = NearestFilter; this.minFilter = NearestFilter; + this.wrapR = ClampToEdgeWrapping; + this.generateMipmaps = false; this.flipY = false; this.unpackAlignment = 1; + } } class WebGLArrayRenderTarget extends WebGLRenderTarget { - constructor(width, height, depth) { - super(width, height); + + 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 = new DataArrayTexture( null, width, height, depth ); + this.texture.isRenderTargetTexture = true; + } } class Data3DTexture extends Texture { - constructor(data = null, width = 1, height = 1, depth = 1) { + + constructor( data = null, width = 1, height = 1, depth = 1 ) { + // We're going to add .setXXX() methods for setting properties later. // Users can still set in DataTexture3D directly. // @@ -2729,222 +3472,291 @@ class Data3DTexture extends Texture { // texture.anisotropy = 16; // // See #14839 - super(null); + + super( null ); + this.isData3DTexture = true; - this.image = { - data, - width, - height, - depth - }; + + this.image = { data, width, height, depth }; + this.magFilter = NearestFilter; this.minFilter = NearestFilter; + this.wrapR = ClampToEdgeWrapping; + this.generateMipmaps = false; this.flipY = false; this.unpackAlignment = 1; + } } class WebGL3DRenderTarget extends WebGLRenderTarget { - constructor(width, height, depth) { - super(width, height); + + 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 = new Data3DTexture( null, width, height, depth ); + this.texture.isRenderTargetTexture = true; + } } class WebGLMultipleRenderTargets extends WebGLRenderTarget { - constructor(width, height, count, options = {}) { - super(width, height, 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; + 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) { + 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; + 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); + this.viewport.set( 0, 0, width, height ); + this.scissor.set( 0, 0, width, height ); + return this; + } - copy(source) { + copy( source ) { + this.dispose(); + this.width = source.width; this.height = source.height; this.depth = source.depth; - this.viewport.set(0, 0, this.width, this.height); - this.scissor.set(0, 0, this.width, this.height); + + this.viewport.set( 0, 0, this.width, this.height ); + this.scissor.set( 0, 0, this.width, this.height ); + this.depthBuffer = source.depthBuffer; this.stencilBuffer = source.stencilBuffer; - if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone(); + + 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; + 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 { - constructor(x = 0, y = 0, z = 0, w = 1) { + + constructor( x = 0, y = 0, z = 0, w = 1 ) { + this.isQuaternion = true; + this._x = x; this._y = y; this._z = z; this._w = w; - } - static slerp(qa, qb, qm, t) { - console.warn('THREE.Quaternion: Static .slerp() has been deprecated. Use qm.slerpQuaternions( qa, qb, t ) instead.'); - return qm.slerpQuaternions(qa, qb, t); } - static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) { + static slerpFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { + // fuzz-free, array-based Quaternion SLERP operation - let x0 = src0[srcOffset0 + 0], - y0 = src0[srcOffset0 + 1], - z0 = src0[srcOffset0 + 2], - w0 = src0[srcOffset0 + 3]; - const x1 = src1[srcOffset1 + 0], - y1 = src1[srcOffset1 + 1], - z1 = src1[srcOffset1 + 2], - w1 = src1[srcOffset1 + 3]; - - if (t === 0) { - dst[dstOffset + 0] = x0; - dst[dstOffset + 1] = y0; - dst[dstOffset + 2] = z0; - dst[dstOffset + 3] = w0; + + let x0 = src0[ srcOffset0 + 0 ], + y0 = src0[ srcOffset0 + 1 ], + z0 = src0[ srcOffset0 + 2 ], + w0 = src0[ srcOffset0 + 3 ]; + + const x1 = src1[ srcOffset1 + 0 ], + y1 = src1[ srcOffset1 + 1 ], + z1 = src1[ srcOffset1 + 2 ], + w1 = src1[ srcOffset1 + 3 ]; + + if ( t === 0 ) { + + dst[ dstOffset + 0 ] = x0; + dst[ dstOffset + 1 ] = y0; + dst[ dstOffset + 2 ] = z0; + dst[ dstOffset + 3 ] = w0; return; + } - if (t === 1) { - dst[dstOffset + 0] = x1; - dst[dstOffset + 1] = y1; - dst[dstOffset + 2] = z1; - dst[dstOffset + 3] = w1; + if ( t === 1 ) { + + dst[ dstOffset + 0 ] = x1; + dst[ dstOffset + 1 ] = y1; + dst[ dstOffset + 2 ] = z1; + dst[ dstOffset + 3 ] = w1; return; + } - if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) { + 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 ); + + s = Math.sin( s * len ) / sin; + t = Math.sin( t * len ) / sin; - if (sqrSin > Number.EPSILON) { - const sin = Math.sqrt(sqrSin), - len = Math.atan2(sin, cos * dir); - s = Math.sin(s * len) / sin; - t = Math.sin(t * len) / sin; } const tDir = t * dir; + x0 = x0 * s + x1 * tDir; y0 = y0 * s + y1 * tDir; z0 = z0 * s + z1 * tDir; - w0 = w0 * s + w1 * tDir; // Normalize in case we just did a lerp: + 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 ); - if (s === 1 - t) { - const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0); x0 *= f; y0 *= f; z0 *= f; w0 *= f; + } + } - dst[dstOffset] = x0; - dst[dstOffset + 1] = y0; - dst[dstOffset + 2] = z0; - dst[dstOffset + 3] = w0; + dst[ dstOffset ] = x0; + dst[ dstOffset + 1 ] = y0; + dst[ dstOffset + 2 ] = z0; + dst[ dstOffset + 3 ] = w0; + } - static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) { - const x0 = src0[srcOffset0]; - const y0 = src0[srcOffset0 + 1]; - const z0 = src0[srcOffset0 + 2]; - const w0 = src0[srcOffset0 + 3]; - const x1 = src1[srcOffset1]; - const y1 = src1[srcOffset1 + 1]; - const z1 = src1[srcOffset1 + 2]; - const w1 = src1[srcOffset1 + 3]; - dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1; - dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1; - dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1; - dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1; + static multiplyQuaternionsFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1 ) { + + const x0 = src0[ srcOffset0 ]; + const y0 = src0[ srcOffset0 + 1 ]; + const z0 = src0[ srcOffset0 + 2 ]; + const w0 = src0[ srcOffset0 + 3 ]; + + const x1 = src1[ srcOffset1 ]; + const y1 = src1[ srcOffset1 + 1 ]; + const z1 = src1[ srcOffset1 + 2 ]; + const w1 = src1[ srcOffset1 + 3 ]; + + dst[ dstOffset ] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1; + dst[ dstOffset + 1 ] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1; + dst[ dstOffset + 2 ] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1; + dst[ dstOffset + 3 ] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1; + return dst; + } get x() { + return this._x; + } - set x(value) { - this._x = value; + set x( value ) { + this._x = value; this._onChangeCallback(); + } get y() { + return this._y; + } - set y(value) { - this._y = value; + set y( value ) { + this._y = value; this._onChangeCallback(); + } get z() { + return this._z; + } - set z(value) { - this._z = value; + set z( value ) { + this._z = value; this._onChangeCallback(); + } get w() { + return this._w; + } - set w(value) { - this._w = value; + set w( value ) { + this._w = value; this._onChangeCallback(); + } - set(x, y, z, w) { + set( x, y, z, w ) { + this._x = x; this._y = y; this._z = z; @@ -2953,13 +3765,17 @@ class Quaternion { this._onChangeCallback(); return this; + } clone() { - return new this.constructor(this._x, this._y, this._z, this._w); + + return new this.constructor( this._x, this._y, this._z, this._w ); + } - copy(quaternion) { + copy( quaternion ) { + this._x = quaternion.x; this._y = quaternion.y; this._z = quaternion.z; @@ -2968,30 +3784,30 @@ class Quaternion { 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.'); - } + setFromEuler( euler, update ) { - const x = euler._x, - y = euler._y, - z = euler._z, - order = euler._order; // http://www.mathworks.com/matlabcentral/fileexchange/ + const x = euler._x, y = euler._y, z = euler._z, order = euler._order; + + // http://www.mathworks.com/matlabcentral/fileexchange/ // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ // content/SpinCalc.m const cos = Math.cos; const sin = Math.sin; - const c1 = cos(x / 2); - const c2 = cos(y / 2); - const c3 = cos(z / 2); - const s1 = sin(x / 2); - const s2 = sin(y / 2); - const s3 = sin(z / 2); - - switch (order) { + + const c1 = cos( x / 2 ); + const c2 = cos( y / 2 ); + const c3 = cos( z / 2 ); + + const s1 = sin( x / 2 ); + const s2 = sin( y / 2 ); + const s3 = sin( z / 2 ); + + switch ( order ) { + case 'XYZ': this._x = s1 * c2 * c3 + c1 * s2 * s3; this._y = c1 * s2 * c3 - s1 * c2 * s3; @@ -3035,191 +3851,247 @@ class Quaternion { break; default: - console.warn('THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order); + console.warn( 'THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order ); + } - if (update !== false) this._onChangeCallback(); + if ( update !== false ) this._onChangeCallback(); + return this; + } - setFromAxisAngle(axis, angle) { + 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); + + const halfAngle = angle / 2, s = Math.sin( halfAngle ); + this._x = axis.x * s; this._y = axis.y * s; this._z = axis.z * s; - this._w = Math.cos(halfAngle); + this._w = Math.cos( halfAngle ); this._onChangeCallback(); return this; + } - setFromRotationMatrix(m) { + setFromRotationMatrix( m ) { + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + const te = m.elements, - m11 = te[0], - m12 = te[4], - m13 = te[8], - m21 = te[1], - m22 = te[5], - m23 = te[9], - m31 = te[2], - m32 = te[6], - m33 = te[10], - trace = m11 + m22 + m33; - - if (trace > 0) { - const s = 0.5 / Math.sqrt(trace + 1.0); + + m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], + m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], + m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ], + + trace = m11 + m22 + m33; + + if ( trace > 0 ) { + + const s = 0.5 / Math.sqrt( trace + 1.0 ); + this._w = 0.25 / s; - this._x = (m32 - m23) * s; - this._y = (m13 - m31) * s; - this._z = (m21 - m12) * s; - } else if (m11 > m22 && m11 > m33) { - const s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33); - this._w = (m32 - m23) / s; + this._x = ( m32 - m23 ) * s; + this._y = ( m13 - m31 ) * s; + this._z = ( m21 - m12 ) * s; + + } else if ( m11 > m22 && m11 > m33 ) { + + const s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); + + this._w = ( m32 - m23 ) / s; this._x = 0.25 * s; - this._y = (m12 + m21) / s; - this._z = (m13 + m31) / s; - } else if (m22 > m33) { - const s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33); - this._w = (m13 - m31) / s; - this._x = (m12 + m21) / s; + this._y = ( m12 + m21 ) / s; + this._z = ( m13 + m31 ) / s; + + } else if ( m22 > m33 ) { + + const s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); + + this._w = ( m13 - m31 ) / s; + this._x = ( m12 + m21 ) / s; this._y = 0.25 * s; - this._z = (m23 + m32) / s; + this._z = ( m23 + m32 ) / s; + } else { - const s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22); - this._w = (m21 - m12) / s; - this._x = (m13 + m31) / s; - this._y = (m23 + m32) / s; + + const s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); + + this._w = ( m21 - m12 ) / s; + this._x = ( m13 + m31 ) / s; + this._y = ( m23 + m32 ) / s; this._z = 0.25 * s; + } this._onChangeCallback(); return this; + } - setFromUnitVectors(vFrom, vTo) { + setFromUnitVectors( vFrom, vTo ) { + // assumes direction vectors vFrom and vTo are normalized - let r = vFrom.dot(vTo) + 1; - if (r < Number.EPSILON) { + let r = vFrom.dot( vTo ) + 1; + + if ( r < Number.EPSILON ) { + // vFrom and vTo point in opposite directions + r = 0; - if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { - this._x = -vFrom.y; + if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { + + this._x = - vFrom.y; this._y = vFrom.x; this._z = 0; this._w = r; + } else { + this._x = 0; - this._y = -vFrom.z; + this._y = - vFrom.z; this._z = vFrom.y; this._w = r; + } + } else { + // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 + this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; this._w = r; + } return this.normalize(); + } - angleTo(q) { - return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1))); + angleTo( q ) { + + return 2 * Math.acos( Math.abs( clamp( this.dot( q ), - 1, 1 ) ) ); + } - rotateTowards(q, step) { - const angle = this.angleTo(q); - if (angle === 0) return this; - const t = Math.min(1, step / angle); - this.slerp(q, t); + rotateTowards( q, step ) { + + const angle = this.angleTo( q ); + + if ( angle === 0 ) return this; + + const t = Math.min( 1, step / angle ); + + this.slerp( q, t ); + return this; + } identity() { - return this.set(0, 0, 0, 1); + + 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._x *= - 1; + this._y *= - 1; + this._z *= - 1; this._onChangeCallback(); return this; + } - dot(v) { + 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); + + 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) { + if ( l === 0 ) { + this._x = 0; this._y = 0; this._z = 0; this._w = 1; + } else { + l = 1 / l; + this._x = this._x * l; this._y = this._y * l; this._z = this._z * l; this._w = this._w * l; + } this._onChangeCallback(); return this; + } - multiply(q, p) { - if (p !== undefined) { - console.warn('THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.'); - return this.multiplyQuaternions(q, p); - } + multiply( q ) { + + return this.multiplyQuaternions( this, q ); - return this.multiplyQuaternions(this, q); } - premultiply(q) { - return this.multiplyQuaternions(q, this); + premultiply( q ) { + + return this.multiplyQuaternions( q, this ); + } - multiplyQuaternions(a, b) { + multiplyQuaternions( a, b ) { + // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm - const qax = a._x, - qay = a._y, - qaz = a._z, - qaw = a._w; - const qbx = b._x, - qby = b._y, - qbz = b._z, - qbw = b._w; + + const qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; + const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; + this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; @@ -3228,2391 +4100,3066 @@ class Quaternion { 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/ + slerp( qb, t ) { + + if ( t === 0 ) return this; + if ( t === 1 ) return this.copy( qb ); + + const x = this._x, y = this._y, z = this._z, w = this._w; + + // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; - if (cosHalfTheta < 0) { - this._w = -qb._w; - this._x = -qb._x; - this._y = -qb._y; - this._z = -qb._z; - cosHalfTheta = -cosHalfTheta; + if ( cosHalfTheta < 0 ) { + + this._w = - qb._w; + this._x = - qb._x; + this._y = - qb._y; + this._z = - qb._z; + + cosHalfTheta = - cosHalfTheta; + } else { - this.copy(qb); + + this.copy( qb ); + } - if (cosHalfTheta >= 1.0) { + if ( cosHalfTheta >= 1.0 ) { + this._w = w; this._x = x; this._y = y; this._z = z; + return this; + } const sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; - if (sqrSinHalfTheta <= Number.EPSILON) { + if ( sqrSinHalfTheta <= Number.EPSILON ) { + const s = 1 - t; this._w = s * w + t * this._w; this._x = s * x + t * this._x; this._y = s * y + t * this._y; this._z = s * z + t * this._z; - this.normalize(); + this.normalize(); this._onChangeCallback(); return this; + } - const sinHalfTheta = Math.sqrt(sqrSinHalfTheta); - const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta); - const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta, - ratioB = Math.sin(t * halfTheta) / sinHalfTheta; - this._w = w * ratioA + this._w * ratioB; - this._x = x * ratioA + this._x * ratioB; - this._y = y * ratioA + this._y * ratioB; - this._z = z * ratioA + this._z * ratioB; + const sinHalfTheta = Math.sqrt( sqrSinHalfTheta ); + const halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta ); + const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, + ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; + + this._w = ( w * ratioA + this._w * ratioB ); + this._x = ( x * ratioA + this._x * ratioB ); + this._y = ( y * ratioA + this._y * ratioB ); + this._z = ( z * ratioA + this._z * ratioB ); this._onChangeCallback(); return this; + } - slerpQuaternions(qa, qb, t) { - return this.copy(qa).slerp(qb, t); + slerpQuaternions( qa, qb, t ) { + + return this.copy( qa ).slerp( qb, t ); + } random() { + // Derived from http://planning.cs.uiuc.edu/node198.html // Note, this source uses w, x, y, z ordering, // so we swap the order below. + const u1 = Math.random(); - const sqrt1u1 = Math.sqrt(1 - u1); - const sqrtu1 = Math.sqrt(u1); + const sqrt1u1 = Math.sqrt( 1 - u1 ); + const sqrtu1 = Math.sqrt( u1 ); + const u2 = 2 * Math.PI * Math.random(); + const u3 = 2 * Math.PI * Math.random(); - return this.set(sqrt1u1 * Math.cos(u2), sqrtu1 * Math.sin(u3), sqrtu1 * Math.cos(u3), sqrt1u1 * Math.sin(u2)); + + 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; + 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]; + fromArray( array, offset = 0 ) { + + this._x = array[ offset ]; + this._y = array[ offset + 1 ]; + this._z = array[ offset + 2 ]; + this._w = array[ offset + 3 ]; this._onChangeCallback(); return this; + } - toArray(array = [], offset = 0) { - array[offset] = this._x; - array[offset + 1] = this._y; - array[offset + 2] = this._z; - array[offset + 3] = this._w; + toArray( array = [], offset = 0 ) { + + array[ offset ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._w; + return array; + } - fromBufferAttribute(attribute, index) { - this._x = attribute.getX(index); - this._y = attribute.getY(index); - this._z = attribute.getZ(index); - this._w = attribute.getW(index); + fromBufferAttribute( attribute, index ) { + + this._x = attribute.getX( index ); + this._y = attribute.getY( index ); + this._z = attribute.getZ( index ); + this._w = attribute.getW( index ); + return this; + } - _onChange(callback) { + _onChange( callback ) { + this._onChangeCallback = callback; + return this; + } _onChangeCallback() {} - *[Symbol.iterator]() { + *[ Symbol.iterator ]() { + yield this._x; yield this._y; yield this._z; yield this._w; + } } class Vector3 { - constructor(x = 0, y = 0, z = 0) { - this.isVector3 = true; + + constructor( x = 0, y = 0, z = 0 ) { + + Vector3.prototype.isVector3 = true; + this.x = x; this.y = y; this.z = z; + } - set(x, y, z) { - if (z === undefined) z = this.z; // sprite.scale.set(x,y) + set( x, y, z ) { + + if ( z === undefined ) z = this.z; // sprite.scale.set(x,y) this.x = x; this.y = y; this.z = z; + return this; + } - setScalar(scalar) { + setScalar( scalar ) { + this.x = scalar; this.y = scalar; this.z = scalar; + return this; + } - setX(x) { + setX( x ) { + this.x = x; + return this; + } - setY(y) { + setY( y ) { + this.y = y; + return this; + } - setZ(z) { + setZ( z ) { + this.z = z; + return this; + } - setComponent(index, value) { - switch (index) { - case 0: - this.x = value; - break; + setComponent( index, value ) { - case 1: - this.y = value; - break; + switch ( index ) { - case 2: - this.z = value; - break; + 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 ); - default: - throw new Error('index is out of range: ' + index); } return this; + } - getComponent(index) { - switch (index) { - case 0: - return this.x; + getComponent( index ) { - case 1: - return this.y; + switch ( index ) { - case 2: - return this.z; + 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 ); - default: - throw new Error('index is out of range: ' + index); } + } clone() { - return new this.constructor(this.x, this.y, this.z); + + return new this.constructor( this.x, this.y, this.z ); + } - copy(v) { + copy( v ) { + this.x = v.x; this.y = v.y; this.z = v.z; + return this; + } - add(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.'); - return this.addVectors(v, w); - } + add( v ) { this.x += v.x; this.y += v.y; this.z += v.z; + return this; + } - addScalar(s) { + addScalar( s ) { + this.x += s; this.y += s; this.z += s; + return this; + } - addVectors(a, b) { + 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) { + addScaledVector( v, s ) { + this.x += v.x * s; this.y += v.y * s; this.z += v.z * s; + return this; + } - sub(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.'); - return this.subVectors(v, w); - } + sub( v ) { this.x -= v.x; this.y -= v.y; this.z -= v.z; + return this; + } - subScalar(s) { + subScalar( s ) { + this.x -= s; this.y -= s; this.z -= s; + return this; + } - subVectors(a, b) { + subVectors( a, b ) { + this.x = a.x - b.x; this.y = a.y - b.y; this.z = a.z - b.z; + return this; + } - multiply(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.'); - return this.multiplyVectors(v, w); - } + multiply( v ) { this.x *= v.x; this.y *= v.y; this.z *= v.z; + return this; + } - multiplyScalar(scalar) { + multiplyScalar( scalar ) { + this.x *= scalar; this.y *= scalar; this.z *= scalar; + return this; + } - multiplyVectors(a, b) { + multiplyVectors( a, b ) { + this.x = a.x * b.x; this.y = a.y * b.y; this.z = a.z * b.z; + return this; + } - applyEuler(euler) { - if (!(euler && euler.isEuler)) { - console.error('THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.'); - } + applyEuler( euler ) { + + return this.applyQuaternion( _quaternion$4.setFromEuler( euler ) ); - return this.applyQuaternion(_quaternion$4.setFromEuler(euler)); } - applyAxisAngle(axis, angle) { - return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle)); + applyAxisAngle( axis, angle ) { + + return this.applyQuaternion( _quaternion$4.setFromAxisAngle( axis, angle ) ); + } - applyMatrix3(m) { - const x = this.x, - y = this.y, - z = this.z; + applyMatrix3( m ) { + + const x = this.x, y = this.y, z = this.z; const e = m.elements; - this.x = e[0] * x + e[3] * y + e[6] * z; - this.y = e[1] * x + e[4] * y + e[7] * z; - this.z = e[2] * x + e[5] * y + e[8] * z; + + 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(); + applyNormalMatrix( m ) { + + return this.applyMatrix3( m ).normalize(); + } - applyMatrix4(m) { - const x = this.x, - y = this.y, - z = this.z; + applyMatrix4( m ) { + + const x = this.x, y = this.y, z = this.z; const e = m.elements; - const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]); - this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * w; - this.y = (e[1] * x + e[5] * y + e[9] * z + e[13]) * w; - this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w; + + const w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); + + this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; + this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; + this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; + return this; + } - applyQuaternion(q) { - const x = this.x, - y = this.y, - z = this.z; - const qx = q.x, - qy = q.y, - qz = q.z, - qw = q.w; // calculate quat * vector + applyQuaternion( q ) { + + const x = this.x, y = this.y, z = this.z; + const qx = q.x, qy = q.y, qz = q.z, qw = q.w; + + // calculate quat * vector const ix = qw * x + qy * z - qz * y; const iy = qw * y + qz * x - qx * z; const iz = qw * z + qx * y - qy * x; - const iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat + 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; - 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); + project( camera ) { + + return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix ); + } - unproject(camera) { - return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld); + unproject( camera ) { + + return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld ); + } - transformDirection(m) { + transformDirection( m ) { + // input: THREE.Matrix4 affine matrix // vector interpreted as a direction - const x = this.x, - y = this.y, - z = this.z; + + const x = this.x, y = this.y, z = this.z; const e = m.elements; - this.x = e[0] * x + e[4] * y + e[8] * z; - this.y = e[1] * x + e[5] * y + e[9] * z; - this.z = e[2] * x + e[6] * y + e[10] * z; + + 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) { + divide( v ) { + this.x /= v.x; this.y /= v.y; this.z /= v.z; + return this; + } - divideScalar(scalar) { - return this.multiplyScalar(1 / scalar); + 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); + 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); + 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) { + 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.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)); + 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) { + clampLength( min, max ) { + const length = this.length(); - return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, 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); + + 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); + + 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); + + 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); + + 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; + + this.x = - this.x; + this.y = - this.y; + this.z = - this.z; + return this; + } - dot(v) { + 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); + + 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); + + return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); + } normalize() { - return this.divideScalar(this.length() || 1); + + return this.divideScalar( this.length() || 1 ); + } - setLength(length) { - return this.normalize().multiplyScalar(length); + 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; + 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; + lerpVectors( v1, v2, alpha ) { + + this.x = v1.x + ( v2.x - v1.x ) * alpha; + this.y = v1.y + ( v2.y - v1.y ) * alpha; + this.z = v1.z + ( v2.z - v1.z ) * alpha; + return this; + } - cross(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.'); - return this.crossVectors(v, w); - } + cross( v ) { + + return this.crossVectors( this, v ); - return this.crossVectors(this, v); } - crossVectors(a, b) { - const ax = a.x, - ay = a.y, - az = a.z; - const bx = b.x, - by = b.y, - bz = b.z; + crossVectors( a, b ) { + + const ax = a.x, ay = a.y, az = a.z; + const bx = b.x, by = b.y, bz = b.z; + this.x = ay * bz - az * by; this.y = az * bx - ax * bz; this.z = ax * by - ay * bx; + return this; + } - projectOnVector(v) { + 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); + + 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); + projectOnPlane( planeNormal ) { + + _vector$c.copy( this ).projectOnVector( planeNormal ); + + return this.sub( _vector$c ); - return this.sub(_vector$c); } - reflect(normal) { + 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))); + + 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 + angleTo( v ) { + + const denominator = Math.sqrt( this.lengthSq() * v.lengthSq() ); + + if ( denominator === 0 ) return Math.PI / 2; + + const theta = this.dot( v ) / denominator; + + // clamp, to handle numerical problems + + return Math.acos( clamp( theta, - 1, 1 ) ); - return Math.acos(clamp(theta, -1, 1)); } - distanceTo(v) { - return Math.sqrt(this.distanceToSquared(v)); + 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; + distanceToSquared( v ) { + + const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; + return dx * dx + dy * dy + dz * dz; + } - manhattanDistanceTo(v) { - return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z); + 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); + setFromSpherical( s ) { + + return this.setFromSphericalCoords( s.radius, s.phi, s.theta ); + } - setFromSphericalCoords(radius, phi, theta) { - const sinPhiRadius = Math.sin(phi) * radius; - this.x = sinPhiRadius * Math.sin(theta); - this.y = Math.cos(phi) * radius; - this.z = sinPhiRadius * Math.cos(theta); + setFromSphericalCoords( radius, phi, theta ) { + + const sinPhiRadius = Math.sin( phi ) * radius; + + this.x = sinPhiRadius * Math.sin( theta ); + this.y = Math.cos( phi ) * radius; + this.z = sinPhiRadius * Math.cos( theta ); + return this; + } - setFromCylindrical(c) { - return this.setFromCylindricalCoords(c.radius, c.theta, c.y); + setFromCylindrical( c ) { + + return this.setFromCylindricalCoords( c.radius, c.theta, c.y ); + } - setFromCylindricalCoords(radius, theta, y) { - this.x = radius * Math.sin(theta); + setFromCylindricalCoords( radius, theta, y ) { + + this.x = radius * Math.sin( theta ); this.y = y; - this.z = radius * Math.cos(theta); + this.z = radius * Math.cos( theta ); + return this; + } - setFromMatrixPosition(m) { + setFromMatrixPosition( m ) { + const e = m.elements; - this.x = e[12]; - this.y = e[13]; - this.z = e[14]; + + this.x = e[ 12 ]; + this.y = e[ 13 ]; + this.z = e[ 14 ]; + return this; + } - setFromMatrixScale(m) { - const sx = this.setFromMatrixColumn(m, 0).length(); - const sy = this.setFromMatrixColumn(m, 1).length(); - const sz = this.setFromMatrixColumn(m, 2).length(); + setFromMatrixScale( m ) { + + const sx = this.setFromMatrixColumn( m, 0 ).length(); + const sy = this.setFromMatrixColumn( m, 1 ).length(); + const sz = this.setFromMatrixColumn( m, 2 ).length(); + this.x = sx; this.y = sy; this.z = sz; + return this; + } - setFromMatrixColumn(m, index) { - return this.fromArray(m.elements, index * 4); + setFromMatrixColumn( m, index ) { + + return this.fromArray( m.elements, index * 4 ); + } - setFromMatrix3Column(m, index) { - return this.fromArray(m.elements, index * 3); + setFromMatrix3Column( m, index ) { + + return this.fromArray( m.elements, index * 3 ); + } - setFromEuler(e) { + 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; + 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]; + 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; + toArray( array = [], offset = 0 ) { + + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + array[ offset + 2 ] = this.z; + return array; + } - fromBufferAttribute(attribute, index, offset) { - if (offset !== undefined) { - console.warn('THREE.Vector3: offset has been removed from .fromBufferAttribute().'); - } + fromBufferAttribute( attribute, index ) { + + this.x = attribute.getX( index ); + this.y = attribute.getY( index ); + this.z = attribute.getZ( 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 u = ( Math.random() - 0.5 ) * 2; const t = Math.random() * Math.PI * 2; - const f = Math.sqrt(1 - u ** 2); - this.x = f * Math.cos(t); - this.y = f * Math.sin(t); + const f = Math.sqrt( 1 - u ** 2 ); + + this.x = f * Math.cos( t ); + this.y = f * Math.sin( t ); this.z = u; + return this; + } - *[Symbol.iterator]() { + *[ Symbol.iterator ]() { + yield this.x; yield this.y; yield this.z; + } } -const _vector$c = /*@__PURE__*/new Vector3(); - -const _quaternion$4 = /*@__PURE__*/new Quaternion(); +const _vector$c = /*@__PURE__*/ new Vector3(); +const _quaternion$4 = /*@__PURE__*/ new Quaternion(); class Box3 { - constructor(min = new Vector3(+Infinity, +Infinity, +Infinity), max = new Vector3(-Infinity, -Infinity, -Infinity)) { + + constructor( min = new Vector3( + Infinity, + Infinity, + Infinity ), max = new Vector3( - Infinity, - Infinity, - Infinity ) ) { + this.isBox3 = true; + 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; - let minZ = +Infinity; - let maxX = -Infinity; - let maxY = -Infinity; - let maxZ = -Infinity; + set( min, max ) { - for (let i = 0, l = array.length; i < l; i += 3) { - const x = array[i]; - const y = array[i + 1]; - const z = array[i + 2]; - if (x < minX) minX = x; - if (y < minY) minY = y; - if (z < minZ) minZ = z; - if (x > maxX) maxX = x; - if (y > maxY) maxY = y; - if (z > maxZ) maxZ = z; - } + this.min.copy( min ); + this.max.copy( max ); - this.min.set(minX, minY, minZ); - this.max.set(maxX, maxY, maxZ); return this; + } - setFromBufferAttribute(attribute) { - let minX = +Infinity; - let minY = +Infinity; - let minZ = +Infinity; - let maxX = -Infinity; - let maxY = -Infinity; - let maxZ = -Infinity; + setFromArray( array ) { - for (let i = 0, l = attribute.count; i < l; i++) { - const x = attribute.getX(i); - const y = attribute.getY(i); - const z = attribute.getZ(i); - if (x < minX) minX = x; - if (y < minY) minY = y; - if (z < minZ) minZ = z; - if (x > maxX) maxX = x; - if (y > maxY) maxY = y; - if (z > maxZ) maxZ = z; - } + let minX = + Infinity; + let minY = + Infinity; + let minZ = + Infinity; - this.min.set(minX, minY, minZ); - this.max.set(maxX, maxY, maxZ); - return this; - } + let maxX = - Infinity; + let maxY = - Infinity; + let maxZ = - Infinity; - setFromPoints(points) { - this.makeEmpty(); + for ( let i = 0, l = array.length; i < l; i += 3 ) { + + const x = array[ i ]; + const y = array[ i + 1 ]; + const z = array[ i + 2 ]; + + if ( x < minX ) minX = x; + if ( y < minY ) minY = y; + if ( z < minZ ) minZ = z; + + if ( x > maxX ) maxX = x; + if ( y > maxY ) maxY = y; + if ( z > maxZ ) maxZ = z; - for (let i = 0, il = points.length; i < il; i++) { - this.expandByPoint(points[i]); } + this.min.set( minX, minY, minZ ); + this.max.set( maxX, maxY, maxZ ); + return this; + } - setFromCenterAndSize(center, size) { - const halfSize = _vector$b.copy(size).multiplyScalar(0.5); + setFromBufferAttribute( attribute ) { + + let minX = + Infinity; + let minY = + Infinity; + let minZ = + Infinity; + + 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 ); + const z = attribute.getZ( i ); + + if ( x < minX ) minX = x; + if ( y < minY ) minY = y; + if ( z < minZ ) minZ = z; + + if ( x > maxX ) maxX = x; + if ( y > maxY ) maxY = y; + if ( z > maxZ ) maxZ = z; + + } + + this.min.set( minX, minY, minZ ); + this.max.set( maxX, maxY, maxZ ); + + return this; + + } + + 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 ); - this.min.copy(center).sub(halfSize); - this.max.copy(center).add(halfSize); return this; + } - setFromObject(object, precise = false) { + setFromObject( object, precise = false ) { + this.makeEmpty(); - return this.expandByObject(object, precise); + + return this.expandByObject( object, precise ); + } clone() { - return new this.constructor().copy(this); + + return new this.constructor().copy( this ); + } - copy(box) { - this.min.copy(box.min); - this.max.copy(box.max); + 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; + + 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; + + 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); + 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); + 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); + expandByPoint( point ) { + + this.min.min( point ); + this.max.max( point ); + return this; + } - expandByVector(vector) { - this.min.sub(vector); - this.max.add(vector); + expandByVector( vector ) { + + this.min.sub( vector ); + this.max.add( vector ); + return this; + } - expandByScalar(scalar) { - this.min.addScalar(-scalar); - this.max.addScalar(scalar); + expandByScalar( scalar ) { + + this.min.addScalar( - scalar ); + this.max.addScalar( scalar ); + return this; + } - expandByObject(object, precise = false) { + 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); + + object.updateWorldMatrix( false, false ); + const geometry = object.geometry; - if (geometry !== undefined) { - if (precise && geometry.attributes != undefined && geometry.attributes.position !== undefined) { + 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 ++ ) { - for (let i = 0, l = position.count; i < l; i++) { - _vector$b.fromBufferAttribute(position, i).applyMatrix4(object.matrixWorld); + _vector$b.fromBufferAttribute( position, i ).applyMatrix4( object.matrixWorld ); + this.expandByPoint( _vector$b ); - this.expandByPoint(_vector$b); } + } else { - if (geometry.boundingBox === null) { + + if ( geometry.boundingBox === null ) { + geometry.computeBoundingBox(); + } - _box$3.copy(geometry.boundingBox); + _box$3.copy( geometry.boundingBox ); + _box$3.applyMatrix4( object.matrixWorld ); - _box$3.applyMatrix4(object.matrixWorld); + this.union( _box$3 ); - this.union(_box$3); } + } const children = object.children; - for (let i = 0, l = children.length; i < l; i++) { - this.expandByObject(children[i], precise); + 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; + 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; + 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) { + 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)); + + 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) { + 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; + 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) { + 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 ); - return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius; } - intersectsPlane(plane) { + 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; - if (plane.normal.x > 0) { + if ( plane.normal.x > 0 ) { + min = plane.normal.x * this.min.x; max = plane.normal.x * this.max.x; + } else { + min = plane.normal.x * this.max.x; max = plane.normal.x * this.min.x; + } - if (plane.normal.y > 0) { + if ( plane.normal.y > 0 ) { + min += plane.normal.y * this.min.y; max += plane.normal.y * this.max.y; + } else { + min += plane.normal.y * this.max.y; max += plane.normal.y * this.min.y; + } - if (plane.normal.z > 0) { + if ( plane.normal.z > 0 ) { + min += plane.normal.z * this.min.z; max += plane.normal.z * this.max.z; + } else { + min += plane.normal.z * this.max.z; max += plane.normal.z * this.min.z; - } - - return min <= -plane.constant && max >= -plane.constant; - } - - intersectsTriangle(triangle) { - if (this.isEmpty()) { - return false; - } // compute box center and extents + } - this.getCenter(_center); + return ( min <= - plane.constant && max >= - plane.constant ); - _extents.subVectors(this.max, _center); // translate triangle to aabb origin + } + intersectsTriangle( triangle ) { - _v0$2.subVectors(triangle.a, _center); + if ( this.isEmpty() ) { - _v1$7.subVectors(triangle.b, _center); + return false; - _v2$3.subVectors(triangle.c, _center); // compute edge vectors for triangle + } + // compute box center and extents + this.getCenter( _center ); + _extents.subVectors( this.max, _center ); - _f0.subVectors(_v1$7, _v0$2); + // translate triangle to aabb origin + _v0$2.subVectors( triangle.a, _center ); + _v1$7.subVectors( triangle.b, _center ); + _v2$4.subVectors( triangle.c, _center ); - _f1.subVectors(_v2$3, _v1$7); + // compute edge vectors for triangle + _f0.subVectors( _v1$7, _v0$2 ); + _f1.subVectors( _v2$4, _v1$7 ); + _f2.subVectors( _v0$2, _v2$4 ); - _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$4, _extents ) ) { - - 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)) { return false; - } // test 3 face normals from the aabb + } - axes = [1, 0, 0, 0, 1, 0, 0, 0, 1]; + // 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$4, _extents ) ) { - if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) { return false; - } // finally testing the face normal of the triangle - // use already existing triangle edge vectors here + } - _triangleNormal.crossVectors(_f0, _f1); + // 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 ]; - 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); + clampPoint( point, target ) { - return clampedPoint.sub(point).length(); - } + return target.copy( point ).clamp( this.min, this.max ); - 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. + distanceToPoint( point ) { - if (this.isEmpty()) this.makeEmpty(); - return this; - } + const clampedPoint = _vector$b.copy( point ).clamp( this.min, this.max ); + + return clampedPoint.sub( point ).length(); - 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 + getBoundingSphere( target ) { - _points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix); // 000 + this.getCenter( target.center ); + target.radius = this.getSize( _vector$b ).length() * 0.5; - _points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix); // 001 + return target; + } - _points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix); // 010 + intersect( box ) { + this.min.max( box.min ); + this.max.min( box.max ); - _points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix); // 011 + // 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; - _points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix); // 100 + } + union( box ) { - _points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix); // 101 + this.min.min( box.min ); + this.max.max( box.max ); + return this; - _points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix); // 110 + } + applyMatrix4( matrix ) { - _points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix); // 111 + // 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 + _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; - } + this.setFromPoints( _points ); - 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()]; + translate( offset ) { -const _vector$b = /*@__PURE__*/new Vector3(); + this.min.add( offset ); + this.max.add( offset ); -const _box$3 = /*@__PURE__*/new Box3(); // triangle centered vertices + return this; + } -const _v0$2 = /*@__PURE__*/new Vector3(); + equals( box ) { -const _v1$7 = /*@__PURE__*/new Vector3(); + return box.min.equals( this.min ) && box.max.equals( this.max ); -const _v2$3 = /*@__PURE__*/new Vector3(); // triangle edge vectors + } +} -const _f0 = /*@__PURE__*/new Vector3(); +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 _f1 = /*@__PURE__*/new Vector3(); +const _vector$b = /*@__PURE__*/ new Vector3(); -const _f2 = /*@__PURE__*/new Vector3(); +const _box$3 = /*@__PURE__*/ new Box3(); -const _center = /*@__PURE__*/new Vector3(); +// triangle centered vertices -const _extents = /*@__PURE__*/new Vector3(); +const _v0$2 = /*@__PURE__*/ new Vector3(); +const _v1$7 = /*@__PURE__*/ new Vector3(); +const _v2$4 = /*@__PURE__*/ new Vector3(); -const _triangleNormal = /*@__PURE__*/new Vector3(); +// triangle edge vectors -const _testAxis = /*@__PURE__*/new Vector3(); +const _f0 = /*@__PURE__*/ new Vector3(); +const _f1 = /*@__PURE__*/ new Vector3(); +const _f2 = /*@__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 _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 ) { - 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 + for ( let i = 0, j = axes.length - 3; i <= j; i += 3 ) { - 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 + _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 + if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > 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 _box$2 = /*@__PURE__*/ new Box3(); +const _v1$6 = /*@__PURE__*/ new Vector3(); +const _v2$3 = /*@__PURE__*/ new Vector3(); -const _toFarthestPoint = /*@__PURE__*/new Vector3(); +class Sphere { -const _toPoint = /*@__PURE__*/new Vector3(); + constructor( center = new Vector3(), radius = - 1 ) { -class Sphere { - constructor(center = new Vector3(), radius = -1) { this.center = center; this.radius = radius; + } - set(center, radius) { - this.center.copy(center); + set( center, radius ) { + + this.center.copy( center ); this.radius = radius; + return this; + } - setFromPoints(points, optionalCenter) { + setFromPoints( points, optionalCenter ) { + const center = this.center; - if (optionalCenter !== undefined) { - center.copy(optionalCenter); + if ( optionalCenter !== undefined ) { + + center.copy( optionalCenter ); + } else { - _box$2.setFromPoints(points).getCenter(center); + + _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])); + for ( let i = 0, il = points.length; i < il; i ++ ) { + + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); + } - this.radius = Math.sqrt(maxRadiusSq); + this.radius = Math.sqrt( maxRadiusSq ); + return this; + } - copy(sphere) { - this.center.copy(sphere.center); + copy( sphere ) { + + this.center.copy( sphere.center ); this.radius = sphere.radius; + return this; + } isEmpty() { - return this.radius < 0; + + return ( this.radius < 0 ); + } makeEmpty() { - this.center.set(0, 0, 0); - this.radius = -1; + + this.center.set( 0, 0, 0 ); + this.radius = - 1; + return this; + } - containsPoint(point) { - return point.distanceToSquared(this.center) <= this.radius * this.radius; + containsPoint( point ) { + + return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); + } - distanceToPoint(point) { - return point.distanceTo(this.center) - this.radius; + distanceToPoint( point ) { + + return ( point.distanceTo( this.center ) - this.radius ); + } - intersectsSphere(sphere) { + intersectsSphere( sphere ) { + const radiusSum = this.radius + sphere.radius; - return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum; + + return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); + } - intersectsBox(box) { - return box.intersectsSphere(this); + intersectsBox( box ) { + + return box.intersectsSphere( this ); + } - intersectsPlane(plane) { - return Math.abs(plane.distanceToPoint(this.center)) <= this.radius; + intersectsPlane( plane ) { + + return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; + } - clampPoint(point, target) { - const deltaLengthSq = this.center.distanceToSquared(point); - target.copy(point); + 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 ); - 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()) { + 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); + target.set( this.center, this.center ); + target.expandByScalar( this.radius ); + return target; + } - applyMatrix4(matrix) { - this.center.applyMatrix4(matrix); + applyMatrix4( matrix ) { + + this.center.applyMatrix4( matrix ); this.radius = this.radius * matrix.getMaxScaleOnAxis(); + return this; + } - translate(offset) { - this.center.add(offset); + 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); + expandByPoint( point ) { + + 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 ) ) { + + // calculate the minimal sphere - const lengthSq = _toPoint.lengthSq(); + const length = Math.sqrt( 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. + const delta = ( length - this.radius ) * 0.5; + + this.center.addScaledVector( _v1$6, delta / length ); + + this.radius += delta; - this.center.add(_toPoint.multiplyScalar(missingRadiusHalf / length)); - this.radius += missingRadiusHalf; } 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 (this.center.equals(sphere.center) === true) { - _toFarthestPoint.set(0, 0, 1).multiplyScalar(sphere.radius); + union( sphere ) { + + if ( sphere.isEmpty() ) { + + return this; + + } + + if ( this.isEmpty() ) { + + this.copy( sphere ); + + 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$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); - } + equals( sphere ) { -} + return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); -const _vector$a = /*@__PURE__*/new Vector3(); + } -const _segCenter = /*@__PURE__*/new Vector3(); + clone() { -const _segDir = /*@__PURE__*/new Vector3(); + return new this.constructor().copy( this ); -const _diff = /*@__PURE__*/new Vector3(); + } -const _edge1 = /*@__PURE__*/new Vector3(); +} -const _edge2 = /*@__PURE__*/new Vector3(); +const _vector$a = /*@__PURE__*/ new Vector3(); +const _segCenter = /*@__PURE__*/ new Vector3(); +const _segDir = /*@__PURE__*/ new Vector3(); +const _diff = /*@__PURE__*/ new Vector3(); -const _normal$1 = /*@__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)) { + + 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); + 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); + 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); + at( t, target ) { + + return target.copy( this.direction ).multiplyScalar( t ).add( this.origin ); + } - lookAt(v) { - this.direction.copy(v).sub(this.origin).normalize(); + lookAt( v ) { + + this.direction.copy( v ).sub( this.origin ).normalize(); + return this; + } - recast(t) { - this.origin.copy(this.at(t, _vector$a)); + 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); + closestPointToPoint( point, target ) { + + target.subVectors( point, this.origin ); + + const directionDistance = target.dot( this.direction ); + + if ( directionDistance < 0 ) { + + return target.copy( this.origin ); - if (directionDistance < 0) { - return target.copy(this.origin); } - return target.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); + return target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); + } - distanceToPoint(point) { - return Math.sqrt(this.distanceSqToPoint(point)); + 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 + distanceSqToPoint( point ) { + + const directionDistance = _vector$a.subVectors( point, this.origin ).dot( this.direction ); + + // point behind the ray + + if ( directionDistance < 0 ) { + return this.origin.distanceToSquared( point ); - if (directionDistance < 0) { - return this.origin.distanceToSquared(point); } - _vector$a.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); + _vector$a.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); + + return _vector$a.distanceToSquared( point ); - return _vector$a.distanceToSquared(point); } - distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) { + 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 // defined by v0 and v1 // It can also set two optional targets : // - The closest point on the ray // - The closest point on the segment - _segCenter.copy(v0).add(v1).multiplyScalar(0.5); - _segDir.copy(v1).sub(v0).normalize(); + _segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); + _segDir.copy( v1 ).sub( v0 ).normalize(); + _diff.copy( this.origin ).sub( _segCenter ); - _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; - const segExtent = v0.distanceTo(v1) * 0.5; - const a01 = -this.direction.dot(_segDir); + if ( det > 0 ) { - 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) { + 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; + 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; + 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; + + s1 = - segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + } + } else { - if (s1 <= -extDet) { + + 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) { + + 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; + 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; + + s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); + s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + } + } + } else { + // Ray and segment are parallel. - s1 = a01 > 0 ? -segExtent : segExtent; - s0 = Math.max(0, -(a01 * s1 + b0)); - sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; + + 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 ( optionalPointOnRay ) { + + optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin ); + } - if (optionalPointOnSegment) { - optionalPointOnSegment.copy(_segDir).multiplyScalar(s1).add(_segCenter); + 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); + intersectSphere( sphere, target ) { - const d2 = _vector$a.dot(_vector$a) - tca * tca; + _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 t0 = tca - thc; // t1 = second intersect point - exit point on back of sphere + if ( d2 > radius2 ) return null; + + const thc = Math.sqrt( radius2 - d2 ); + + // t0 = first intersect point - entrance on front of sphere + const t0 = tca - thc; + + // t1 = second intersect point - exit point on back of sphere + const t1 = tca + thc; - const t1 = tca + thc; // test to see if both t0 and t1 are behind the ray - if so, return null + // test to see if both t0 and t1 are behind the ray - if so, return null + if ( t0 < 0 && t1 < 0 ) return null; - if (t0 < 0 && t1 < 0) return null; // test to see if t0 is behind the ray: + // 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 ); - return this.at(t0, target); } - intersectsSphere(sphere) { - return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius; + intersectsSphere( sphere ) { + + return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius ); + } - distanceToPlane(plane) { - const denominator = plane.normal.dot(this.direction); + distanceToPlane( plane ) { + + const denominator = plane.normal.dot( this.direction ); + + if ( denominator === 0 ) { - if (denominator === 0) { // line is coplanar, return origin - if (plane.distanceToPoint(this.origin) === 0) { + 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; // Return if the ray never intersects the plane + const t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; + + // Return if the ray never intersects the plane return t >= 0 ? t : null; + } - intersectPlane(plane, target) { - const t = this.distanceToPlane(plane); + intersectPlane( plane, target ) { + + const t = this.distanceToPlane( plane ); + + if ( t === null ) { - if (t === null) { return null; + } - return this.at(t, target); + return this.at( t, target ); + } - intersectsPlane(plane) { + intersectsPlane( plane ) { + // check if the ray lies on the plane first - const distToPoint = plane.distanceToPoint(this.origin); - if (distToPoint === 0) { + const distToPoint = plane.distanceToPoint( this.origin ); + + if ( distToPoint === 0 ) { + return true; + } - const denominator = plane.normal.dot(this.direction); + const denominator = plane.normal.dot( this.direction ); + + if ( denominator * distToPoint < 0 ) { - 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) { + 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; + if ( invdirx >= 0 ) { + + tmin = ( box.min.x - origin.x ) * invdirx; + tmax = ( box.max.x - origin.x ) * invdirx; + } else { - tmin = (box.max.x - origin.x) * invdirx; - tmax = (box.min.x - origin.x) * invdirx; + + 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; + if ( invdiry >= 0 ) { + + tymin = ( box.min.y - origin.y ) * invdiry; + tymax = ( box.max.y - origin.y ) * invdiry; + } else { - tymin = (box.max.y - origin.y) * invdiry; - tymax = (box.min.y - origin.y) * invdiry; + + 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 ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; + + if ( tymin > tmin || isNaN( tmin ) ) tmin = tymin; + + if ( tymax < tmax || isNaN( tmax ) ) tmax = tymax; + + if ( invdirz >= 0 ) { - if (tymin > tmin || tmin !== tmin) tmin = tymin; - if (tymax < tmax || tmax !== tmax) tmax = tymax; + tzmin = ( box.min.z - origin.z ) * invdirz; + tzmax = ( box.max.z - origin.z ) * invdirz; - if (invdirz >= 0) { - tzmin = (box.min.z - origin.z) * invdirz; - tzmax = (box.max.z - origin.z) * invdirz; } else { - tzmin = (box.max.z - origin.z) * invdirz; - tzmax = (box.min.z - origin.z) * invdirz; + + 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 ( ( 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 ( tmax < 0 ) return null; + + return this.at( tmin >= 0 ? tmin : tmax, target ); - if (tmax < 0) return null; - return this.at(tmin >= 0 ? tmin : tmax, target); } - intersectsBox(box) { - return this.intersectBox(box, _vector$a) !== null; + intersectsBox( box ) { + + return this.intersectBox( box, _vector$a ) !== null; + } - intersectTriangle(a, b, c, backfaceCulling, target) { + 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); - _edge2.subVectors(c, 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); + // |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; + if ( DdN > 0 ) { + + if ( backfaceCulling ) return null; sign = 1; - } else if (DdN < 0) { - sign = -1; - DdN = -DdN; + + } else if ( DdN < 0 ) { + + sign = - 1; + DdN = - DdN; + } else { + return null; + } - _diff.subVectors(this.origin, a); + _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 ) { - if (DdQxE2 < 0) { return null; + } - const DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff)); // b2 < 0, no intersection + const DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) ); + + // b2 < 0, no intersection + if ( DdE1xQ < 0 ) { - if (DdE1xQ < 0) { return null; - } // b1+b2 > 1, no intersection + } + + // b1+b2 > 1, no intersection + if ( DdQxE2 + DdE1xQ > DdN ) { - 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 ) { - if (QdN < 0) { return null; - } // Ray intersects triangle. + } + + // Ray intersects triangle. + return this.at( QdN / DdN, target ); - return this.at(QdN / DdN, target); } - applyMatrix4(matrix4) { - this.origin.applyMatrix4(matrix4); - this.direction.transformDirection(matrix4); + 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); + equals( ray ) { + + return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); + } clone() { - return new this.constructor().copy(this); + + return new this.constructor().copy( this ); + } } class Matrix4 { + constructor() { - this.isMatrix4 = true; - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; - if (arguments.length > 0) { - console.error('THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.'); - } + 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) { + set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { + const te = this.elements; - te[0] = n11; - te[4] = n12; - te[8] = n13; - te[12] = n14; - te[1] = n21; - te[5] = n22; - te[9] = n23; - te[13] = n24; - te[2] = n31; - te[6] = n32; - te[10] = n33; - te[14] = n34; - te[3] = n41; - te[7] = n42; - te[11] = n43; - te[15] = n44; + + te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; + te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; + te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; + te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; + return this; + } identity() { - this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + + 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); + + return new Matrix4().fromArray( this.elements ); + } - copy(m) { + copy( m ) { + const te = this.elements; const me = m.elements; - te[0] = me[0]; - te[1] = me[1]; - te[2] = me[2]; - te[3] = me[3]; - te[4] = me[4]; - te[5] = me[5]; - te[6] = me[6]; - te[7] = me[7]; - te[8] = me[8]; - te[9] = me[9]; - te[10] = me[10]; - te[11] = me[11]; - te[12] = me[12]; - te[13] = me[13]; - te[14] = me[14]; - te[15] = me[15]; - return this; - } - - copyPosition(m) { - const te = this.elements, - me = m.elements; - te[12] = me[12]; - te[13] = me[13]; - te[14] = me[14]; + + te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; + te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; + te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; + te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; + + return this; + + } + + copyPosition( m ) { + + const te = this.elements, me = m.elements; + + te[ 12 ] = me[ 12 ]; + te[ 13 ] = me[ 13 ]; + te[ 14 ] = me[ 14 ]; + return this; + } - setFromMatrix3(m) { + 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); + + 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); + 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); + 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) { + 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 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(); - const scaleY = 1 / _v1$5.setFromMatrixColumn(m, 1).length(); + te[ 0 ] = me[ 0 ] * scaleX; + te[ 1 ] = me[ 1 ] * scaleX; + te[ 2 ] = me[ 2 ] * scaleX; + te[ 3 ] = 0; - const scaleZ = 1 / _v1$5.setFromMatrixColumn(m, 2).length(); + te[ 4 ] = me[ 4 ] * scaleY; + te[ 5 ] = me[ 5 ] * scaleY; + te[ 6 ] = me[ 6 ] * scaleY; + te[ 7 ] = 0; + + te[ 8 ] = me[ 8 ] * scaleZ; + te[ 9 ] = me[ 9 ] * scaleZ; + te[ 10 ] = me[ 10 ] * scaleZ; + te[ 11 ] = 0; + + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; - te[0] = me[0] * scaleX; - te[1] = me[1] * scaleX; - te[2] = me[2] * scaleX; - te[3] = 0; - te[4] = me[4] * scaleY; - te[5] = me[5] * scaleY; - te[6] = me[6] * scaleY; - te[7] = 0; - te[8] = me[8] * scaleZ; - te[9] = me[9] * scaleZ; - te[10] = me[10] * scaleZ; - te[11] = 0; - te[12] = 0; - te[13] = 0; - te[14] = 0; - te[15] = 1; return this; + } - makeRotationFromEuler(euler) { - if (!(euler && euler.isEuler)) { - console.error('THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.'); - } + makeRotationFromEuler( euler ) { const te = this.elements; - const x = euler.x, - y = euler.y, - z = euler.z; - const a = Math.cos(x), - b = Math.sin(x); - const c = Math.cos(y), - d = Math.sin(y); - const e = Math.cos(z), - f = Math.sin(z); - - if (euler.order === 'XYZ') { - const ae = a * e, - af = a * f, - be = b * e, - bf = b * f; - te[0] = c * e; - te[4] = -c * f; - te[8] = d; - te[1] = af + be * d; - te[5] = ae - bf * d; - te[9] = -b * c; - te[2] = bf - ae * d; - te[6] = be + af * d; - te[10] = a * c; - } else if (euler.order === 'YXZ') { - const ce = c * e, - cf = c * f, - de = d * e, - df = d * f; - te[0] = ce + df * b; - te[4] = de * b - cf; - te[8] = a * d; - te[1] = a * f; - te[5] = a * e; - te[9] = -b; - te[2] = cf * b - de; - te[6] = df + ce * b; - te[10] = a * c; - } else if (euler.order === 'ZXY') { - const ce = c * e, - cf = c * f, - de = d * e, - df = d * f; - te[0] = ce - df * b; - te[4] = -a * f; - te[8] = de + cf * b; - te[1] = cf + de * b; - te[5] = a * e; - te[9] = df - ce * b; - te[2] = -a * d; - te[6] = b; - te[10] = a * c; - } else if (euler.order === 'ZYX') { - const ae = a * e, - af = a * f, - be = b * e, - bf = b * f; - te[0] = c * e; - te[4] = be * d - af; - te[8] = ae * d + bf; - te[1] = c * f; - te[5] = bf * d + ae; - te[9] = af * d - be; - te[2] = -d; - te[6] = b * c; - te[10] = a * c; - } else if (euler.order === 'YZX') { - const ac = a * c, - ad = a * d, - bc = b * c, - bd = b * d; - te[0] = c * e; - te[4] = bd - ac * f; - te[8] = bc * f + ad; - te[1] = f; - te[5] = a * e; - te[9] = -b * e; - te[2] = -d * e; - te[6] = ad * f + bc; - te[10] = ac - bd * f; - } else if (euler.order === 'XZY') { - const ac = a * c, - ad = a * d, - bc = b * c, - bd = b * d; - te[0] = c * e; - te[4] = -f; - te[8] = d * e; - te[1] = ac * f + bd; - te[5] = a * e; - te[9] = ad * f - bc; - te[2] = bc * f - ad; - te[6] = b * e; - te[10] = bd * f + ac; - } // bottom row - - - te[3] = 0; - te[7] = 0; - te[11] = 0; // last column - - te[12] = 0; - te[13] = 0; - te[14] = 0; - te[15] = 1; - return this; - } - - makeRotationFromQuaternion(q) { - return this.compose(_zero, q, _one); - } - - lookAt(eye, target, up) { + + const x = euler.x, y = euler.y, z = euler.z; + const a = Math.cos( x ), b = Math.sin( x ); + const c = Math.cos( y ), d = Math.sin( y ); + const e = Math.cos( z ), f = Math.sin( z ); + + if ( euler.order === 'XYZ' ) { + + const ae = a * e, af = a * f, be = b * e, bf = b * f; + + te[ 0 ] = c * e; + te[ 4 ] = - c * f; + te[ 8 ] = d; + + te[ 1 ] = af + be * d; + te[ 5 ] = ae - bf * d; + te[ 9 ] = - b * c; + + te[ 2 ] = bf - ae * d; + te[ 6 ] = be + af * d; + te[ 10 ] = a * c; + + } else if ( euler.order === 'YXZ' ) { + + const ce = c * e, cf = c * f, de = d * e, df = d * f; + + te[ 0 ] = ce + df * b; + te[ 4 ] = de * b - cf; + te[ 8 ] = a * d; + + te[ 1 ] = a * f; + te[ 5 ] = a * e; + te[ 9 ] = - b; + + te[ 2 ] = cf * b - de; + te[ 6 ] = df + ce * b; + te[ 10 ] = a * c; + + } else if ( euler.order === 'ZXY' ) { + + const ce = c * e, cf = c * f, de = d * e, df = d * f; + + te[ 0 ] = ce - df * b; + te[ 4 ] = - a * f; + te[ 8 ] = de + cf * b; + + te[ 1 ] = cf + de * b; + te[ 5 ] = a * e; + te[ 9 ] = df - ce * b; + + te[ 2 ] = - a * d; + te[ 6 ] = b; + te[ 10 ] = a * c; + + } else if ( euler.order === 'ZYX' ) { + + const ae = a * e, af = a * f, be = b * e, bf = b * f; + + te[ 0 ] = c * e; + te[ 4 ] = be * d - af; + te[ 8 ] = ae * d + bf; + + te[ 1 ] = c * f; + te[ 5 ] = bf * d + ae; + te[ 9 ] = af * d - be; + + te[ 2 ] = - d; + te[ 6 ] = b * c; + te[ 10 ] = a * c; + + } else if ( euler.order === 'YZX' ) { + + const ac = a * c, ad = a * d, bc = b * c, bd = b * d; + + te[ 0 ] = c * e; + te[ 4 ] = bd - ac * f; + te[ 8 ] = bc * f + ad; + + te[ 1 ] = f; + te[ 5 ] = a * e; + te[ 9 ] = - b * e; + + te[ 2 ] = - d * e; + te[ 6 ] = ad * f + bc; + te[ 10 ] = ac - bd * f; + + } else if ( euler.order === 'XZY' ) { + + const ac = a * c, ad = a * d, bc = b * c, bd = b * d; + + te[ 0 ] = c * e; + te[ 4 ] = - f; + te[ 8 ] = d * e; + + te[ 1 ] = ac * f + bd; + te[ 5 ] = a * e; + te[ 9 ] = ad * f - bc; + + te[ 2 ] = bc * f - ad; + te[ 6 ] = b * e; + te[ 10 ] = bd * f + ac; + + } + + // bottom row + te[ 3 ] = 0; + te[ 7 ] = 0; + te[ 11 ] = 0; + + // last column + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; + + return this; + + } + + makeRotationFromQuaternion( q ) { + + return this.compose( _zero, q, _one ); + + } + + lookAt( eye, target, up ) { + const te = this.elements; - _z.subVectors(eye, target); + _z.subVectors( eye, target ); + + if ( _z.lengthSq() === 0 ) { - if (_z.lengthSq() === 0) { // eye and target are in the same position + _z.z = 1; + } _z.normalize(); + _x.crossVectors( up, _z ); - _x.crossVectors(up, _z); + if ( _x.lengthSq() === 0 ) { - if (_x.lengthSq() === 0) { // up and z are parallel - if (Math.abs(up.z) === 1) { + + if ( Math.abs( up.z ) === 1 ) { + _z.x += 0.0001; + } else { + _z.z += 0.0001; + } _z.normalize(); + _x.crossVectors( up, _z ); - _x.crossVectors(up, _z); } _x.normalize(); + _y.crossVectors( _z, _x ); - _y.crossVectors(_z, _x); + te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x; + te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y; + te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z; - te[0] = _x.x; - te[4] = _y.x; - te[8] = _z.x; - te[1] = _x.y; - te[5] = _y.y; - te[9] = _z.y; - te[2] = _x.z; - te[6] = _y.z; - te[10] = _z.z; return this; + } - multiply(m, n) { - if (n !== undefined) { - console.warn('THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.'); - return this.multiplyMatrices(m, n); - } + multiply( m ) { + + return this.multiplyMatrices( this, m ); - return this.multiplyMatrices(this, m); } - premultiply(m) { - return this.multiplyMatrices(m, this); + premultiply( m ) { + + return this.multiplyMatrices( m, this ); + } - multiplyMatrices(a, b) { + multiplyMatrices( a, b ) { + const ae = a.elements; const be = b.elements; const te = this.elements; - const a11 = ae[0], - a12 = ae[4], - a13 = ae[8], - a14 = ae[12]; - const a21 = ae[1], - a22 = ae[5], - a23 = ae[9], - a24 = ae[13]; - const a31 = ae[2], - a32 = ae[6], - a33 = ae[10], - a34 = ae[14]; - const a41 = ae[3], - a42 = ae[7], - a43 = ae[11], - a44 = ae[15]; - const b11 = be[0], - b12 = be[4], - b13 = be[8], - b14 = be[12]; - const b21 = be[1], - b22 = be[5], - b23 = be[9], - b24 = be[13]; - const b31 = be[2], - b32 = be[6], - b33 = be[10], - b34 = be[14]; - const b41 = be[3], - b42 = be[7], - b43 = be[11], - b44 = be[15]; - te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; - te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; - te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; - te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; - te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; - te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; - te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; - te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; - te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; - te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; - te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; - te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; - te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; - te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; - te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; - te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; - return this; - } - - multiplyScalar(s) { + + const a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; + const a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; + const a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; + const a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; + + const b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; + const b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; + const b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; + const b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; + + te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; + te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; + te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; + te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; + + te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; + te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; + te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; + te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; + + te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; + te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; + te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; + te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; + + te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; + te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; + te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; + te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; + + return this; + + } + + multiplyScalar( s ) { + const te = this.elements; - te[0] *= s; - te[4] *= s; - te[8] *= s; - te[12] *= s; - te[1] *= s; - te[5] *= s; - te[9] *= s; - te[13] *= s; - te[2] *= s; - te[6] *= s; - te[10] *= s; - te[14] *= s; - te[3] *= s; - te[7] *= s; - te[11] *= s; - te[15] *= s; + + te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; + te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; + te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; + te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; + return this; + } determinant() { + const te = this.elements; - const n11 = te[0], - n12 = te[4], - n13 = te[8], - n14 = te[12]; - const n21 = te[1], - n22 = te[5], - n23 = te[9], - n24 = te[13]; - const n31 = te[2], - n32 = te[6], - n33 = te[10], - n34 = te[14]; - const n41 = te[3], - n42 = te[7], - n43 = te[11], - n44 = te[15]; //TODO: make this more efficient + + const n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; + const n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; + const n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; + const n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; + + //TODO: make this more efficient //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) - return n41 * (+n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34) + n42 * (+n11 * n23 * n34 - n11 * n24 * n33 + n14 * n21 * n33 - n13 * n21 * n34 + n13 * n24 * n31 - n14 * n23 * n31) + n43 * (+n11 * n24 * n32 - n11 * n22 * n34 - n14 * n21 * n32 + n12 * n21 * n34 + n14 * n22 * n31 - n12 * n24 * n31) + n44 * (-n13 * n22 * n31 - n11 * n23 * n32 + n11 * n22 * n33 + n13 * n21 * n32 - n12 * n21 * n33 + n12 * n23 * n31); + return ( + n41 * ( + + n14 * n23 * n32 + - n13 * n24 * n32 + - n14 * n22 * n33 + + n12 * n24 * n33 + + n13 * n22 * n34 + - n12 * n23 * n34 + ) + + n42 * ( + + n11 * n23 * n34 + - n11 * n24 * n33 + + n14 * n21 * n33 + - n13 * n21 * n34 + + n13 * n24 * n31 + - n14 * n23 * n31 + ) + + n43 * ( + + n11 * n24 * n32 + - n11 * n22 * n34 + - n14 * n21 * n32 + + n12 * n21 * n34 + + n14 * n22 * n31 + - n12 * n24 * n31 + ) + + n44 * ( + - n13 * n22 * n31 + - n11 * n23 * n32 + + n11 * n22 * n33 + + n13 * n21 * n32 + - n12 * n21 * n33 + + n12 * n23 * n31 + ) + + ); + } transpose() { + const te = this.elements; let tmp; - tmp = te[1]; - te[1] = te[4]; - te[4] = tmp; - tmp = te[2]; - te[2] = te[8]; - te[8] = tmp; - tmp = te[6]; - te[6] = te[9]; - te[9] = tmp; - tmp = te[3]; - te[3] = te[12]; - te[12] = tmp; - tmp = te[7]; - te[7] = te[13]; - te[13] = tmp; - tmp = te[11]; - te[11] = te[14]; - te[14] = tmp; - return this; - } - - setPosition(x, y, z) { + + tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; + tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; + tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; + + tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; + tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; + tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; + + return this; + + } + + setPosition( x, y, z ) { + const te = this.elements; - if (x.isVector3) { - te[12] = x.x; - te[13] = x.y; - te[14] = x.z; + if ( x.isVector3 ) { + + te[ 12 ] = x.x; + te[ 13 ] = x.y; + te[ 14 ] = x.z; + } else { - te[12] = x; - te[13] = y; - te[14] = z; + + te[ 12 ] = x; + te[ 13 ] = y; + te[ 14 ] = z; + } return this; + } invert() { + // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm const te = this.elements, - n11 = te[0], - n21 = te[1], - n31 = te[2], - n41 = te[3], - n12 = te[4], - n22 = te[5], - n32 = te[6], - n42 = te[7], - n13 = te[8], - n23 = te[9], - n33 = te[10], - n43 = te[11], - n14 = te[12], - n24 = te[13], - n34 = te[14], - n44 = te[15], - t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, - t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, - t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, - t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; + + 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); + + if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + const detInv = 1 / det; - te[0] = t11 * detInv; - te[1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * detInv; - te[2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * detInv; - te[3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * detInv; - te[4] = t12 * detInv; - te[5] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * detInv; - te[6] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * detInv; - te[7] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * detInv; - te[8] = t13 * detInv; - te[9] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * detInv; - te[10] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * detInv; - te[11] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * detInv; - te[12] = t14 * detInv; - te[13] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * detInv; - te[14] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * detInv; - te[15] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv; - return this; - } - - scale(v) { + + te[ 0 ] = t11 * detInv; + te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv; + te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv; + te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv; + + te[ 4 ] = t12 * detInv; + te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv; + te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv; + te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv; + + te[ 8 ] = t13 * detInv; + te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv; + te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv; + te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv; + + te[ 12 ] = t14 * detInv; + te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv; + te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv; + te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv; + + return this; + + } + + scale( v ) { + const te = this.elements; - const x = v.x, - y = v.y, - z = v.z; - te[0] *= x; - te[4] *= y; - te[8] *= z; - te[1] *= x; - te[5] *= y; - te[9] *= z; - te[2] *= x; - te[6] *= y; - te[10] *= z; - te[3] *= x; - te[7] *= y; - te[11] *= z; + const x = v.x, y = v.y, z = v.z; + + te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; + te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; + te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; + te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; + return this; + } getMaxScaleOnAxis() { + const te = this.elements; - const scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2]; - const scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6]; - const scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10]; - return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq)); + + const scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; + const scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; + const scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; + + return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); + } - makeTranslation(x, y, z) { - this.set(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1); + makeTranslation( x, y, z ) { + + this.set( + + 1, 0, 0, x, + 0, 1, 0, y, + 0, 0, 1, z, + 0, 0, 0, 1 + + ); + return this; + } - makeRotationX(theta) { - const c = Math.cos(theta), - s = Math.sin(theta); - this.set(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1); + makeRotationX( theta ) { + + const c = Math.cos( theta ), s = Math.sin( theta ); + + this.set( + + 1, 0, 0, 0, + 0, c, - s, 0, + 0, s, c, 0, + 0, 0, 0, 1 + + ); + return this; + } - makeRotationY(theta) { - const c = Math.cos(theta), - s = Math.sin(theta); - this.set(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1); + makeRotationY( theta ) { + + const c = Math.cos( theta ), s = Math.sin( theta ); + + this.set( + + c, 0, s, 0, + 0, 1, 0, 0, + - s, 0, c, 0, + 0, 0, 0, 1 + + ); + return this; + } - makeRotationZ(theta) { - const c = Math.cos(theta), - s = Math.sin(theta); - this.set(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + makeRotationZ( theta ) { + + const c = Math.cos( theta ), s = Math.sin( theta ); + + this.set( + + c, - s, 0, 0, + s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + + ); + return this; + } - makeRotationAxis(axis, angle) { + makeRotationAxis( axis, angle ) { + // Based on http://www.gamedev.net/reference/articles/article1199.asp - const c = Math.cos(angle); - const s = Math.sin(angle); + + const c = Math.cos( angle ); + const s = Math.sin( angle ); const t = 1 - c; - const x = axis.x, - y = axis.y, - z = axis.z; - const tx = t * x, - ty = t * y; - this.set(tx * x + c, tx * y - s * z, tx * z + s * y, 0, tx * y + s * z, ty * y + c, ty * z - s * x, 0, tx * z - s * y, ty * z + s * x, t * z * z + c, 0, 0, 0, 0, 1); + const x = axis.x, y = axis.y, z = axis.z; + const tx = t * x, ty = t * y; + + this.set( + + tx * x + c, tx * y - s * z, tx * z + s * y, 0, + tx * y + s * z, ty * y + c, ty * z - s * x, 0, + tx * z - s * y, ty * z + s * x, t * z * z + c, 0, + 0, 0, 0, 1 + + ); + return this; + } - makeScale(x, y, z) { - this.set(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1); + 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); + makeShear( xy, xz, yx, yz, zx, zy ) { + + this.set( + + 1, yx, zx, 0, + xy, 1, zy, 0, + xz, yz, 1, 0, + 0, 0, 0, 1 + + ); + return this; + } - compose(position, quaternion, scale) { - const te = this.elements; - const x = quaternion._x, - y = quaternion._y, - z = quaternion._z, - w = quaternion._w; - const x2 = x + x, - y2 = y + y, - z2 = z + z; - const xx = x * x2, - xy = x * y2, - xz = x * z2; - const yy = y * y2, - yz = y * z2, - zz = z * z2; - const wx = w * x2, - wy = w * y2, - wz = w * z2; - const sx = scale.x, - sy = scale.y, - sz = scale.z; - te[0] = (1 - (yy + zz)) * sx; - te[1] = (xy + wz) * sx; - te[2] = (xz - wy) * sx; - te[3] = 0; - te[4] = (xy - wz) * sy; - te[5] = (1 - (xx + zz)) * sy; - te[6] = (yz + wx) * sy; - te[7] = 0; - te[8] = (xz + wy) * sz; - te[9] = (yz - wx) * sz; - te[10] = (1 - (xx + yy)) * sz; - te[11] = 0; - te[12] = position.x; - te[13] = position.y; - te[14] = position.z; - te[15] = 1; - return this; - } - - decompose(position, quaternion, scale) { + compose( position, quaternion, scale ) { + const te = this.elements; - let sx = _v1$5.set(te[0], te[1], te[2]).length(); + const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; + const x2 = x + x, y2 = y + y, z2 = z + z; + const xx = x * x2, xy = x * y2, xz = x * z2; + const yy = y * y2, yz = y * z2, zz = z * z2; + const wx = w * x2, wy = w * y2, wz = w * z2; + + const sx = scale.x, sy = scale.y, sz = scale.z; + + te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; + te[ 1 ] = ( xy + wz ) * sx; + te[ 2 ] = ( xz - wy ) * sx; + te[ 3 ] = 0; + + te[ 4 ] = ( xy - wz ) * sy; + te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; + te[ 6 ] = ( yz + wx ) * sy; + te[ 7 ] = 0; - const sy = _v1$5.set(te[4], te[5], te[6]).length(); + te[ 8 ] = ( xz + wy ) * sz; + te[ 9 ] = ( yz - wx ) * sz; + te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; + te[ 11 ] = 0; - const sz = _v1$5.set(te[8], te[9], te[10]).length(); // if determine is negative, we need to invert one scale + te[ 12 ] = position.x; + te[ 13 ] = position.y; + te[ 14 ] = position.z; + te[ 15 ] = 1; + return this; + + } + + decompose( position, quaternion, scale ) { + const te = this.elements; + + let sx = _v1$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(); + + // 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 + if ( det < 0 ) sx = - sx; + + position.x = te[ 12 ]; + position.y = te[ 13 ]; + position.z = te[ 14 ]; - _m1$2.copy(this); + // scale the rotation part + _m1$2.copy( this ); const invSX = 1 / sx; const invSY = 1 / sy; const invSZ = 1 / sz; - _m1$2.elements[0] *= invSX; - _m1$2.elements[1] *= invSX; - _m1$2.elements[2] *= invSX; - _m1$2.elements[4] *= invSY; - _m1$2.elements[5] *= invSY; - _m1$2.elements[6] *= invSY; - _m1$2.elements[8] *= invSZ; - _m1$2.elements[9] *= invSZ; - _m1$2.elements[10] *= invSZ; - quaternion.setFromRotationMatrix(_m1$2); + + _m1$2.elements[ 0 ] *= invSX; + _m1$2.elements[ 1 ] *= invSX; + _m1$2.elements[ 2 ] *= invSX; + + _m1$2.elements[ 4 ] *= invSY; + _m1$2.elements[ 5 ] *= invSY; + _m1$2.elements[ 6 ] *= invSY; + + _m1$2.elements[ 8 ] *= invSZ; + _m1$2.elements[ 9 ] *= invSZ; + _m1$2.elements[ 10 ] *= invSZ; + + quaternion.setFromRotationMatrix( _m1$2 ); + scale.x = sx; scale.y = sy; scale.z = sz; + return this; + } - makePerspective(left, right, top, bottom, near, far) { - if (far === undefined) { - console.warn('THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.'); - } + makePerspective( left, right, top, bottom, near, far ) { const te = this.elements; - const x = 2 * near / (right - left); - const y = 2 * near / (top - bottom); - const a = (right + left) / (right - left); - const b = (top + bottom) / (top - bottom); - const c = -(far + near) / (far - near); - const d = -2 * far * near / (far - near); - te[0] = x; - te[4] = 0; - te[8] = a; - te[12] = 0; - te[1] = 0; - te[5] = y; - te[9] = b; - te[13] = 0; - te[2] = 0; - te[6] = 0; - te[10] = c; - te[14] = d; - te[3] = 0; - te[7] = 0; - te[11] = -1; - te[15] = 0; - return this; - } - - makeOrthographic(left, right, top, bottom, near, far) { + const x = 2 * near / ( right - left ); + const y = 2 * near / ( top - bottom ); + + const a = ( right + left ) / ( right - left ); + const b = ( top + bottom ) / ( top - bottom ); + const c = - ( far + near ) / ( far - near ); + const d = - 2 * far * near / ( far - near ); + + te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; + te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; + te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; + te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0; + + return this; + + } + + makeOrthographic( left, right, top, bottom, near, far ) { + const te = this.elements; - const w = 1.0 / (right - left); - const h = 1.0 / (top - bottom); - const p = 1.0 / (far - near); - const x = (right + left) * w; - const y = (top + bottom) * h; - const z = (far + near) * p; - te[0] = 2 * w; - te[4] = 0; - te[8] = 0; - te[12] = -x; - te[1] = 0; - te[5] = 2 * h; - te[9] = 0; - te[13] = -y; - te[2] = 0; - te[6] = 0; - te[10] = -2 * p; - te[14] = -z; - te[3] = 0; - te[7] = 0; - te[11] = 0; - te[15] = 1; - return this; - } - - equals(matrix) { + const w = 1.0 / ( right - left ); + const h = 1.0 / ( top - bottom ); + const p = 1.0 / ( far - near ); + + const x = ( right + left ) * w; + const y = ( top + bottom ) * h; + const z = ( far + near ) * p; + + te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x; + te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y; + te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z; + te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; + + return this; + + } + + equals( matrix ) { + const te = this.elements; const me = matrix.elements; - for (let i = 0; i < 16; i++) { - if (te[i] !== me[i]) return false; + 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]; + fromArray( array, offset = 0 ) { + + for ( let i = 0; i < 16; i ++ ) { + + this.elements[ i ] = array[ i + offset ]; + } return this; - } - toArray(array = [], offset = 0) { - const te = this.elements; - array[offset] = te[0]; - array[offset + 1] = te[1]; - array[offset + 2] = te[2]; - array[offset + 3] = te[3]; - array[offset + 4] = te[4]; - array[offset + 5] = te[5]; - array[offset + 6] = te[6]; - array[offset + 7] = te[7]; - array[offset + 8] = te[8]; - array[offset + 9] = te[9]; - array[offset + 10] = te[10]; - array[offset + 11] = te[11]; - array[offset + 12] = te[12]; - array[offset + 13] = te[13]; - array[offset + 14] = te[14]; - array[offset + 15] = te[15]; - return array; } -} + toArray( array = [], offset = 0 ) { + + const te = this.elements; -const _v1$5 = /*@__PURE__*/new Vector3(); + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; + array[ offset + 3 ] = te[ 3 ]; -const _m1$2 = /*@__PURE__*/new Matrix4(); + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; -const _zero = /*@__PURE__*/new Vector3(0, 0, 0); + array[ offset + 8 ] = te[ 8 ]; + array[ offset + 9 ] = te[ 9 ]; + array[ offset + 10 ] = te[ 10 ]; + array[ offset + 11 ] = te[ 11 ]; -const _one = /*@__PURE__*/new Vector3(1, 1, 1); + array[ offset + 12 ] = te[ 12 ]; + array[ offset + 13 ] = te[ 13 ]; + array[ offset + 14 ] = te[ 14 ]; + array[ offset + 15 ] = te[ 15 ]; -const _x = /*@__PURE__*/new Vector3(); + return array; -const _y = /*@__PURE__*/new Vector3(); + } -const _z = /*@__PURE__*/new Vector3(); +} -const _matrix$1 = /*@__PURE__*/new Matrix4(); +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 _quaternion$3 = /*@__PURE__*/new Quaternion(); +const _matrix$1 = /*@__PURE__*/ new Matrix4(); +const _quaternion$3 = /*@__PURE__*/ new Quaternion(); class Euler { - constructor(x = 0, y = 0, z = 0, order = Euler.DefaultOrder) { + + constructor( x = 0, y = 0, z = 0, order = Euler.DEFAULT_ORDER ) { + this.isEuler = true; + this._x = x; this._y = y; this._z = z; this._order = order; + } get x() { + return this._x; + } - set x(value) { - this._x = value; + set x( value ) { + this._x = value; this._onChangeCallback(); + } get y() { + return this._y; + } - set y(value) { - this._y = value; + set y( value ) { + this._y = value; this._onChangeCallback(); + } get z() { + return this._z; + } - set z(value) { - this._z = value; + set z( value ) { + this._z = value; this._onChangeCallback(); + } get order() { + return this._order; + } - set order(value) { - this._order = value; + set order( value ) { + this._order = value; this._onChangeCallback(); + } - set(x, y, z, order = this._order) { + set( x, y, z, order = this._order ) { + this._x = x; this._y = y; this._z = z; @@ -5621,13 +7168,17 @@ class Euler { this._onChangeCallback(); return this; + } clone() { - return new this.constructor(this._x, this._y, this._z, this._order); + + return new this.constructor( this._x, this._y, this._z, this._order ); + } - copy(euler) { + copy( euler ) { + this._x = euler._x; this._y = euler._y; this._z = euler._z; @@ -5636,272 +7187,336 @@ class Euler { this._onChangeCallback(); return this; + } - setFromRotationMatrix(m, order = this._order, update = true) { + setFromRotationMatrix( m, order = this._order, update = true ) { + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + const te = m.elements; - const m11 = te[0], - m12 = te[4], - m13 = te[8]; - const m21 = te[1], - m22 = te[5], - m23 = te[9]; - const m31 = te[2], - m32 = te[6], - m33 = te[10]; - - switch (order) { + const m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; + const m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; + const m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; + + switch ( order ) { + case 'XYZ': - this._y = Math.asin(clamp(m13, -1, 1)); - if (Math.abs(m13) < 0.9999999) { - this._x = Math.atan2(-m23, m33); - this._z = Math.atan2(-m12, m11); + this._y = Math.asin( clamp( m13, - 1, 1 ) ); + + if ( Math.abs( m13 ) < 0.9999999 ) { + + this._x = Math.atan2( - m23, m33 ); + this._z = Math.atan2( - m12, m11 ); + } else { - this._x = Math.atan2(m32, m22); + + this._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); + this._x = Math.asin( - clamp( m23, - 1, 1 ) ); + + if ( Math.abs( m23 ) < 0.9999999 ) { + + this._y = Math.atan2( m13, m33 ); + this._z = Math.atan2( m21, m22 ); + } else { - this._y = Math.atan2(-m31, m11); + + this._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); + this._x = Math.asin( clamp( m32, - 1, 1 ) ); + + if ( Math.abs( m32 ) < 0.9999999 ) { + + this._y = Math.atan2( - m31, m33 ); + this._z = Math.atan2( - m12, m22 ); + } else { + this._y = 0; - this._z = Math.atan2(m21, m11); + 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); + this._y = Math.asin( - clamp( m31, - 1, 1 ) ); + + if ( Math.abs( m31 ) < 0.9999999 ) { + + this._x = Math.atan2( m32, m33 ); + this._z = Math.atan2( m21, m11 ); + } else { + this._x = 0; - this._z = Math.atan2(-m12, m22); + 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); + this._z = Math.asin( clamp( m21, - 1, 1 ) ); + + if ( Math.abs( m21 ) < 0.9999999 ) { + + this._x = Math.atan2( - m23, m22 ); + this._y = Math.atan2( - m31, m11 ); + } else { + this._x = 0; - this._y = Math.atan2(m13, m33); + 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); + this._z = Math.asin( - clamp( m12, - 1, 1 ) ); + + if ( Math.abs( m12 ) < 0.9999999 ) { + + this._x = Math.atan2( m32, m22 ); + this._y = Math.atan2( m13, m11 ); + } else { - this._x = Math.atan2(-m23, m33); + + this._x = Math.atan2( - m23, m33 ); this._y = 0; + } break; default: - console.warn('THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order); + + console.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order ); + } this._order = order; - if (update === true) this._onChangeCallback(); + + if ( update === true ) this._onChangeCallback(); + return this; + } - setFromQuaternion(q, order, update) { - _matrix$1.makeRotationFromQuaternion(q); + setFromQuaternion( q, order, update ) { + + _matrix$1.makeRotationFromQuaternion( q ); + + return this.setFromRotationMatrix( _matrix$1, order, update ); - return this.setFromRotationMatrix(_matrix$1, order, update); } - setFromVector3(v, order = this._order) { - return this.set(v.x, v.y, v.z, order); + setFromVector3( v, order = this._order ) { + + return this.set( v.x, v.y, v.z, order ); + } - reorder(newOrder) { + reorder( newOrder ) { + // WARNING: this discards revolution information -bhouston - _quaternion$3.setFromEuler(this); - return this.setFromQuaternion(_quaternion$3, newOrder); + _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; + 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]; + fromArray( array ) { + + this._x = array[ 0 ]; + this._y = array[ 1 ]; + this._z = array[ 2 ]; + if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; this._onChangeCallback(); return this; + } - toArray(array = [], offset = 0) { - array[offset] = this._x; - array[offset + 1] = this._y; - array[offset + 2] = this._z; - array[offset + 3] = this._order; + toArray( array = [], offset = 0 ) { + + array[ offset ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._order; + return array; + } - _onChange(callback) { + _onChange( callback ) { + this._onChangeCallback = callback; + return this; + } _onChangeCallback() {} - *[Symbol.iterator]() { + *[ Symbol.iterator ]() { + yield this._x; yield this._y; yield this._z; yield this._order; - } // @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']; +Euler.DEFAULT_ORDER = 'XYZ'; class Layers { + constructor() { + this.mask = 1 | 0; + } - set(channel) { - this.mask = (1 << channel | 0) >>> 0; + set( channel ) { + + this.mask = ( 1 << channel | 0 ) >>> 0; + } - enable(channel) { + enable( channel ) { + this.mask |= 1 << channel | 0; + } enableAll() { + this.mask = 0xffffffff | 0; + } - toggle(channel) { + toggle( channel ) { + this.mask ^= 1 << channel | 0; + } - disable(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; - } + this.mask = 0; - isEnabled(channel) { - return (this.mask & (1 << channel | 0)) !== 0; } -} - -let _object3DId = 0; + test( layers ) { -const _v1$4 = /*@__PURE__*/new Vector3(); + return ( this.mask & layers.mask ) !== 0; -const _q1 = /*@__PURE__*/new Quaternion(); + } -const _m1$1 = /*@__PURE__*/new Matrix4(); + isEnabled( channel ) { -const _target = /*@__PURE__*/new Vector3(); + return ( this.mask & ( 1 << channel | 0 ) ) !== 0; -const _position$3 = /*@__PURE__*/new Vector3(); + } -const _scale$2 = /*@__PURE__*/new Vector3(); +} -const _quaternion$2 = /*@__PURE__*/new Quaternion(); +let _object3DId = 0; -const _xAxis = /*@__PURE__*/new Vector3(1, 0, 0); +const _v1$4 = /*@__PURE__*/ new Vector3(); +const _q1 = /*@__PURE__*/ new Quaternion(); +const _m1$1 = /*@__PURE__*/ new Matrix4(); +const _target = /*@__PURE__*/ new Vector3(); -const _yAxis = /*@__PURE__*/new Vector3(0, 1, 0); +const _position$3 = /*@__PURE__*/ new Vector3(); +const _scale$2 = /*@__PURE__*/ new Vector3(); +const _quaternion$2 = /*@__PURE__*/ new Quaternion(); -const _zAxis = /*@__PURE__*/new Vector3(0, 0, 1); +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' -}; +const _addedEvent = { type: 'added' }; +const _removedEvent = { type: 'removed' }; class Object3D extends EventDispatcher { + constructor() { + super(); + this.isObject3D = true; - Object.defineProperty(this, 'id', { - value: _object3DId++ - }); + + Object.defineProperty( this, 'id', { value: _object3DId ++ } ); + this.uuid = generateUUID(); + this.name = ''; this.type = 'Object3D'; + this.parent = null; this.children = []; - this.up = Object3D.DefaultUp.clone(); + + this.up = Object3D.DEFAULT_UP.clone(); + const position = new Vector3(); const rotation = new Euler(); const quaternion = new Quaternion(); - const scale = new Vector3(1, 1, 1); + const scale = new Vector3( 1, 1, 1 ); function onRotationChange() { - quaternion.setFromEuler(rotation, false); + + quaternion.setFromEuler( rotation, false ); + } function onQuaternionChange() { - rotation.setFromQuaternion(quaternion, undefined, false); - } - rotation._onChange(onRotationChange); + rotation.setFromQuaternion( quaternion, undefined, false ); + + } - quaternion._onChange(onQuaternionChange); + rotation._onChange( onRotationChange ); + quaternion._onChange( onQuaternionChange ); - Object.defineProperties(this, { + Object.defineProperties( this, { position: { configurable: true, enumerable: true, @@ -5928,370 +7543,594 @@ class Object3D extends EventDispatcher { normalMatrix: { value: new Matrix3() } - }); + } ); + this.matrix = new Matrix4(); this.matrixWorld = new Matrix4(); - this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; + + this.matrixAutoUpdate = Object3D.DEFAULT_MATRIX_AUTO_UPDATE; this.matrixWorldNeedsUpdate = false; + + this.matrixWorldAutoUpdate = Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; // checked by the renderer + this.layers = new Layers(); this.visible = true; + this.castShadow = false; this.receiveShadow = false; + this.frustumCulled = true; this.renderOrder = 0; + this.animations = []; + this.userData = {}; + } - onBeforeRender() {} + onBeforeRender( /* renderer, scene, camera, geometry, material, group */ ) {} - onAfterRender() {} + onAfterRender( /* renderer, scene, camera, geometry, material, group */ ) {} - applyMatrix4(matrix) { - if (this.matrixAutoUpdate) this.updateMatrix(); - this.matrix.premultiply(matrix); - this.matrix.decompose(this.position, this.quaternion, this.scale); - } + applyMatrix4( matrix ) { - applyQuaternion(q) { - this.quaternion.premultiply(q); - return this; - } + if ( this.matrixAutoUpdate ) this.updateMatrix(); - setRotationFromAxisAngle(axis, angle) { - // assumes axis is normalized - this.quaternion.setFromAxisAngle(axis, angle); - } + this.matrix.premultiply( matrix ); - setRotationFromEuler(euler) { - this.quaternion.setFromEuler(euler, true); - } + this.matrix.decompose( this.position, this.quaternion, this.scale ); - 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); + 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) { + rotateOnAxis( axis, angle ) { + // rotate object on axis in object space // axis is assumed to be normalized - _q1.setFromAxisAngle(axis, angle); - this.quaternion.multiply(_q1); + _q1.setFromAxisAngle( axis, angle ); + + this.quaternion.multiply( _q1 ); + return this; + } - rotateOnWorldAxis(axis, angle) { + rotateOnWorldAxis( axis, angle ) { + // rotate object on axis in world space // axis is assumed to be normalized // method assumes no rotated parent - _q1.setFromAxisAngle(axis, angle); - this.quaternion.premultiply(_q1); + _q1.setFromAxisAngle( axis, angle ); + + this.quaternion.premultiply( _q1 ); + return this; + } - rotateX(angle) { - return this.rotateOnAxis(_xAxis, angle); + rotateX( angle ) { + + return this.rotateOnAxis( _xAxis, angle ); + } - rotateY(angle) { - return this.rotateOnAxis(_yAxis, angle); + rotateY( angle ) { + + return this.rotateOnAxis( _yAxis, angle ); + } - rotateZ(angle) { - return this.rotateOnAxis(_zAxis, angle); + rotateZ( angle ) { + + return this.rotateOnAxis( _zAxis, angle ); + } - translateOnAxis(axis, distance) { + 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); - this.position.add(_v1$4.multiplyScalar(distance)); + _v1$4.copy( axis ).applyQuaternion( this.quaternion ); + + this.position.add( _v1$4.multiplyScalar( distance ) ); + return this; + } - translateX(distance) { - return this.translateOnAxis(_xAxis, distance); + translateX( distance ) { + + return this.translateOnAxis( _xAxis, distance ); + } - translateY(distance) { - return this.translateOnAxis(_yAxis, distance); + translateY( distance ) { + + return this.translateOnAxis( _yAxis, distance ); + } - translateZ(distance) { - return this.translateOnAxis(_zAxis, distance); + translateZ( distance ) { + + return this.translateOnAxis( _zAxis, distance ); + } - localToWorld(vector) { - return vector.applyMatrix4(this.matrixWorld); + localToWorld( vector ) { + + this.updateWorldMatrix( true, false ); + + return vector.applyMatrix4( this.matrixWorld ); + } - worldToLocal(vector) { - return vector.applyMatrix4(_m1$1.copy(this.matrixWorld).invert()); + worldToLocal( vector ) { + + this.updateWorldMatrix( true, false ); + + return vector.applyMatrix4( _m1$1.copy( this.matrixWorld ).invert() ); + } - lookAt(x, y, z) { + lookAt( x, y, z ) { + // This method does not support objects having non-uniformly-scaled parent(s) - if (x.isVector3) { - _target.copy(x); + + if ( x.isVector3 ) { + + _target.copy( x ); + } else { - _target.set(x, y, z); + + _target.set( x, y, z ); + } const parent = this.parent; - this.updateWorldMatrix(true, false); - _position$3.setFromMatrixPosition(this.matrixWorld); + this.updateWorldMatrix( true, false ); + + _position$3.setFromMatrixPosition( this.matrixWorld ); + + if ( this.isCamera || this.isLight ) { + + _m1$1.lookAt( _position$3, _target, this.up ); - if (this.isCamera || this.isLight) { - _m1$1.lookAt(_position$3, _target, this.up); } else { - _m1$1.lookAt(_target, _position$3, this.up); + + _m1$1.lookAt( _target, _position$3, this.up ); + } - this.quaternion.setFromRotationMatrix(_m1$1); + this.quaternion.setFromRotationMatrix( _m1$1 ); - if (parent) { - _m1$1.extractRotation(parent.matrixWorld); + if ( parent ) { - _q1.setFromRotationMatrix(_m1$1); + _m1$1.extractRotation( parent.matrixWorld ); + _q1.setFromRotationMatrix( _m1$1 ); + this.quaternion.premultiply( _q1.invert() ); - this.quaternion.premultiply(_q1.invert()); } + } - add(object) { - if (arguments.length > 1) { - for (let i = 0; i < arguments.length; i++) { - this.add(arguments[i]); + 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); + 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); + if ( object && object.isObject3D ) { + + if ( object.parent !== null ) { + + object.parent.remove( object ); + } object.parent = this; - this.children.push(object); - object.dispatchEvent(_addedEvent); + this.children.push( object ); + + object.dispatchEvent( _addedEvent ); + } else { - console.error('THREE.Object3D.add: object not an instance of THREE.Object3D.', object); + + 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]); + 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); + const index = this.children.indexOf( object ); + + if ( index !== - 1 ) { - if (index !== -1) { object.parent = null; - this.children.splice(index, 1); - object.dispatchEvent(_removedEvent); + this.children.splice( index, 1 ); + + object.dispatchEvent( _removedEvent ); + } return this; + } removeFromParent() { + const parent = this.parent; - if (parent !== null) { - parent.remove(this); + if ( parent !== null ) { + + parent.remove( this ); + } return this; + } clear() { - for (let i = 0; i < this.children.length; i++) { - const object = this.children[i]; + + for ( let i = 0; i < this.children.length; i ++ ) { + + const object = this.children[ i ]; + object.parent = null; - object.dispatchEvent(_removedEvent); + + object.dispatchEvent( _removedEvent ); + } this.children.length = 0; + return this; + + } - attach(object) { + 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); - _m1$1.copy(this.matrixWorld).invert(); + this.updateWorldMatrix( true, false ); + + _m1$1.copy( this.matrixWorld ).invert(); + + if ( object.parent !== null ) { - if (object.parent !== null) { - object.parent.updateWorldMatrix(true, false); + object.parent.updateWorldMatrix( true, false ); + + _m1$1.multiply( object.parent.matrixWorld ); - _m1$1.multiply(object.parent.matrixWorld); } - object.applyMatrix4(_m1$1); - this.add(object); - object.updateWorldMatrix(false, true); + object.applyMatrix4( _m1$1 ); + + this.add( object ); + + object.updateWorldMatrix( false, true ); + return this; + } - getObjectById(id) { - return this.getObjectByProperty('id', id); + getObjectById( id ) { + + return this.getObjectByProperty( 'id', id ); + } - getObjectByName(name) { - return this.getObjectByProperty('name', name); + getObjectByName( name ) { + + return this.getObjectByProperty( 'name', name ); + } - getObjectByProperty(name, value) { - if (this[name] === value) return this; + 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 ); - 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 ) { - if (object !== undefined) { return object; + } + } return undefined; + + } + + getObjectsByProperty( name, value ) { + + let result = []; + + if ( this[ name ] === value ) result.push( this ); + + for ( let i = 0, l = this.children.length; i < l; i ++ ) { + + const childResult = this.children[ i ].getObjectsByProperty( name, value ); + + if ( childResult.length > 0 ) { + + result = result.concat( childResult ); + + } + + } + + return result; + } - getWorldPosition(target) { - this.updateWorldMatrix(true, false); - return target.setFromMatrixPosition(this.matrixWorld); + 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); + 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); + getWorldScale( target ) { + + this.updateWorldMatrix( true, false ); + + this.matrixWorld.decompose( _position$3, _quaternion$2, target ); + return target; + } - getWorldDirection(target) { - this.updateWorldMatrix(true, false); + getWorldDirection( target ) { + + this.updateWorldMatrix( true, false ); + const e = this.matrixWorld.elements; - return target.set(e[8], e[9], e[10]).normalize(); + + return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize(); + } - raycast() {} + raycast( /* raycaster, intersects */ ) {} + + traverse( callback ) { + + callback( this ); - traverse(callback) { - callback(this); const children = this.children; - for (let i = 0, l = children.length; i < l; i++) { - children[i].traverse(callback); + for ( let i = 0, l = children.length; i < l; i ++ ) { + + children[ i ].traverse( callback ); + } + } - traverseVisible(callback) { - if (this.visible === false) return; - callback(this); + 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); + for ( let i = 0, l = children.length; i < l; i ++ ) { + + children[ i ].traverseVisible( callback ); + } + } - traverseAncestors(callback) { + traverseAncestors( callback ) { + const parent = this.parent; - if (parent !== null) { - callback(parent); - parent.traverseAncestors(callback); + if ( parent !== null ) { + + callback( parent ); + + parent.traverseAncestors( callback ); + } + } updateMatrix() { - this.matrix.compose(this.position, this.quaternion, this.scale); + + this.matrix.compose( this.position, this.quaternion, this.scale ); + this.matrixWorldNeedsUpdate = true; + } - updateMatrixWorld(force) { - if (this.matrixAutoUpdate) this.updateMatrix(); + updateMatrixWorld( force ) { + + if ( this.matrixAutoUpdate ) this.updateMatrix(); + + if ( this.matrixWorldNeedsUpdate || force ) { + + if ( this.parent === null ) { + + this.matrixWorld.copy( this.matrix ); - if (this.matrixWorldNeedsUpdate || force) { - if (this.parent === null) { - this.matrixWorld.copy(this.matrix); } else { - this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); + + 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); + for ( let i = 0, l = children.length; i < l; i ++ ) { + + const child = children[ i ]; + + if ( child.matrixWorldAutoUpdate === true || force === true ) { + + child.updateMatrixWorld( force ); + + } + } + } - updateWorldMatrix(updateParents, updateChildren) { + updateWorldMatrix( updateParents, updateChildren ) { + const parent = this.parent; - if (updateParents === true && parent !== null) { - parent.updateWorldMatrix(true, false); + if ( updateParents === true && parent !== null && parent.matrixWorldAutoUpdate === true ) { + + parent.updateWorldMatrix( true, false ); + } - if (this.matrixAutoUpdate) this.updateMatrix(); + if ( this.matrixAutoUpdate ) this.updateMatrix(); + + if ( this.parent === null ) { + + this.matrixWorld.copy( this.matrix ); - if (this.parent === null) { - this.matrixWorld.copy(this.matrix); } else { - this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); - } // update children + this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); + + } + + // update children + + if ( updateChildren === true ) { - if (updateChildren === true) { const children = this.children; - for (let i = 0, l = children.length; i < l; i++) { - children[i].updateWorldMatrix(false, true); + for ( let i = 0, l = children.length; i < l; i ++ ) { + + const child = children[ i ]; + + if ( child.matrixWorldAutoUpdate === true ) { + + child.updateWorldMatrix( false, true ); + + } + } + } + } - toJSON(meta) { + 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 isRootObject = ( meta === undefined || typeof meta === 'string' ); + + const output = {}; + + // meta is a hash used to collect geometries, materials. // not providing it implies that this is the root object // being serialized. + if ( isRootObject ) { - if (isRootObject) { // initialize meta obj meta = { geometries: {}, @@ -6303,446 +8142,574 @@ class Object3D extends EventDispatcher { animations: {}, nodes: {} }; + output.metadata = { version: 4.5, type: 'Object', generator: 'Object3D.toJSON' }; - } // standard Object3D serialization + } + + // standard Object3D serialization const object = {}; + object.uuid = this.uuid; object.type = this.type; - if (this.name !== '') object.name = this.name; - if (this.castShadow === true) object.castShadow = true; - if (this.receiveShadow === true) object.receiveShadow = true; - if (this.visible === false) object.visible = false; - if (this.frustumCulled === false) object.frustumCulled = false; - if (this.renderOrder !== 0) object.renderOrder = this.renderOrder; - if (JSON.stringify(this.userData) !== '{}') object.userData = this.userData; + + if ( this.name !== '' ) object.name = this.name; + if ( this.castShadow === true ) object.castShadow = true; + if ( this.receiveShadow === true ) object.receiveShadow = true; + if ( this.visible === false ) object.visible = false; + if ( this.frustumCulled === false ) object.frustumCulled = false; + if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; + if ( Object.keys( this.userData ).length > 0 ) object.userData = this.userData; + object.layers = this.layers.mask; object.matrix = this.matrix.toArray(); - if (this.matrixAutoUpdate === false) object.matrixAutoUpdate = false; // object specific properties - if (this.isInstancedMesh) { + 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(); - } // + if ( this.instanceColor !== null ) object.instanceColor = this.instanceColor.toJSON(); + + } + + // + + function serialize( library, element ) { + + if ( library[ element.uuid ] === undefined ) { + library[ element.uuid ] = element.toJSON( meta ); - 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) { + if ( this.isScene ) { + + if ( this.background ) { + + if ( this.background.isColor ) { + object.background = this.background.toJSON(); - } else if (this.background.isTexture) { - object.background = this.background.toJSON(meta).uuid; + + } else if ( this.background.isTexture ) { + + object.background = this.background.toJSON( meta ).uuid; + } + } - if (this.environment && this.environment.isTexture) { - object.environment = this.environment.toJSON(meta).uuid; + 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); + + } 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) { + if ( parameters !== undefined && parameters.shapes !== undefined ) { + const shapes = parameters.shapes; - if (Array.isArray(shapes)) { - for (let i = 0, l = shapes.length; i < l; i++) { - const shape = shapes[i]; - serialize(meta.shapes, shape); + if ( Array.isArray( shapes ) ) { + + for ( let i = 0, l = shapes.length; i < l; i ++ ) { + + const shape = shapes[ i ]; + + serialize( meta.shapes, shape ); + } + } else { - serialize(meta.shapes, shapes); + + serialize( meta.shapes, shapes ); + } + } + } - if (this.isSkinnedMesh) { + if ( this.isSkinnedMesh ) { + object.bindMode = this.bindMode; object.bindMatrix = this.bindMatrix.toArray(); - if (this.skeleton !== undefined) { - serialize(meta.skeletons, this.skeleton); + if ( this.skeleton !== undefined ) { + + serialize( meta.skeletons, this.skeleton ); + object.skeleton = this.skeleton.uuid; + } + } - if (this.material !== undefined) { - if (Array.isArray(this.material)) { + 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])); + 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); + + object.material = serialize( meta.materials, this.material ); + } - } // + } + + // + + if ( this.children.length > 0 ) { - 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); + for ( let i = 0; i < this.children.length; i ++ ) { + + object.children.push( this.children[ i ].toJSON( meta ).object ); + } - } // + } + + // + + if ( this.animations.length > 0 ) { - 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)); + for ( let i = 0; i < this.animations.length; i ++ ) { + + const animation = this.animations[ i ]; + + object.animations.push( serialize( meta.animations, animation ) ); + } + } - if (isRootObject) { - const geometries = extractFromCache(meta.geometries); - const materials = extractFromCache(meta.materials); - const textures = extractFromCache(meta.textures); - const images = extractFromCache(meta.images); - const shapes = extractFromCache(meta.shapes); - const skeletons = extractFromCache(meta.skeletons); - const animations = extractFromCache(meta.animations); - const nodes = extractFromCache(meta.nodes); - if (geometries.length > 0) output.geometries = geometries; - if (materials.length > 0) output.materials = materials; - if (textures.length > 0) output.textures = textures; - if (images.length > 0) output.images = images; - if (shapes.length > 0) output.shapes = shapes; - if (skeletons.length > 0) output.skeletons = skeletons; - if (animations.length > 0) output.animations = animations; - if (nodes.length > 0) output.nodes = nodes; + if ( isRootObject ) { + + const geometries = extractFromCache( meta.geometries ); + const materials = extractFromCache( meta.materials ); + const textures = extractFromCache( meta.textures ); + const images = extractFromCache( meta.images ); + const shapes = extractFromCache( meta.shapes ); + const skeletons = extractFromCache( meta.skeletons ); + const animations = extractFromCache( meta.animations ); + const nodes = extractFromCache( meta.nodes ); + + if ( geometries.length > 0 ) output.geometries = geometries; + if ( materials.length > 0 ) output.materials = materials; + if ( textures.length > 0 ) output.textures = textures; + if ( images.length > 0 ) output.images = images; + if ( shapes.length > 0 ) output.shapes = shapes; + if ( skeletons.length > 0 ) output.skeletons = skeletons; + if ( animations.length > 0 ) output.animations = animations; + 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 ) { - function extractFromCache(cache) { const values = []; + for ( const key in cache ) { - for (const key in cache) { - const data = cache[key]; + const data = cache[ key ]; delete data.metadata; - values.push(data); + values.push( data ); + } return values; + } + } - clone(recursive) { - return new this.constructor().copy(this, recursive); + clone( recursive ) { + + return new this.constructor().copy( this, recursive ); + } - copy(source, recursive = true) { + copy( source, recursive = true ) { + this.name = source.name; - this.up.copy(source.up); - this.position.copy(source.position); + + this.up.copy( source.up ); + + this.position.copy( source.position ); this.rotation.order = source.rotation.order; - this.quaternion.copy(source.quaternion); - this.scale.copy(source.scale); - this.matrix.copy(source.matrix); - this.matrixWorld.copy(source.matrixWorld); + this.quaternion.copy( source.quaternion ); + this.scale.copy( source.scale ); + + this.matrix.copy( source.matrix ); + this.matrixWorld.copy( source.matrixWorld ); + this.matrixAutoUpdate = source.matrixAutoUpdate; this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; + + this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; + this.layers.mask = source.layers.mask; this.visible = source.visible; + this.castShadow = source.castShadow; this.receiveShadow = source.receiveShadow; + this.frustumCulled = source.frustumCulled; this.renderOrder = source.renderOrder; - this.userData = JSON.parse(JSON.stringify(source.userData)); - if (recursive === true) { - for (let i = 0; i < source.children.length; i++) { - const child = source.children[i]; - this.add(child.clone()); - } - } + this.userData = JSON.parse( JSON.stringify( source.userData ) ); - return this; - } + if ( recursive === true ) { -} + for ( let i = 0; i < source.children.length; i ++ ) { -Object3D.DefaultUp = new Vector3(0, 1, 0); -Object3D.DefaultMatrixAutoUpdate = true; + const child = source.children[ i ]; + this.add( child.clone() ); -const _v0$1 = /*@__PURE__*/new Vector3(); + } -const _v1$3 = /*@__PURE__*/new Vector3(); + } -const _v2$2 = /*@__PURE__*/new Vector3(); + return this; -const _v3$1 = /*@__PURE__*/new Vector3(); + } -const _vab = /*@__PURE__*/new Vector3(); +} -const _vac = /*@__PURE__*/new Vector3(); +Object3D.DEFAULT_UP = /*@__PURE__*/ new Vector3( 0, 1, 0 ); +Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true; +Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true; -const _vbc = /*@__PURE__*/new Vector3(); +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 _vap = /*@__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(); -const _vbp = /*@__PURE__*/new Vector3(); +class Triangle { -const _vcp = /*@__PURE__*/new Vector3(); + constructor( a = new Vector3(), b = new Vector3(), c = 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); + static getNormal( a, b, c, target ) { - _v0$1.subVectors(a, b); + target.subVectors( c, b ); + _v0$1.subVectors( a, b ); + target.cross( _v0$1 ); - target.cross(_v0$1); const targetLengthSq = target.lengthSq(); + if ( targetLengthSq > 0 ) { - 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 - + return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); - static getBarycoord(point, a, b, c, target) { - _v0$1.subVectors(c, a); - - _v1$3.subVectors(b, a); + } - _v2$2.subVectors(point, a); + return target.set( 0, 0, 0 ); - const dot00 = _v0$1.dot(_v0$1); + } - const dot01 = _v0$1.dot(_v1$3); + // static/instance method to calculate barycentric coordinates + // based on: http://www.blackpawn.com/texts/pointinpoly/default.html + static getBarycoord( point, a, b, c, target ) { - const dot02 = _v0$1.dot(_v2$2); + _v0$1.subVectors( c, a ); + _v1$3.subVectors( b, a ); + _v2$2.subVectors( point, a ); - const dot11 = _v1$3.dot(_v1$3); + 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 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 ) { - 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); + 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 u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; + const v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; + + // barycentric coordinates must always sum to 1 + return target.set( 1 - u - v, v, u ); - 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 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); - target.addScaledVector(uv1, _v3$1.x); - target.addScaledVector(uv2, _v3$1.y); - target.addScaledVector(uv3, _v3$1.z); + static getUV( point, p1, p2, p3, uv1, uv2, uv3, target ) { + + this.getBarycoord( point, p1, p2, p3, _v3$1 ); + + target.set( 0, 0 ); + target.addScaledVector( uv1, _v3$1.x ); + target.addScaledVector( uv2, _v3$1.y ); + target.addScaledVector( uv3, _v3$1.z ); + return target; + } - static isFrontFacing(a, b, c, direction) { - _v0$1.subVectors(c, b); + static isFrontFacing( a, b, c, direction ) { - _v1$3.subVectors(a, b); // strictly front facing + _v0$1.subVectors( c, b ); + _v1$3.subVectors( a, b ); + // strictly front facing + return ( _v0$1.cross( _v1$3 ).dot( direction ) < 0 ) ? true : false; - 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); + 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]); + 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); + 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); + + return new this.constructor().copy( this ); + } - copy(triangle) { - this.a.copy(triangle.a); - this.b.copy(triangle.b); - this.c.copy(triangle.c); + 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); + _v0$1.subVectors( this.c, this.b ); + _v1$3.subVectors( this.a, this.b ); + + return _v0$1.cross( _v1$3 ).length() * 0.5; - return _v0$1.cross(_v1$3).length() * 0.5; } - getMidpoint(target) { - return target.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3); + 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); + getNormal( target ) { + + return Triangle.getNormal( this.a, this.b, this.c, target ); + } - getPlane(target) { - return target.setFromCoplanarPoints(this.a, this.b, this.c); + 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); + 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); + 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); + containsPoint( point ) { + + return Triangle.containsPoint( point, this.a, this.b, this.c ); + } - isFrontFacing(direction) { - return Triangle.isFrontFacing(this.a, this.b, this.c, direction); + isFrontFacing( direction ) { + + return Triangle.isFrontFacing( this.a, this.b, this.c, direction ); + } - intersectsBox(box) { - return box.intersectsTriangle(this); + 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, + 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, // 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); + _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 ) { - 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); + return target.copy( a ); - const d3 = _vab.dot(_vbp); + } - const d4 = _vac.dot(_vbp); + _vbp.subVectors( p, b ); + const d3 = _vab.dot( _vbp ); + const d4 = _vac.dot( _vbp ); + if ( d3 >= 0 && d4 <= d3 ) { - if (d3 >= 0 && d4 <= d3) { // vertex region of B; barycentric coords (0, 1, 0) - return target.copy(b); + return target.copy( b ); + } const vc = d1 * d4 - d3 * d2; + if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { - 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 ); - return target.copy(a).addScaledVector(_vab, v); } - _vcp.subVectors(p, c); - - const d5 = _vab.dot(_vcp); - - const d6 = _vac.dot(_vcp); + _vcp.subVectors( p, c ); + const d5 = _vab.dot( _vcp ); + const d6 = _vac.dot( _vcp ); + if ( d6 >= 0 && d5 <= d6 ) { - if (d6 >= 0 && d5 <= d6) { // vertex region of C; barycentric coords (0, 0, 1) - return target.copy(c); + return target.copy( c ); + } const vb = d5 * d2 - d1 * d6; + if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { - 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 ); - return target.copy(a).addScaledVector(_vac, w); } const va = d3 * d6 - d5 * d4; + if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { - 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) - - return target.copy(b).addScaledVector(_vbc, w); // edge region of BC - } // face region - + _vbc.subVectors( c, b ); + 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 - 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); + + 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); + equals( triangle ) { + + return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); + } } @@ -6750,29 +8717,38 @@ class Triangle { let materialId = 0; class Material extends EventDispatcher { + constructor() { + super(); + this.isMaterial = true; - Object.defineProperty(this, 'id', { - value: materialId++ - }); + + Object.defineProperty( this, 'id', { value: materialId ++ } ); + this.uuid = generateUUID(); + this.name = ''; this.type = 'Material'; + this.blending = NormalBlending; this.side = FrontSide; this.vertexColors = false; + this.opacity = 1; this.transparent = false; + this.blendSrc = SrcAlphaFactor; this.blendDst = OneMinusSrcAlphaFactor; this.blendEquation = AddEquation; this.blendSrcAlpha = null; this.blendDstAlpha = null; this.blendEquationAlpha = null; + this.depthFunc = LessEqualDepth; this.depthTest = true; this.depthWrite = true; + this.stencilWriteMask = 0xff; this.stencilFunc = AlwaysStencilFunc; this.stencilRef = 0; @@ -6781,91 +8757,122 @@ class Material extends EventDispatcher { this.stencilZFail = KeepStencilOp; this.stencilZPass = KeepStencilOp; this.stencilWrite = false; + this.clippingPlanes = null; this.clipIntersection = false; this.clipShadows = false; + this.shadowSide = null; + this.colorWrite = true; + this.precision = null; // override the renderer's default precision for this material this.polygonOffset = false; this.polygonOffsetFactor = 0; this.polygonOffsetUnits = 0; + this.dithering = false; + this.alphaToCoverage = false; this.premultipliedAlpha = false; + this.forceSinglePass = false; + this.visible = true; + this.toneMapped = true; + this.userData = {}; + this.version = 0; + this._alphaTest = 0; + } get alphaTest() { + return this._alphaTest; + } - set alphaTest(value) { - if (this._alphaTest > 0 !== value > 0) { - this.version++; + set alphaTest( value ) { + + if ( this._alphaTest > 0 !== value > 0 ) { + + this.version ++; + } this._alphaTest = value; + } - onBuild() {} + onBuild( /* shaderobject, renderer */ ) {} - onBeforeRender() {} + onBeforeRender( /* renderer, scene, camera, geometry, object, group */ ) {} - onBeforeCompile() {} + onBeforeCompile( /* shaderobject, renderer */ ) {} customProgramCacheKey() { + return this.onBeforeCompile.toString(); + } - setValues(values) { - if (values === undefined) return; + setValues( values ) { - for (const key in values) { - const newValue = values[key]; + if ( values === undefined ) return; - if (newValue === undefined) { - console.warn('THREE.Material: \'' + key + '\' parameter is undefined.'); - continue; - } // for backward compatibility if shading is set in the constructor + for ( const key in values ) { + + const newValue = values[ key ]; + if ( newValue === undefined ) { - if (key === 'shading') { - console.warn('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.'); - this.flatShading = newValue === FlatShading ? true : false; + console.warn( 'THREE.Material: \'' + key + '\' parameter is undefined.' ); continue; + } - const currentValue = this[key]; + const currentValue = this[ key ]; + + if ( currentValue === undefined ) { - if (currentValue === undefined) { - console.warn('THREE.' + this.type + ': \'' + key + '\' is not a property of this material.'); + 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) { - currentValue.copy(newValue); + if ( currentValue && currentValue.isColor ) { + + currentValue.set( newValue ); + + } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { + + currentValue.copy( newValue ); + } else { - this[key] = newValue; + + this[ key ] = newValue; + } + } + } - toJSON(meta) { - const isRootObject = meta === undefined || typeof meta === 'string'; + toJSON( meta ) { + + const isRootObject = ( meta === undefined || typeof meta === 'string' ); + + if ( isRootObject ) { - if (isRootObject) { meta = { textures: {}, images: {} }; + } const data = { @@ -6874,120 +8881,157 @@ class Material extends EventDispatcher { 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; - if (this.color && this.color.isColor) data.color = this.color.getHex(); - if (this.roughness !== undefined) data.roughness = this.roughness; - if (this.metalness !== undefined) data.metalness = this.metalness; - if (this.sheen !== undefined) data.sheen = this.sheen; - if (this.sheenColor && this.sheenColor.isColor) data.sheenColor = this.sheenColor.getHex(); - if (this.sheenRoughness !== undefined) data.sheenRoughness = this.sheenRoughness; - if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex(); - if (this.emissiveIntensity && this.emissiveIntensity !== 1) data.emissiveIntensity = this.emissiveIntensity; - if (this.specular && this.specular.isColor) data.specular = this.specular.getHex(); - if (this.specularIntensity !== undefined) data.specularIntensity = this.specularIntensity; - if (this.specularColor && this.specularColor.isColor) data.specularColor = this.specularColor.getHex(); - if (this.shininess !== undefined) data.shininess = this.shininess; - if (this.clearcoat !== undefined) data.clearcoat = this.clearcoat; - if (this.clearcoatRoughness !== undefined) data.clearcoatRoughness = this.clearcoatRoughness; - - if (this.clearcoatMap && this.clearcoatMap.isTexture) { - data.clearcoatMap = this.clearcoatMap.toJSON(meta).uuid; - } - - if (this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture) { - data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON(meta).uuid; - } - - if (this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture) { - data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON(meta).uuid; + + if ( this.name !== '' ) data.name = this.name; + + if ( this.color && this.color.isColor ) data.color = this.color.getHex(); + + if ( this.roughness !== undefined ) data.roughness = this.roughness; + if ( this.metalness !== undefined ) data.metalness = this.metalness; + + if ( this.sheen !== undefined ) data.sheen = this.sheen; + if ( this.sheenColor && this.sheenColor.isColor ) data.sheenColor = this.sheenColor.getHex(); + if ( this.sheenRoughness !== undefined ) data.sheenRoughness = this.sheenRoughness; + if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); + if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; + + if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); + if ( this.specularIntensity !== undefined ) data.specularIntensity = this.specularIntensity; + if ( this.specularColor && this.specularColor.isColor ) data.specularColor = this.specularColor.getHex(); + if ( this.shininess !== undefined ) data.shininess = this.shininess; + if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat; + if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness; + + if ( this.clearcoatMap && this.clearcoatMap.isTexture ) { + + data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid; + + } + + if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) { + + data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid; + + } + + if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) { + + data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid; data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); + } - if (this.iridescence !== undefined) data.iridescence = this.iridescence; - if (this.iridescenceIOR !== undefined) data.iridescenceIOR = this.iridescenceIOR; - if (this.iridescenceThicknessRange !== undefined) data.iridescenceThicknessRange = this.iridescenceThicknessRange; + 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.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.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.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 ) { - if (this.lightMap && this.lightMap.isTexture) { - data.lightMap = this.lightMap.toJSON(meta).uuid; + data.lightMap = this.lightMap.toJSON( meta ).uuid; data.lightMapIntensity = this.lightMapIntensity; + } - if (this.aoMap && this.aoMap.isTexture) { - data.aoMap = this.aoMap.toJSON(meta).uuid; + if ( this.aoMap && this.aoMap.isTexture ) { + + data.aoMap = this.aoMap.toJSON( meta ).uuid; data.aoMapIntensity = this.aoMapIntensity; + } - if (this.bumpMap && this.bumpMap.isTexture) { - data.bumpMap = this.bumpMap.toJSON(meta).uuid; + 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; + 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; + 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.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.attenuationColor !== undefined) data.attenuationColor = this.attenuationColor.getHex(); - if (this.size !== undefined) data.size = this.size; - if (this.shadowSide !== null) data.shadowSide = this.shadowSide; - if (this.sizeAttenuation !== undefined) data.sizeAttenuation = this.sizeAttenuation; - if (this.blending !== NormalBlending) data.blending = this.blending; - if (this.side !== FrontSide) data.side = this.side; - if (this.vertexColors) data.vertexColors = true; - if (this.opacity < 1) data.opacity = this.opacity; - if (this.transparent === true) data.transparent = this.transparent; + 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 && 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; + if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; + + if ( this.blending !== NormalBlending ) data.blending = this.blending; + if ( this.side !== FrontSide ) data.side = this.side; + if ( this.vertexColors ) data.vertexColors = true; + + if ( this.opacity < 1 ) data.opacity = this.opacity; + if ( this.transparent === true ) data.transparent = this.transparent; + data.depthFunc = this.depthFunc; data.depthTest = this.depthTest; data.depthWrite = this.depthWrite; data.colorWrite = this.colorWrite; + data.stencilWrite = this.stencilWrite; data.stencilWriteMask = this.stencilWriteMask; data.stencilFunc = this.stencilFunc; @@ -6995,72 +9039,102 @@ class Material extends EventDispatcher { data.stencilFuncMask = this.stencilFuncMask; data.stencilFail = this.stencilFail; data.stencilZFail = this.stencilZFail; - 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; - if (this.polygonOffsetUnits !== 0) data.polygonOffsetUnits = this.polygonOffsetUnits; - if (this.linewidth !== undefined && this.linewidth !== 1) data.linewidth = this.linewidth; - if (this.dashSize !== undefined) data.dashSize = this.dashSize; - if (this.gapSize !== undefined) data.gapSize = this.gapSize; - if (this.scale !== undefined) data.scale = this.scale; - if (this.dithering === true) data.dithering = true; - if (this.alphaTest > 0) data.alphaTest = this.alphaTest; - if (this.alphaToCoverage === true) data.alphaToCoverage = this.alphaToCoverage; - if (this.premultipliedAlpha === true) data.premultipliedAlpha = this.premultipliedAlpha; - if (this.wireframe === true) data.wireframe = this.wireframe; - if (this.wireframeLinewidth > 1) data.wireframeLinewidth = this.wireframeLinewidth; - if (this.wireframeLinecap !== 'round') data.wireframeLinecap = this.wireframeLinecap; - if (this.wireframeLinejoin !== 'round') data.wireframeLinejoin = this.wireframeLinejoin; - if (this.flatShading === true) data.flatShading = this.flatShading; - 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 - - function extractFromCache(cache) { + 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; + if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits; + + if ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth; + if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; + if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; + if ( this.scale !== undefined ) data.scale = this.scale; + + if ( this.dithering === true ) data.dithering = true; + + if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; + if ( this.alphaToCoverage === true ) data.alphaToCoverage = this.alphaToCoverage; + if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha; + if ( this.forceSinglePass === true ) data.forceSinglePass = this.forceSinglePass; + + if ( this.wireframe === true ) data.wireframe = this.wireframe; + if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; + if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; + if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; + + if ( this.flatShading === true ) data.flatShading = this.flatShading; + + if ( this.visible === false ) data.visible = false; + + if ( this.toneMapped === false ) data.toneMapped = false; + + if ( this.fog === false ) data.fog = false; + + if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; + + // TODO: Copied from Object3D.toJSON + + function extractFromCache( cache ) { + const values = []; - for (const key in cache) { - const data = cache[key]; + for ( const key in cache ) { + + const data = cache[ key ]; delete data.metadata; - values.push(data); + 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; + 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); + + return new this.constructor().copy( this ); + } - copy(source) { + copy( source ) { + this.name = source.name; + this.blending = source.blending; this.side = source.side; this.vertexColors = source.vertexColors; + this.opacity = source.opacity; this.transparent = source.transparent; + this.blendSrc = source.blendSrc; this.blendDst = source.blendDst; this.blendEquation = source.blendEquation; this.blendSrcAlpha = source.blendSrcAlpha; this.blendDstAlpha = source.blendDstAlpha; this.blendEquationAlpha = source.blendEquationAlpha; + this.depthFunc = source.depthFunc; this.depthTest = source.depthTest; this.depthWrite = source.depthWrite; + this.stencilWriteMask = source.stencilWriteMask; this.stencilFunc = source.stencilFunc; this.stencilRef = source.stencilRef; @@ -7069,1564 +9143,2055 @@ class Material extends EventDispatcher { this.stencilZFail = source.stencilZFail; this.stencilZPass = source.stencilZPass; this.stencilWrite = source.stencilWrite; + const srcPlanes = source.clippingPlanes; let dstPlanes = null; - if (srcPlanes !== null) { + if ( srcPlanes !== null ) { + const n = srcPlanes.length; - dstPlanes = new Array(n); + dstPlanes = new Array( n ); + + for ( let i = 0; i !== n; ++ i ) { + + dstPlanes[ i ] = srcPlanes[ i ].clone(); - for (let i = 0; i !== n; ++i) { - dstPlanes[i] = srcPlanes[i].clone(); } + } this.clippingPlanes = dstPlanes; this.clipIntersection = source.clipIntersection; this.clipShadows = source.clipShadows; + this.shadowSide = source.shadowSide; + this.colorWrite = source.colorWrite; + this.precision = source.precision; + this.polygonOffset = source.polygonOffset; this.polygonOffsetFactor = source.polygonOffsetFactor; this.polygonOffsetUnits = source.polygonOffsetUnits; + this.dithering = source.dithering; + this.alphaTest = source.alphaTest; this.alphaToCoverage = source.alphaToCoverage; this.premultipliedAlpha = source.premultipliedAlpha; + this.forceSinglePass = source.forceSinglePass; + this.visible = source.visible; + this.toneMapped = source.toneMapped; - this.userData = JSON.parse(JSON.stringify(source.userData)); + + this.userData = JSON.parse( JSON.stringify( source.userData ) ); + return this; - } - dispose() { - this.dispatchEvent({ - type: 'dispose' - }); } - set needsUpdate(value) { - if (value === true) this.version++; - } // @deprecated since r131, f5803c62cc4a29d90744e9dc7811d086e354c1d8 + dispose() { + this.dispatchEvent( { type: 'dispose' } ); - get vertexTangents() { - console.warn('THREE.' + this.type + ': .vertexTangents has been removed.'); - return false; } - set vertexTangents(value) { - console.warn('THREE.' + this.type + ': .vertexTangents has been removed.'); + set needsUpdate( value ) { + + if ( value === true ) this.version ++; + } } -Material.fromType = function - /*type*/ -() { - // TODO: Behavior added in Materials.js - return null; -}; - class MeshBasicMaterial extends Material { - constructor(parameters) { + + constructor( parameters ) { + super(); + this.isMeshBasicMaterial = true; + this.type = 'MeshBasicMaterial'; - this.color = new Color(0xffffff); // emissive + + this.color = new Color( 0xffffff ); // emissive this.map = null; + this.lightMap = null; this.lightMapIntensity = 1.0; + this.aoMap = null; this.aoMapIntensity = 1.0; + this.specularMap = null; + this.alphaMap = null; + this.envMap = null; this.combine = MultiplyOperation; this.reflectivity = 1; this.refractionRatio = 0.98; + this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = 'round'; this.wireframeLinejoin = 'round'; + this.fog = true; - this.setValues(parameters); + + this.setValues( parameters ); + } - copy(source) { - super.copy(source); - this.color.copy(source.color); + 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.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; + } } -const _vector$9 = /*@__PURE__*/new Vector3(); - -const _vector2$1 = /*@__PURE__*/new Vector2(); +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.'); + + constructor( array, itemSize, normalized = false ) { + + if ( Array.isArray( array ) ) { + + throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); + } this.isBufferAttribute = true; + this.name = ''; + this.array = array; this.itemSize = itemSize; this.count = array !== undefined ? array.length / itemSize : 0; - this.normalized = normalized === true; + this.normalized = normalized; + this.usage = StaticDrawUsage; - this.updateRange = { - offset: 0, - count: -1 - }; + this.updateRange = { offset: 0, count: - 1 }; + this.version = 0; + } onUploadCallback() {} - set needsUpdate(value) { - if (value === true) this.version++; + set needsUpdate( value ) { + + if ( value === true ) this.version ++; + } - setUsage(value) { + setUsage( value ) { + this.usage = value; + return this; + } - copy(source) { + copy( source ) { + this.name = source.name; - this.array = new source.array.constructor(source.array); + this.array = new source.array.constructor( source.array ); this.itemSize = source.itemSize; this.count = source.count; this.normalized = source.normalized; + this.usage = source.usage; + return this; + } - copyAt(index1, attribute, index2) { + 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]; + 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); + copyArray( array ) { + + this.array.set( array ); + return this; + } - copyColorsArray(colors) { - const array = this.array; - let offset = 0; + 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 ); - for (let i = 0, l = colors.length; i < l; i++) { - let color = colors[i]; + this.setXY( i, _vector2$1.x, _vector2$1.y ); - 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; - } + } else if ( this.itemSize === 3 ) { - return this; - } + for ( let i = 0, l = this.count; i < l; i ++ ) { - copyVector2sArray(vectors) { - const array = this.array; - let offset = 0; + _vector$9.fromBufferAttribute( this, i ); + _vector$9.applyMatrix3( m ); - for (let i = 0, l = vectors.length; i < l; i++) { - let vector = vectors[i]; + this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); - 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; + applyMatrix4( m ) { - for (let i = 0, l = vectors.length; i < l; i++) { - let vector = vectors[i]; + for ( let i = 0, l = this.count; i < l; i ++ ) { - if (vector === undefined) { - console.warn('THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i); - vector = new Vector3(); - } + _vector$9.fromBufferAttribute( this, i ); + + _vector$9.applyMatrix4( m ); + + this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); - array[offset++] = vector.x; - array[offset++] = vector.y; - array[offset++] = vector.z; } return this; + } - copyVector4sArray(vectors) { - const array = this.array; - let offset = 0; + applyNormalMatrix( m ) { - for (let i = 0, l = vectors.length; i < l; i++) { - let vector = vectors[i]; + for ( let i = 0, l = this.count; i < l; i ++ ) { - if (vector === undefined) { - console.warn('THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i); - vector = new Vector4(); - } + _vector$9.fromBufferAttribute( this, i ); + + _vector$9.applyNormalMatrix( m ); + + this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); - 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); + transformDirection( m ) { - _vector2$1.applyMatrix3(m); + for ( let i = 0, l = this.count; i < l; i ++ ) { - 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.fromBufferAttribute( this, i ); - _vector$9.applyMatrix3(m); + _vector$9.transformDirection( m ); + + this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); - 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); + set( value, offset = 0 ) { - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); - } + // Matching BufferAttribute constructor, do not normalize the array. + this.array.set( value, offset ); return this; + } - applyNormalMatrix(m) { - for (let i = 0, l = this.count; i < l; i++) { - _vector$9.fromBufferAttribute(this, i); + getX( index ) { - _vector$9.applyNormalMatrix(m); + let x = this.array[ index * this.itemSize ]; - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); - } + if ( this.normalized ) x = denormalize( x, this.array ); + + return x; - return this; } - transformDirection(m) { - for (let i = 0, l = this.count; i < l; i++) { - _vector$9.fromBufferAttribute(this, i); + setX( index, x ) { - _vector$9.transformDirection(m); + if ( this.normalized ) x = normalize( x, this.array ); - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); - } + this.array[ index * this.itemSize ] = x; return this; - } - set(value, offset = 0) { - this.array.set(value, offset); - return this; } - getX(index) { - return this.array[index * this.itemSize]; - } + getY( index ) { - setX(index, x) { - this.array[index * this.itemSize] = x; - return this; - } + let y = this.array[ index * this.itemSize + 1 ]; + + if ( this.normalized ) y = denormalize( y, this.array ); + + return y; - getY(index) { - return this.array[index * this.itemSize + 1]; } - setY(index, y) { - this.array[index * this.itemSize + 1] = 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]; + getZ( index ) { + + let z = this.array[ index * this.itemSize + 2 ]; + + if ( this.normalized ) z = denormalize( z, this.array ); + + return z; + } - setZ(index, z) { - this.array[index * this.itemSize + 2] = 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]; + getW( index ) { + + let w = this.array[ index * this.itemSize + 3 ]; + + if ( this.normalized ) w = denormalize( w, this.array ); + + return w; + } - setW(index, w) { - this.array[index * this.itemSize + 3] = 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) { + setXY( index, x, y ) { + index *= this.itemSize; - this.array[index + 0] = x; - this.array[index + 1] = y; + + 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) { + setXYZ( index, x, y, z ) { + index *= this.itemSize; - this.array[index + 0] = x; - this.array[index + 1] = y; - this.array[index + 2] = z; + + 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) { + setXYZW( index, x, y, z, w ) { + index *= this.itemSize; - this.array[index + 0] = x; - this.array[index + 1] = y; - this.array[index + 2] = z; - this.array[index + 3] = w; + + 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) { + onUpload( callback ) { + this.onUploadCallback = callback; + return this; + } clone() { - return new this.constructor(this.array, this.itemSize).copy(this); + + return new this.constructor( this.array, this.itemSize ).copy( this ); + } toJSON() { + const data = { itemSize: this.itemSize, type: this.array.constructor.name, - array: Array.prototype.slice.call(this.array), + array: Array.from( this.array ), normalized: this.normalized }; - if (this.name !== '') data.name = this.name; - if (this.usage !== StaticDrawUsage) data.usage = this.usage; - if (this.updateRange.offset !== 0 || this.updateRange.count !== -1) data.updateRange = this.updateRange; + + if ( this.name !== '' ) data.name = this.name; + if ( this.usage !== StaticDrawUsage ) data.usage = this.usage; + if ( this.updateRange.offset !== 0 || this.updateRange.count !== - 1 ) data.updateRange = this.updateRange; + 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); + + constructor( array, itemSize, normalized ) { + + super( new Int8Array( array ), itemSize, normalized ); + } } class Uint8BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Uint8Array(array), itemSize, normalized); + + constructor( array, itemSize, normalized ) { + + super( new Uint8Array( array ), itemSize, normalized ); + } } class Uint8ClampedBufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Uint8ClampedArray(array), itemSize, normalized); + + constructor( array, itemSize, normalized ) { + + super( new Uint8ClampedArray( array ), itemSize, normalized ); + } } class Int16BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Int16Array(array), itemSize, normalized); + + constructor( array, itemSize, normalized ) { + + super( new Int16Array( array ), itemSize, normalized ); + } } class Uint16BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Uint16Array(array), itemSize, normalized); + + constructor( array, itemSize, normalized ) { + + super( new Uint16Array( array ), itemSize, normalized ); + } } class Int32BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Int32Array(array), itemSize, normalized); + + constructor( array, itemSize, normalized ) { + + super( new Int32Array( array ), itemSize, normalized ); + } } class Uint32BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Uint32Array(array), itemSize, normalized); + + constructor( array, itemSize, normalized ) { + + super( new Uint32Array( array ), itemSize, normalized ); + } } class Float16BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Uint16Array(array), itemSize, normalized); + + 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); - } -} + 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; +class Float64BufferAttribute extends BufferAttribute { -const _m1 = /*@__PURE__*/new Matrix4(); + constructor( array, itemSize, normalized ) { -const _obj = /*@__PURE__*/new Object3D(); + super( new Float64Array( array ), itemSize, normalized ); -const _offset = /*@__PURE__*/new Vector3(); + } -const _box$1 = /*@__PURE__*/new Box3(); +} -const _boxMorphTargets = /*@__PURE__*/new Box3(); +let _id$1 = 0; -const _vector$8 = /*@__PURE__*/new Vector3(); +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(); + this.isBufferGeometry = true; - Object.defineProperty(this, 'id', { - value: _id$1++ - }); + + Object.defineProperty( this, 'id', { value: _id$1 ++ } ); + this.uuid = generateUUID(); + this.name = ''; this.type = 'BufferGeometry'; + this.index = null; this.attributes = {}; + this.morphAttributes = {}; this.morphTargetsRelative = false; + this.groups = []; + this.boundingBox = null; this.boundingSphere = null; - this.drawRange = { - start: 0, - count: Infinity - }; + + this.drawRange = { start: 0, count: Infinity }; + this.userData = {}; + } getIndex() { + return this.index; + } - setIndex(index) { - if (Array.isArray(index)) { - this.index = new (arrayNeedsUint32(index) ? Uint32BufferAttribute : Uint16BufferAttribute)(index, 1); + 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]; + getAttribute( name ) { + + return this.attributes[ name ]; + } - setAttribute(name, attribute) { - this.attributes[name] = attribute; + setAttribute( name, attribute ) { + + this.attributes[ name ] = attribute; + return this; + } - deleteAttribute(name) { - delete this.attributes[name]; + deleteAttribute( name ) { + + delete this.attributes[ name ]; + return this; + } - hasAttribute(name) { - return this.attributes[name] !== undefined; + hasAttribute( name ) { + + return this.attributes[ name ] !== undefined; + } - addGroup(start, count, materialIndex = 0) { - this.groups.push({ + addGroup( start, count, materialIndex = 0 ) { + + this.groups.push( { + start: start, count: count, materialIndex: materialIndex - }); + + } ); + } clearGroups() { + this.groups = []; + } - setDrawRange(start, count) { + setDrawRange( start, count ) { + this.drawRange.start = start; this.drawRange.count = count; + } - applyMatrix4(matrix) { + applyMatrix4( matrix ) { + const position = this.attributes.position; - if (position !== undefined) { - position.applyMatrix4(matrix); + 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); + 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 ( tangent !== undefined ) { + + tangent.transformDirection( matrix ); + + tangent.needsUpdate = true; + + } + + if ( this.boundingBox !== null ) { - if (this.boundingBox !== null) { this.computeBoundingBox(); + } - if (this.boundingSphere !== null) { + if ( this.boundingSphere !== null ) { + this.computeBoundingSphere(); + } return this; + } - applyQuaternion(q) { - _m1.makeRotationFromQuaternion(q); + applyQuaternion( q ) { + + _m1.makeRotationFromQuaternion( q ); + + this.applyMatrix4( _m1 ); - this.applyMatrix4(_m1); return this; + } - rotateX(angle) { + rotateX( angle ) { + // rotate geometry around world x-axis - _m1.makeRotationX(angle); - this.applyMatrix4(_m1); + _m1.makeRotationX( angle ); + + this.applyMatrix4( _m1 ); + return this; + } - rotateY(angle) { + rotateY( angle ) { + // rotate geometry around world y-axis - _m1.makeRotationY(angle); - this.applyMatrix4(_m1); + _m1.makeRotationY( angle ); + + this.applyMatrix4( _m1 ); + return this; + } - rotateZ(angle) { + rotateZ( angle ) { + // rotate geometry around world z-axis - _m1.makeRotationZ(angle); - this.applyMatrix4(_m1); + _m1.makeRotationZ( angle ); + + this.applyMatrix4( _m1 ); + return this; + } - translate(x, y, z) { + translate( x, y, z ) { + // translate geometry - _m1.makeTranslation(x, y, z); - this.applyMatrix4(_m1); + _m1.makeTranslation( x, y, z ); + + this.applyMatrix4( _m1 ); + return this; + } - scale(x, y, z) { + scale( x, y, z ) { + // scale geometry - _m1.makeScale(x, y, z); - this.applyMatrix4(_m1); + _m1.makeScale( x, y, z ); + + this.applyMatrix4( _m1 ); + return this; + } - lookAt(vector) { - _obj.lookAt(vector); + lookAt( vector ) { + + _obj.lookAt( vector ); _obj.updateMatrix(); - this.applyMatrix4(_obj.matrix); + this.applyMatrix4( _obj.matrix ); + return this; + } center() { + this.computeBoundingBox(); - this.boundingBox.getCenter(_offset).negate(); - this.translate(_offset.x, _offset.y, _offset.z); + + this.boundingBox.getCenter( _offset ).negate(); + + this.translate( _offset.x, _offset.y, _offset.z ); + return this; + } - setFromPoints(points) { + 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); + 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)); + this.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); + return this; + } computeBoundingBox() { - if (this.boundingBox === null) { + + 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)); + 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 + if ( position !== undefined ) { + + this.boundingBox.setFromBufferAttribute( position ); + + // process morph attributes if present + + if ( morphAttributesPosition ) { - if (morphAttributesPosition) { - for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { - const morphAttribute = morphAttributesPosition[i]; + for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - _box$1.setFromBufferAttribute(morphAttribute); + const morphAttribute = morphAttributesPosition[ i ]; + _box$1.setFromBufferAttribute( morphAttribute ); - if (this.morphTargetsRelative) { - _vector$8.addVectors(this.boundingBox.min, _box$1.min); + if ( this.morphTargetsRelative ) { - this.boundingBox.expandByPoint(_vector$8); + _vector$8.addVectors( this.boundingBox.min, _box$1.min ); + this.boundingBox.expandByPoint( _vector$8 ); - _vector$8.addVectors(this.boundingBox.max, _box$1.max); + _vector$8.addVectors( this.boundingBox.max, _box$1.max ); + this.boundingBox.expandByPoint( _vector$8 ); - this.boundingBox.expandByPoint(_vector$8); } else { - this.boundingBox.expandByPoint(_box$1.min); - this.boundingBox.expandByPoint(_box$1.max); + + this.boundingBox.expandByPoint( _box$1.min ); + this.boundingBox.expandByPoint( _box$1.max ); + } + } + } + } 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); + 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) { + + 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); + 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) { + if ( position ) { + // first, find the center of the bounding sphere + const center = this.boundingSphere.center; - _box$1.setFromBufferAttribute(position); // process morph attributes if present + _box$1.setFromBufferAttribute( position ); + + // process morph attributes if present + if ( morphAttributesPosition ) { - if (morphAttributesPosition) { - for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { - const morphAttribute = morphAttributesPosition[i]; + for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - _boxMorphTargets.setFromBufferAttribute(morphAttribute); + const morphAttribute = morphAttributesPosition[ i ]; + _boxMorphTargets.setFromBufferAttribute( morphAttribute ); - if (this.morphTargetsRelative) { - _vector$8.addVectors(_box$1.min, _boxMorphTargets.min); + if ( this.morphTargetsRelative ) { - _box$1.expandByPoint(_vector$8); + _vector$8.addVectors( _box$1.min, _boxMorphTargets.min ); + _box$1.expandByPoint( _vector$8 ); - _vector$8.addVectors(_box$1.max, _boxMorphTargets.max); + _vector$8.addVectors( _box$1.max, _boxMorphTargets.max ); + _box$1.expandByPoint( _vector$8 ); - _box$1.expandByPoint(_vector$8); } else { - _box$1.expandByPoint(_boxMorphTargets.min); - _box$1.expandByPoint(_boxMorphTargets.max); + _box$1.expandByPoint( _boxMorphTargets.min ); + _box$1.expandByPoint( _boxMorphTargets.max ); + } + } + } - _box$1.getCenter(center); // second, try to find a boundingSphere with a radius smaller than the - // boundingSphere of the boundingBox: sqrt(3) smaller in the best case + _box$1.getCenter( center ); + // second, try to find a boundingSphere with a radius smaller than the + // boundingSphere of the boundingBox: sqrt(3) smaller in the best case let maxRadiusSq = 0; - for (let i = 0, il = position.count; i < il; i++) { - _vector$8.fromBufferAttribute(position, i); + 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 - maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8)); - } // process morph attributes if present + if ( morphAttributesPosition ) { + for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - if (morphAttributesPosition) { - for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { - const morphAttribute = morphAttributesPosition[i]; + const morphAttribute = morphAttributesPosition[ i ]; const morphTargetsRelative = this.morphTargetsRelative; - for (let j = 0, jl = morphAttribute.count; j < jl; j++) { - _vector$8.fromBufferAttribute(morphAttribute, j); + for ( let j = 0, jl = morphAttribute.count; j < jl; j ++ ) { + + _vector$8.fromBufferAttribute( morphAttribute, j ); + + if ( morphTargetsRelative ) { - if (morphTargetsRelative) { - _offset.fromBufferAttribute(position, j); + _offset.fromBufferAttribute( position, j ); + _vector$8.add( _offset ); - _vector$8.add(_offset); } - maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8)); + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) ); + } + } + } - this.boundingSphere.radius = Math.sqrt(maxRadiusSq); + 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 ); - 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)'); + 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)); + if ( this.hasAttribute( 'tangent' ) === false ) { + + this.setAttribute( 'tangent', new BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) ); + } - const tangents = this.getAttribute('tangent').array; - const tan1 = [], - tan2 = []; + const tangents = this.getAttribute( 'tangent' ).array; + + const tan1 = [], tan2 = []; + + for ( let i = 0; i < nVertices; i ++ ) { + + tan1[ i ] = new Vector3(); + tan2[ i ] = new Vector3(); - 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(); - - function handleTriangle(a, b, c) { - vA.fromArray(positions, a * 3); - vB.fromArray(positions, b * 3); - vC.fromArray(positions, c * 3); - uvA.fromArray(uvs, a * 2); - uvB.fromArray(uvs, b * 2); - uvC.fromArray(uvs, c * 2); - vB.sub(vA); - 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 - - if (!isFinite(r)) return; - sdir.copy(vB).multiplyScalar(uvC.y).addScaledVector(vC, -uvB.y).multiplyScalar(r); - tdir.copy(vC).multiplyScalar(uvB.x).addScaledVector(vB, -uvC.x).multiplyScalar(r); - tan1[a].add(sdir); - tan1[b].add(sdir); - tan1[c].add(sdir); - tan2[a].add(tdir); - tan2[b].add(tdir); - tan2[c].add(tdir); + 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 ); + vC.fromArray( positions, c * 3 ); + + uvA.fromArray( uvs, a * 2 ); + uvB.fromArray( uvs, b * 2 ); + uvC.fromArray( uvs, c * 2 ); + + vB.sub( vA ); + 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 + + if ( ! isFinite( r ) ) return; + + sdir.copy( vB ).multiplyScalar( uvC.y ).addScaledVector( vC, - uvB.y ).multiplyScalar( r ); + tdir.copy( vC ).multiplyScalar( uvB.x ).addScaledVector( vB, - uvC.x ).multiplyScalar( r ); + + tan1[ a ].add( sdir ); + tan1[ b ].add( sdir ); + tan1[ c ].add( sdir ); + + tan2[ a ].add( tdir ); + tan2[ b ].add( tdir ); + tan2[ c ].add( tdir ); + } let groups = this.groups; - if (groups.length === 0) { - 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]; + 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]); + 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(); - const n = new Vector3(), - n2 = new Vector3(); + const tmp = new Vector3(), tmp2 = new Vector3(); + const n = new Vector3(), n2 = new Vector3(); + + function handleVertex( v ) { - function handleVertex(v) { - n.fromArray(normals, v * 3); - n2.copy(n); - const t = tan1[v]; // Gram-Schmidt orthogonalize + n.fromArray( normals, v * 3 ); + n2.copy( n ); - tmp.copy(t); - tmp.sub(n.multiplyScalar(n.dot(t))).normalize(); // Calculate handedness + const t = tan1[ v ]; + + // Gram-Schmidt orthogonalize + + tmp.copy( t ); + tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize(); + + // Calculate handedness + + tmp2.crossVectors( n2, t ); + const test = tmp2.dot( tan2[ v ] ); + const w = ( test < 0.0 ) ? - 1.0 : 1.0; + + tangents[ v * 4 ] = tmp.x; + tangents[ v * 4 + 1 ] = tmp.y; + tangents[ v * 4 + 2 ] = tmp.z; + tangents[ v * 4 + 3 ] = w; - tmp2.crossVectors(n2, t); - const test = tmp2.dot(tan2[v]); - const w = test < 0.0 ? -1.0 : 1.0; - tangents[v * 4] = tmp.x; - tangents[v * 4 + 1] = tmp.y; - 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]; + 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]); - handleVertex(indices[j + 2]); + for ( let j = start, jl = start + count; j < jl; j += 3 ) { + + handleVertex( indices[ j + 0 ] ); + handleVertex( indices[ j + 1 ] ); + handleVertex( indices[ j + 2 ] ); + } + } + } computeVertexNormals() { + const index = this.index; - const positionAttribute = this.getAttribute('position'); + const positionAttribute = this.getAttribute( 'position' ); - if (positionAttribute !== undefined) { - let normalAttribute = this.getAttribute('normal'); + if ( positionAttribute !== undefined ) { + + let normalAttribute = this.getAttribute( 'normal' ); + + if ( normalAttribute === undefined ) { + + normalAttribute = new BufferAttribute( new Float32Array( positionAttribute.count * 3 ), 3 ); + this.setAttribute( 'normal', normalAttribute ); - 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(); - const nA = new Vector3(), - nB = new Vector3(), - nC = new Vector3(); - const cb = new Vector3(), - ab = new Vector3(); // indexed elements - - if (index) { - for (let i = 0, il = index.count; i < il; i += 3) { - const vA = index.getX(i + 0); - const vB = index.getX(i + 1); - const vC = index.getX(i + 2); - pA.fromBufferAttribute(positionAttribute, vA); - pB.fromBufferAttribute(positionAttribute, vB); - pC.fromBufferAttribute(positionAttribute, vC); - cb.subVectors(pC, pB); - ab.subVectors(pA, pB); - cb.cross(ab); - nA.fromBufferAttribute(normalAttribute, vA); - nB.fromBufferAttribute(normalAttribute, vB); - nC.fromBufferAttribute(normalAttribute, vC); - nA.add(cb); - nB.add(cb); - nC.add(cb); - normalAttribute.setXYZ(vA, nA.x, nA.y, nA.z); - normalAttribute.setXYZ(vB, nB.x, nB.y, nB.z); - normalAttribute.setXYZ(vC, nC.x, nC.y, nC.z); + + 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(); + const nA = new Vector3(), nB = new Vector3(), nC = new Vector3(); + const cb = new Vector3(), ab = new Vector3(); + + // indexed elements + + if ( index ) { + + for ( let i = 0, il = index.count; i < il; i += 3 ) { + + const vA = index.getX( i + 0 ); + const vB = index.getX( i + 1 ); + const vC = index.getX( i + 2 ); + + pA.fromBufferAttribute( positionAttribute, vA ); + pB.fromBufferAttribute( positionAttribute, vB ); + pC.fromBufferAttribute( positionAttribute, vC ); + + cb.subVectors( pC, pB ); + ab.subVectors( pA, pB ); + cb.cross( ab ); + + nA.fromBufferAttribute( normalAttribute, vA ); + nB.fromBufferAttribute( normalAttribute, vB ); + nC.fromBufferAttribute( normalAttribute, vC ); + + nA.add( cb ); + nB.add( cb ); + nC.add( cb ); + + normalAttribute.setXYZ( vA, nA.x, nA.y, nA.z ); + normalAttribute.setXYZ( vB, nB.x, nB.y, nB.z ); + normalAttribute.setXYZ( vC, nC.x, nC.y, nC.z ); + } + } else { + // non-indexed elements (unconnected triangle soup) - for (let i = 0, il = positionAttribute.count; i < il; i += 3) { - pA.fromBufferAttribute(positionAttribute, i + 0); - pB.fromBufferAttribute(positionAttribute, i + 1); - pC.fromBufferAttribute(positionAttribute, i + 2); - cb.subVectors(pC, pB); - ab.subVectors(pA, pB); - cb.cross(ab); - normalAttribute.setXYZ(i + 0, cb.x, cb.y, cb.z); - normalAttribute.setXYZ(i + 1, cb.x, cb.y, cb.z); - normalAttribute.setXYZ(i + 2, cb.x, cb.y, cb.z); + + for ( let i = 0, il = positionAttribute.count; i < il; i += 3 ) { + + pA.fromBufferAttribute( positionAttribute, i + 0 ); + pB.fromBufferAttribute( positionAttribute, i + 1 ); + pC.fromBufferAttribute( positionAttribute, i + 2 ); + + cb.subVectors( pC, pB ); + ab.subVectors( pA, pB ); + cb.cross( ab ); + + normalAttribute.setXYZ( i + 0, cb.x, cb.y, cb.z ); + normalAttribute.setXYZ( i + 1, cb.x, cb.y, cb.z ); + 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; - } + normalAttribute.needsUpdate = true; - 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); + // @deprecated since r144 - 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; + } normalizeNormals() { + const normals = this.attributes.normal; - for (let i = 0, il = normals.count; i < il; i++) { - _vector$8.fromBufferAttribute(normals, i); + 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); + normals.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z ); + } + } toNonIndexed() { - function convertBufferAttribute(attribute, indices) { + + function convertBufferAttribute( attribute, indices ) { + const array = attribute.array; const itemSize = attribute.itemSize; const normalized = attribute.normalized; - const array2 = new array.constructor(indices.length * itemSize); - let index = 0, - index2 = 0; - for (let i = 0, l = indices.length; i < l; i++) { - if (attribute.isInterleavedBufferAttribute) { - index = indices[i] * attribute.data.stride + attribute.offset; + const array2 = new array.constructor( indices.length * itemSize ); + + let index = 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; + + index = indices[ i ] * itemSize; + } - for (let j = 0; j < itemSize; j++) { - array2[index2++] = array[index++]; + for ( let j = 0; j < itemSize; j ++ ) { + + array2[ index2 ++ ] = array[ index ++ ]; + } + } - return new BufferAttribute(array2, itemSize, normalized); - } // + return new BufferAttribute( array2, itemSize, normalized ); + + } + + // + if ( this.index === null ) { - if (this.index === null) { - console.warn('THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.'); + 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 ); - for (const name in attributes) { - const attribute = attributes[name]; - const newAttribute = convertBufferAttribute(attribute, indices); - geometry2.setAttribute(name, newAttribute); - } // morph attributes + geometry2.setAttribute( name, newAttribute ); + } + + // morph attributes const morphAttributes = this.morphAttributes; - for (const name in morphAttributes) { + for ( const name in morphAttributes ) { + const morphArray = []; - const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes + const morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes + + for ( let i = 0, il = morphAttribute.length; i < il; i ++ ) { + + const attribute = morphAttribute[ i ]; + + const newAttribute = convertBufferAttribute( attribute, indices ); + + morphArray.push( newAttribute ); - for (let i = 0, il = morphAttribute.length; i < il; i++) { - const attribute = morphAttribute[i]; - const newAttribute = convertBufferAttribute(attribute, indices); - morphArray.push(newAttribute); } - geometry2.morphAttributes[name] = morphArray; + geometry2.morphAttributes[ name ] = morphArray; + } - geometry2.morphTargetsRelative = this.morphTargetsRelative; // groups + geometry2.morphTargetsRelative = this.morphTargetsRelative; + + // 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); + 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: { version: 4.5, 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.name !== '' ) data.name = this.name; + if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; + + if ( this.parameters !== undefined ) { - if (this.parameters !== undefined) { const parameters = this.parameters; - for (const key in parameters) { - if (parameters[key] !== undefined) data[key] = parameters[key]; + 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: {} }; - data.data = { - attributes: {} - }; const index = this.index; - if (index !== null) { + if ( index !== null ) { + data.data.index = { type: index.array.constructor.name, - array: Array.prototype.slice.call(index.array) + 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); + 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]; + 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)); + 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; + if ( array.length > 0 ) { + + morphAttributes[ key ] = array; + hasMorphAttributes = true; + } + } - if (hasMorphAttributes) { + 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)); + if ( groups.length > 0 ) { + + data.data.groups = JSON.parse( JSON.stringify( groups ) ); + } const boundingSphere = this.boundingSphere; - if (boundingSphere !== null) { + if ( boundingSphere !== null ) { + data.data.boundingSphere = { center: boundingSphere.center.toArray(), radius: boundingSphere.radius }; + } return data; + } clone() { - return new this.constructor().copy(this); + + return new this.constructor().copy( this ); + } - copy(source) { + 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 = {}; + + // name + + this.name = source.name; + + // index const index = source.index; - if (index !== null) { - this.setIndex(index.clone(data)); - } // attributes + if ( index !== null ) { + this.setIndex( index.clone( data ) ); + + } + + // attributes const attributes = source.attributes; - for (const name in attributes) { - const attribute = attributes[name]; - this.setAttribute(name, attribute.clone(data)); - } // morph attributes + for ( const name in attributes ) { + + const attribute = attributes[ name ]; + this.setAttribute( name, attribute.clone( data ) ); + } + + // morph attributes const morphAttributes = source.morphAttributes; - for (const name in morphAttributes) { + for ( const name in morphAttributes ) { + const array = []; - const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes + const morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes + + for ( let i = 0, l = morphAttribute.length; i < l; i ++ ) { + + array.push( morphAttribute[ i ].clone( data ) ); - for (let i = 0, l = morphAttribute.length; i < l; i++) { - array.push(morphAttribute[i].clone(data)); } - this.morphAttributes[name] = array; + this.morphAttributes[ name ] = array; + } - this.morphTargetsRelative = source.morphTargetsRelative; // groups + this.morphTargetsRelative = source.morphTargetsRelative; + + // 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 + for ( let i = 0, l = groups.length; i < l; i ++ ) { + const group = groups[ i ]; + this.addGroup( group.start, group.count, group.materialIndex ); - const boundingBox = source.boundingBox; + } - if (boundingBox !== null) { - this.boundingBox = boundingBox.clone(); - } // bounding sphere + // bounding box + const boundingBox = source.boundingBox; - const boundingSphere = source.boundingSphere; + if ( boundingBox !== null ) { - if (boundingSphere !== null) { - this.boundingSphere = boundingSphere.clone(); - } // draw range + this.boundingBox = boundingBox.clone(); + } - this.drawRange.start = source.drawRange.start; - this.drawRange.count = source.drawRange.count; // user data + // bounding sphere - this.userData = source.userData; // geometry generator parameters + const boundingSphere = source.boundingSphere; - if (source.parameters !== undefined) this.parameters = Object.assign({}, source.parameters); - return this; - } + if ( boundingSphere !== null ) { - dispose() { - this.dispatchEvent({ - type: 'dispose' - }); - } + this.boundingSphere = boundingSphere.clone(); -} + } -const _inverseMatrix$2 = /*@__PURE__*/new Matrix4(); + // draw range -const _ray$2 = /*@__PURE__*/new Ray(); + this.drawRange.start = source.drawRange.start; + this.drawRange.count = source.drawRange.count; -const _sphere$3 = /*@__PURE__*/new Sphere(); + // user data -const _vA$1 = /*@__PURE__*/new Vector3(); + this.userData = source.userData; -const _vB$1 = /*@__PURE__*/new Vector3(); + // geometry generator parameters -const _vC$1 = /*@__PURE__*/new Vector3(); + if ( source.parameters !== undefined ) this.parameters = Object.assign( {}, source.parameters ); -const _tempA = /*@__PURE__*/new Vector3(); + return this; -const _tempB = /*@__PURE__*/new Vector3(); + } -const _tempC = /*@__PURE__*/new Vector3(); + dispose() { -const _morphA = /*@__PURE__*/new Vector3(); + this.dispatchEvent( { type: 'dispose' } ); -const _morphB = /*@__PURE__*/new Vector3(); + } -const _morphC = /*@__PURE__*/new Vector3(); +} -const _uvA$1 = /*@__PURE__*/new Vector2(); +const _inverseMatrix$2 = /*@__PURE__*/ new Matrix4(); +const _ray$2 = /*@__PURE__*/ new Ray(); +const _sphere$3 = /*@__PURE__*/ new Sphere(); -const _uvB$1 = /*@__PURE__*/new Vector2(); +const _vA$1 = /*@__PURE__*/ new Vector3(); +const _vB$1 = /*@__PURE__*/ new Vector3(); +const _vC$1 = /*@__PURE__*/ new Vector3(); -const _uvC$1 = /*@__PURE__*/new Vector2(); +const _tempA = /*@__PURE__*/ new Vector3(); +const _morphA = /*@__PURE__*/ new Vector3(); -const _intersectionPoint = /*@__PURE__*/new Vector3(); +const _uvA$1 = /*@__PURE__*/ new Vector2(); +const _uvB$1 = /*@__PURE__*/ new Vector2(); +const _uvC$1 = /*@__PURE__*/ new Vector2(); -const _intersectionPointWorld = /*@__PURE__*/new Vector3(); +const _intersectionPoint = /*@__PURE__*/ new Vector3(); +const _intersectionPointWorld = /*@__PURE__*/ new Vector3(); class Mesh extends Object3D { - constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()) { + + constructor( geometry = new BufferGeometry(), material = new MeshBasicMaterial() ) { + super(); + this.isMesh = true; + this.type = 'Mesh'; + this.geometry = geometry; this.material = material; + this.updateMorphTargets(); + } - copy(source, recursive) { - super.copy(source, recursive); + copy( source, recursive ) { + + super.copy( source, recursive ); + + if ( source.morphTargetInfluences !== undefined ) { - if (source.morphTargetInfluences !== undefined) { this.morphTargetInfluences = source.morphTargetInfluences.slice(); + } - if (source.morphTargetDictionary !== undefined) { - this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary); + 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); + const keys = Object.keys( morphAttributes ); + + if ( keys.length > 0 ) { + + const morphAttribute = morphAttributes[ keys[ 0 ] ]; - if (keys.length > 0) { - const morphAttribute = morphAttributes[keys[0]]; + if ( morphAttribute !== undefined ) { - 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); - this.morphTargetDictionary[name] = m; + for ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) { + + const name = morphAttribute[ m ].name || String( m ); + + this.morphTargetInfluences.push( 0 ); + this.morphTargetDictionary[ name ] = m; + + } + + } + + } + + } + + getVertexPosition( index, target ) { + + const geometry = this.geometry; + const position = geometry.attributes.position; + const morphPosition = geometry.morphAttributes.position; + const morphTargetsRelative = geometry.morphTargetsRelative; + + target.fromBufferAttribute( position, index ); + + const morphInfluences = this.morphTargetInfluences; + + if ( morphPosition && morphInfluences ) { + + _morphA.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, index ); + + if ( morphTargetsRelative ) { + + _morphA.addScaledVector( _tempA, influence ); + + } else { + + _morphA.addScaledVector( _tempA.sub( target ), influence ); + } + } + + target.add( _morphA ); + + } + + if ( this.isSkinnedMesh ) { + + this.boneTransform( index, target ); + } + + return target; + } - raycast(raycaster, intersects) { + 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 (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + if ( material === undefined ) return; + + // Checking boundingSphere distance to ray + + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + + _sphere$3.copy( geometry.boundingSphere ); + _sphere$3.applyMatrix4( matrixWorld ); - _sphere$3.copy(geometry.boundingSphere); + if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return; - _sphere$3.applyMatrix4(matrixWorld); + // - if (raycaster.ray.intersectsSphere(_sphere$3) === false) return; // + _inverseMatrix$2.copy( matrixWorld ).invert(); + _ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 ); - _inverseMatrix$2.copy(matrixWorld).invert(); + // Check boundingBox before continuing - _ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2); // Check boundingBox before continuing + if ( geometry.boundingBox !== null ) { + if ( _ray$2.intersectsBox( geometry.boundingBox ) === false ) return; - if (geometry.boundingBox !== null) { - if (_ray$2.intersectsBox(geometry.boundingBox) === false) return; } let intersection; + const index = geometry.index; const position = geometry.attributes.position; - const morphPosition = geometry.morphAttributes.position; - const morphTargetsRelative = geometry.morphTargetsRelative; const uv = geometry.attributes.uv; const uv2 = geometry.attributes.uv2; const groups = geometry.groups; const drawRange = geometry.drawRange; - if (index !== null) { + 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 + 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, 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); + intersects.push( intersection ); + } + } + } + } 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); + 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, uv, uv2, a, b, c ); - if (intersection) { - intersection.faceIndex = Math.floor(i / 3); // triangle number in indexed buffer semantics + if ( intersection ) { + + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics + intersects.push( intersection ); - intersects.push(intersection); } + } + } - } else if (position !== undefined) { + + } 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) { + + 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 = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray$2, 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); + intersects.push( intersection ); + } + } + } + } 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 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 + intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray$2, uv, uv2, a, b, c ); + + if ( intersection ) { + + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics + intersects.push( intersection ); - intersects.push(intersection); } + } + } + } + } } -function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) { +function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) { + let intersect; - if (material.side === BackSide) { - intersect = ray.intersectTriangle(pC, pB, pA, true, point); + if ( material.side === BackSide ) { + + intersect = ray.intersectTriangle( pC, pB, pA, true, point ); + } else { - intersect = ray.intersectTriangle(pA, pB, pC, material.side !== DoubleSide, point); + + intersect = ray.intersectTriangle( pA, pB, pC, ( material.side === FrontSide ), point ); + } - if (intersect === null) return null; + if ( intersect === null ) return null; + + _intersectionPointWorld.copy( point ); + _intersectionPointWorld.applyMatrix4( object.matrixWorld ); - _intersectionPointWorld.copy(point); + const distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld ); - _intersectionPointWorld.applyMatrix4(object.matrixWorld); + if ( distance < raycaster.near || distance > raycaster.far ) return null; - const distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld); - if (distance < raycaster.near || distance > raycaster.far) return null; return { distance: distance, point: _intersectionPointWorld.clone(), 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); +function checkBufferGeometryIntersection( object, material, raycaster, ray, uv, uv2, a, b, c ) { - _vC$1.add(_morphC); - } + object.getVertexPosition( a, _vA$1 ); + object.getVertexPosition( b, _vB$1 ); + object.getVertexPosition( c, _vC$1 ); - 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 ); - const intersection = checkIntersection(object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint); + if ( intersection ) { - if (intersection) { - if (uv) { - _uvA$1.fromBufferAttribute(uv, a); + if ( uv ) { - _uvB$1.fromBufferAttribute(uv, b); + _uvA$1.fromBufferAttribute( uv, a ); + _uvB$1.fromBufferAttribute( uv, b ); + _uvC$1.fromBufferAttribute( uv, c ); - _uvC$1.fromBufferAttribute(uv, c); + intersection.uv = Triangle.getUV( _intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() ); - 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); + if ( uv2 ) { - _uvB$1.fromBufferAttribute(uv2, b); + _uvA$1.fromBufferAttribute( uv2, a ); + _uvB$1.fromBufferAttribute( uv2, b ); + _uvC$1.fromBufferAttribute( uv2, c ); - _uvC$1.fromBufferAttribute(uv2, c); + intersection.uv2 = Triangle.getUV( _intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() ); - intersection.uv2 = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2()); } const face = { @@ -8636,17 +11201,25 @@ function checkBufferGeometryIntersection(object, material, raycaster, ray, posit normal: new Vector3(), materialIndex: 0 }; - Triangle.getNormal(_vA$1, _vB$1, _vC$1, face.normal); + + Triangle.getNormal( _vA$1, _vB$1, _vC$1, face.normal ); + intersection.face = face; + } return intersection; + } class BoxGeometry extends BufferGeometry { - constructor(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) { + + constructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) { + super(); + this.type = 'BoxGeometry'; + this.parameters = { width: width, height: height, @@ -8655,104 +11228,151 @@ class BoxGeometry extends BufferGeometry { heightSegments: heightSegments, depthSegments: depthSegments }; - const scope = this; // segments - widthSegments = Math.floor(widthSegments); - heightSegments = Math.floor(heightSegments); - depthSegments = Math.floor(depthSegments); // buffers + const scope = this; + + // segments + + widthSegments = Math.floor( widthSegments ); + heightSegments = Math.floor( heightSegments ); + depthSegments = Math.floor( depthSegments ); + + // buffers const indices = []; const vertices = []; const normals = []; - const uvs = []; // helper variables - - let numberOfVertices = 0; - let groupStart = 0; // build each side of the box geometry - - buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px + const uvs = []; - buildPlane('z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1); // nx + // helper variables - buildPlane('x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2); // py + let numberOfVertices = 0; + let groupStart = 0; - buildPlane('x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3); // ny + // build each side of the box geometry - buildPlane('x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4); // pz + 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 - 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)); + 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 ) { - function buildPlane(u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex) { const segmentWidth = width / gridX; const segmentHeight = height / gridY; + const widthHalf = width / 2; const heightHalf = height / 2; const depthHalf = depth / 2; + const gridX1 = gridX + 1; const gridY1 = gridY + 1; + let vertexCounter = 0; let groupCount = 0; - const vector = new Vector3(); // generate vertices, normals and uvs - for (let iy = 0; iy < gridY1; iy++) { + 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 + for ( let ix = 0; ix < gridX1; ix ++ ) { + + 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[ u ] = x * udir; + vector[ v ] = y * vdir; + vector[ w ] = depthHalf; - vertices.push(vector.x, vector.y, vector.z); // set values to correct vector component + // now apply vector to vertex buffer - vector[u] = 0; - vector[v] = 0; - vector[w] = depth > 0 ? 1 : -1; // now apply vector to normal buffer + vertices.push( vector.x, vector.y, vector.z ); - normals.push(vector.x, vector.y, vector.z); // uvs + // set values to correct vector component - uvs.push(ix / gridX); - uvs.push(1 - iy / gridY); // counters + vector[ u ] = 0; + vector[ v ] = 0; + vector[ w ] = depth > 0 ? 1 : - 1; + + // now apply vector to normal buffer + + normals.push( vector.x, vector.y, vector.z ); + + // uvs + + uvs.push( ix / gridX ); + 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 ++ ) { - 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 b = numberOfVertices + ix + gridX1 * ( iy + 1 ); + const c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); + const d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; + + // faces - indices.push(a, b, d); - indices.push(b, c, d); // increase counter + indices.push( a, b, d ); + 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); + static fromJSON( data ) { + + return new BoxGeometry( data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments ); + } } @@ -8760,252 +11380,386 @@ class BoxGeometry extends BufferGeometry { /** * Uniform Utilities */ -function cloneUniforms(src) { + +function cloneUniforms( src ) { + const dst = {}; - for (const u in src) { - dst[u] = {}; + for ( const u in src ) { + + dst[ u ] = {}; + + for ( const p in src[ u ] ) { + + const property = src[ u ][ p ]; - 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 ) ) { + + dst[ u ][ p ] = property.slice(); - 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)) { - dst[u][p] = property.slice(); } else { - dst[u][p] = property; + + dst[ u ][ p ] = property; + } + } + } return dst; + } -function mergeUniforms(uniforms) { + +function mergeUniforms( uniforms ) { + const merged = {}; - for (let u = 0; u < uniforms.length; u++) { - const tmp = cloneUniforms(uniforms[u]); + for ( let u = 0; u < uniforms.length; u ++ ) { + + const tmp = cloneUniforms( uniforms[ u ] ); + + for ( const p in tmp ) { + + merged[ p ] = tmp[ p ]; - for (const p in tmp) { - merged[p] = tmp[p]; } + } return merged; -} // Legacy -const UniformsUtils = { - clone: cloneUniforms, - merge: mergeUniforms -}; +} -var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; +function cloneUniformsGroups( src ) { -var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; + const dst = []; -class ShaderMaterial extends Material { - constructor(parameters) { - super(); - this.isShaderMaterial = true; - this.type = 'ShaderMaterial'; - this.defines = {}; - this.uniforms = {}; - this.vertexShader = default_vertex; - this.fragmentShader = default_fragment; - this.linewidth = 1; - this.wireframe = false; + for ( let u = 0; u < src.length; u ++ ) { + + dst.push( src[ u ].clone() ); + + } + + return dst; + +} + +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 }; + +var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; + +var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; + +class ShaderMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isShaderMaterial = true; + + this.type = 'ShaderMaterial'; + + this.defines = {}; + this.uniforms = {}; + this.uniformsGroups = []; + + this.vertexShader = default_vertex; + this.fragmentShader = default_fragment; + + this.linewidth = 1; + + this.wireframe = false; this.wireframeLinewidth = 1; - this.fog = false; // set to use scene fog + 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 = { - derivatives: false, - // set to use derivatives - fragDepth: false, - // set to use fragment depth values - drawBuffers: false, - // set to use draw buffers + derivatives: false, // set to use derivatives + fragDepth: false, // set to use fragment depth values + drawBuffers: false, // set to use draw buffers shaderTextureLOD: false // set to use shader texture LOD + }; - }; // 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], - 'uv2': [0, 0] + 'color': [ 1, 1, 1 ], + 'uv': [ 0, 0 ], + 'uv2': [ 0, 0 ] }; + this.index0AttributeName = undefined; this.uniformsNeedUpdate = false; + this.glslVersion = null; - if (parameters !== undefined) { - if (parameters.attributes !== undefined) { - console.error('THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.'); - } + if ( parameters !== undefined ) { + + this.setValues( parameters ); - this.setValues(parameters); } + } - copy(source) { - super.copy(source); + copy( source ) { + + super.copy( source ); + this.fragmentShader = source.fragmentShader; this.vertexShader = source.vertexShader; - this.uniforms = cloneUniforms(source.uniforms); - this.defines = Object.assign({}, source.defines); + + this.uniforms = cloneUniforms( source.uniforms ); + this.uniformsGroups = cloneUniformsGroups( source.uniformsGroups ); + + this.defines = Object.assign( {}, source.defines ); + this.wireframe = source.wireframe; this.wireframeLinewidth = source.wireframeLinewidth; + this.fog = source.fog; this.lights = source.lights; this.clipping = source.clipping; - this.extensions = Object.assign({}, source.extensions); + + this.extensions = Object.assign( {}, source.extensions ); + this.glslVersion = source.glslVersion; + return this; + } - toJSON(meta) { - const data = super.toJSON(meta); + toJSON( meta ) { + + const data = super.toJSON( meta ); + data.glslVersion = this.glslVersion; data.uniforms = {}; - for (const name in this.uniforms) { - const uniform = this.uniforms[name]; + for ( const name in this.uniforms ) { + + const uniform = this.uniforms[ name ]; const value = uniform.value; - if (value && value.isTexture) { - data.uniforms[name] = { + if ( value && value.isTexture ) { + + data.uniforms[ name ] = { type: 't', - value: value.toJSON(meta).uuid + value: value.toJSON( meta ).uuid }; - } else if (value && value.isColor) { - data.uniforms[name] = { + + } else if ( value && value.isColor ) { + + data.uniforms[ name ] = { type: 'c', value: value.getHex() }; - } else if (value && value.isVector2) { - data.uniforms[name] = { + + } else if ( value && value.isVector2 ) { + + data.uniforms[ name ] = { type: 'v2', value: value.toArray() }; - } else if (value && value.isVector3) { - data.uniforms[name] = { + + } else if ( value && value.isVector3 ) { + + data.uniforms[ name ] = { type: 'v3', value: value.toArray() }; - } else if (value && value.isVector4) { - data.uniforms[name] = { + + } else if ( value && value.isVector4 ) { + + data.uniforms[ name ] = { type: 'v4', value: value.toArray() }; - } else if (value && value.isMatrix3) { - data.uniforms[name] = { + + } else if ( value && value.isMatrix3 ) { + + data.uniforms[ name ] = { type: 'm3', value: value.toArray() }; - } else if (value && value.isMatrix4) { - data.uniforms[name] = { + + } else if ( value && value.isMatrix4 ) { + + data.uniforms[ name ] = { type: 'm4', value: value.toArray() }; + } else { - data.uniforms[name] = { + + 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 + } + } - if (Object.keys(this.defines).length > 0) data.defines = this.defines; + if ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines; + data.vertexShader = this.vertexShader; data.fragmentShader = this.fragmentShader; + const extensions = {}; - for (const key in this.extensions) { - if (this.extensions[key] === true) extensions[key] = true; + for ( const key in this.extensions ) { + + if ( this.extensions[ key ] === true ) extensions[ key ] = true; + } - if (Object.keys(extensions).length > 0) data.extensions = extensions; + if ( Object.keys( extensions ).length > 0 ) data.extensions = extensions; + return data; + } } class Camera extends Object3D { + constructor() { + super(); + this.isCamera = true; + this.type = 'Camera'; + this.matrixWorldInverse = new Matrix4(); + this.projectionMatrix = new Matrix4(); this.projectionMatrixInverse = new Matrix4(); + } - copy(source, recursive) { - super.copy(source, recursive); - this.matrixWorldInverse.copy(source.matrixWorldInverse); - this.projectionMatrix.copy(source.projectionMatrix); - this.projectionMatrixInverse.copy(source.projectionMatrixInverse); + copy( source, recursive ) { + + super.copy( source, recursive ); + + this.matrixWorldInverse.copy( source.matrixWorldInverse ); + + this.projectionMatrix.copy( source.projectionMatrix ); + this.projectionMatrixInverse.copy( source.projectionMatrixInverse ); + return this; + } - getWorldDirection(target) { - this.updateWorldMatrix(true, false); + getWorldDirection( target ) { + + this.updateWorldMatrix( true, false ); + const e = this.matrixWorld.elements; - return target.set(-e[8], -e[9], -e[10]).normalize(); + + return target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize(); + } - updateMatrixWorld(force) { - super.updateMatrixWorld(force); - this.matrixWorldInverse.copy(this.matrixWorld).invert(); + updateMatrixWorld( force ) { + + super.updateMatrixWorld( force ); + + this.matrixWorldInverse.copy( this.matrixWorld ).invert(); + } - updateWorldMatrix(updateParents, updateChildren) { - super.updateWorldMatrix(updateParents, updateChildren); - 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); + + return new this.constructor().copy( this ); + } } class PerspectiveCamera extends Camera { - constructor(fov = 50, aspect = 1, near = 0.1, far = 2000) { + + constructor( fov = 50, aspect = 1, near = 0.1, far = 2000 ) { + super(); + this.isPerspectiveCamera = true; + this.type = 'PerspectiveCamera'; + this.fov = fov; this.zoom = 1; + this.near = near; this.far = far; this.focus = 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.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); + copy( source, recursive ) { + + super.copy( source, recursive ); + this.fov = source.fov; this.zoom = source.zoom; + this.near = source.near; this.far = source.far; this.focus = source.focus; + this.aspect = source.aspect; - this.view = source.view === null ? null : Object.assign({}, source.view); + this.view = source.view === null ? null : Object.assign( {}, source.view ); + this.filmGauge = source.filmGauge; this.filmOffset = source.filmOffset; + return this; + } + /** * Sets the FOV by focal length in respect to the current .filmGauge. * @@ -9014,37 +11768,48 @@ class PerspectiveCamera extends Camera { * * Values for focal length and film gauge must have the same unit. */ + setFocalLength( focalLength ) { - - 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.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 ); - 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); + + 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); + 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); + 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. @@ -9052,40 +11817,40 @@ class PerspectiveCamera extends Camera { * For example, if you have 3x2 monitors and each monitor is 1920x1080 and * the monitors are in grid like this * - * +---+---+---+ - * | A | B | C | - * +---+---+---+ - * | D | E | F | - * +---+---+---+ + * +---+---+---+ + * | A | B | C | + * +---+---+---+ + * | D | E | F | + * +---+---+---+ * * then for each monitor you would call it like this * - * const w = 1920; - * const h = 1080; - * const fullWidth = w * 3; - * const fullHeight = h * 2; + * 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 ); + * --A-- + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); + * --B-- + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); + * --C-- + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); + * --D-- + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); + * --E-- + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); + * --F-- + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); * - * Note there is no reason monitors have to be the same size or in a grid. + * Note there is no reason monitors have to be the same size or in a grid. */ + setViewOffset( fullWidth, fullHeight, x, y, width, height ) { - - setViewOffset(fullWidth, fullHeight, x, y, width, height) { this.aspect = fullWidth / fullHeight; - if (this.view === null) { + if ( this.view === null ) { + this.view = { enabled: true, fullWidth: 1, @@ -9095,6 +11860,7 @@ class PerspectiveCamera extends Camera { width: 1, height: 1 }; + } this.view.enabled = true; @@ -9104,190 +11870,252 @@ class PerspectiveCamera extends Camera { this.view.offsetY = y; this.view.width = width; this.view.height = height; + this.updateProjectionMatrix(); + } clearViewOffset() { - if (this.view !== null) { + + 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; + let top = near * Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom; let height = 2 * top; let width = this.aspect * height; - let left = -0.5 * width; + let left = - 0.5 * width; const view = this.view; - if (this.view !== null && this.view.enabled) { + 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(); + 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); + toJSON( meta ) { + + const data = super.toJSON( meta ); + data.object.fov = this.fov; data.object.zoom = this.zoom; + data.object.near = this.near; data.object.far = this.far; data.object.focus = this.focus; + data.object.aspect = this.aspect; - if (this.view !== null) data.object.view = Object.assign({}, this.view); + + if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); + data.object.filmGauge = this.filmGauge; 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) { + + 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.type = 'CubeCamera'; this.renderTarget = renderTarget; - const cameraPX = new PerspectiveCamera(fov, aspect, near, far); + + 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)); - this.add(cameraPX); - const cameraNX = new PerspectiveCamera(fov, aspect, near, far); + 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)); - this.add(cameraNX); - const cameraPY = new PerspectiveCamera(fov, aspect, near, far); + 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)); - this.add(cameraPY); - const cameraNY = new PerspectiveCamera(fov, aspect, near, far); + 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)); - this.add(cameraNY); - const cameraPZ = new PerspectiveCamera(fov, aspect, near, far); + 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)); - this.add(cameraPZ); - const cameraNZ = new PerspectiveCamera(fov, aspect, near, far); + 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)); - this.add(cameraNZ); + cameraNZ.up.set( 0, 1, 0 ); + cameraNZ.lookAt( 0, 0, - 1 ); + this.add( cameraNZ ); + } - update(renderer, scene) { - if (this.parent === null) this.updateMatrixWorld(); + update( renderer, scene ) { + + if ( this.parent === null ) this.updateMatrixWorld(); + const renderTarget = this.renderTarget; - const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = this.children; + + const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = this.children; + const currentRenderTarget = renderer.getRenderTarget(); + const currentToneMapping = renderer.toneMapping; const currentXrEnabled = renderer.xr.enabled; + renderer.toneMapping = NoToneMapping; renderer.xr.enabled = false; + const generateMipmaps = renderTarget.texture.generateMipmaps; + renderTarget.texture.generateMipmaps = false; - renderer.setRenderTarget(renderTarget, 0); - renderer.render(scene, cameraPX); - renderer.setRenderTarget(renderTarget, 1); - renderer.render(scene, cameraNX); - renderer.setRenderTarget(renderTarget, 2); - renderer.render(scene, cameraPY); - renderer.setRenderTarget(renderTarget, 3); - renderer.render(scene, cameraNY); - renderer.setRenderTarget(renderTarget, 4); - renderer.render(scene, cameraPZ); + + renderer.setRenderTarget( renderTarget, 0 ); + renderer.render( scene, cameraPX ); + + renderer.setRenderTarget( renderTarget, 1 ); + renderer.render( scene, cameraNX ); + + renderer.setRenderTarget( renderTarget, 2 ); + renderer.render( scene, cameraPY ); + + renderer.setRenderTarget( renderTarget, 3 ); + renderer.render( scene, cameraNY ); + + renderer.setRenderTarget( renderTarget, 4 ); + renderer.render( scene, cameraPZ ); + renderTarget.texture.generateMipmaps = generateMipmaps; - renderer.setRenderTarget(renderTarget, 5); - renderer.render(scene, cameraNZ); - renderer.setRenderTarget(currentRenderTarget); + + renderer.setRenderTarget( renderTarget, 5 ); + renderer.render( scene, cameraNZ ); + + renderer.setRenderTarget( currentRenderTarget ); + renderer.toneMapping = currentToneMapping; renderer.xr.enabled = currentXrEnabled; + renderTarget.texture.needsPMREMUpdate = true; + } } class CubeTexture extends Texture { - constructor(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding) { + + constructor( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { + images = images !== undefined ? images : []; mapping = mapping !== undefined ? mapping : CubeReflectionMapping; - super(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); + + super( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); + this.isCubeTexture = true; + this.flipY = false; + } get images() { + return this.image; + } - set images(value) { + set images( value ) { + this.image = value; + } } class WebGLCubeRenderTarget extends WebGLRenderTarget { - constructor(size, options = {}) { - super(size, size, options); + + constructor( size = 1, options = {} ) { + + super( size, size, options ); + this.isWebGLCubeRenderTarget = true; - const image = { - width: size, - height: size, - 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) + + const image = { width: size, height: size, 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) // 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). this.texture.isRenderTargetTexture = true; + this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; + } - fromEquirectangularTexture(renderer, texture) { + fromEquirectangularTexture( renderer, texture ) { + this.texture.type = texture.type; this.texture.encoding = texture.encoding; + this.texture.generateMipmaps = texture.generateMipmaps; this.texture.minFilter = texture.minFilter; this.texture.magFilter = texture.magFilter; + const shader = { + uniforms: { - tEquirect: { - value: null - } + tEquirect: { value: null }, }, - vertexShader: - /* glsl */ - ` + + vertexShader: /* glsl */` varying vec3 vWorldDirection; @@ -9306,9 +12134,8 @@ class WebGLCubeRenderTarget extends WebGLRenderTarget { } `, - fragmentShader: - /* glsl */ - ` + + fragmentShader: /* glsl */` uniform sampler2D tEquirect; @@ -9327,378 +12154,541 @@ class WebGLCubeRenderTarget extends WebGLRenderTarget { } ` }; - const geometry = new BoxGeometry(5, 5, 5); - const material = new ShaderMaterial({ + + const geometry = new BoxGeometry( 5, 5, 5 ); + + const material = new ShaderMaterial( { + name: 'CubemapFromEquirect', - uniforms: cloneUniforms(shader.uniforms), + + uniforms: cloneUniforms( shader.uniforms ), vertexShader: shader.vertexShader, fragmentShader: shader.fragmentShader, side: BackSide, blending: NoBlending - }); + + } ); + material.uniforms.tEquirect.value = texture; - const mesh = new Mesh(geometry, material); - 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); + const mesh = new Mesh( geometry, material ); + + 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 ); + texture.minFilter = currentMinFilter; + mesh.geometry.dispose(); mesh.material.dispose(); + return this; + } - clear(renderer, color, depth, stencil) { + 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); + for ( let i = 0; i < 6; i ++ ) { + + renderer.setRenderTarget( this, i ); + + renderer.clear( color, depth, stencil ); + } - renderer.setRenderTarget(currentRenderTarget); + renderer.setRenderTarget( currentRenderTarget ); + } } -const _vector1 = /*@__PURE__*/new Vector3(); +const _vector1 = /*@__PURE__*/ new Vector3(); +const _vector2 = /*@__PURE__*/ new Vector3(); +const _normalMatrix = /*@__PURE__*/ new Matrix3(); + +class Plane { -const _vector2 = /*@__PURE__*/new Vector3(); + constructor( normal = new Vector3( 1, 0, 0 ), constant = 0 ) { -const _normalMatrix = /*@__PURE__*/new Matrix3(); + this.isPlane = true; -class Plane { - constructor(normal = new Vector3(1, 0, 0), constant = 0) { - this.isPlane = true; // normal is assumed to be normalized + // normal is assumed to be normalized this.normal = normal; this.constant = constant; + } - set(normal, constant) { - this.normal.copy(normal); + set( normal, constant ) { + + this.normal.copy( normal ); this.constant = constant; + return this; + } - setComponents(x, y, z, w) { - this.normal.set(x, y, z); + 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)? + setFromNormalAndCoplanarPoint( normal, point ) { + this.normal.copy( normal ); + this.constant = - point.dot( this.normal ); - this.setFromNormalAndCoplanarPoint(normal, a); 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)? + + this.setFromNormalAndCoplanarPoint( normal, a ); + + return this; + } - copy(plane) { - this.normal.copy(plane.normal); + 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.normal.multiplyScalar( inverseNormalLength ); this.constant *= inverseNormalLength; + return this; + } negate() { - this.constant *= -1; + + this.constant *= - 1; this.normal.negate(); + return this; + } - distanceToPoint(point) { - return this.normal.dot(point) + this.constant; + distanceToPoint( point ) { + + return this.normal.dot( point ) + this.constant; + } - distanceToSphere(sphere) { - return this.distanceToPoint(sphere.center) - sphere.radius; + distanceToSphere( sphere ) { + + return this.distanceToPoint( sphere.center ) - sphere.radius; + } - projectPoint(point, target) { - return target.copy(this.normal).multiplyScalar(-this.distanceToPoint(point)).add(point); + 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); + intersectLine( line, target ) { + + const direction = line.delta( _vector1 ); + + const denominator = this.normal.dot( direction ); + + if ( denominator === 0 ) { - 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. + if ( this.distanceToPoint( line.start ) === 0 ) { + return target.copy( line.start ); + } + + // Unsure if this is the correct method to handle this case. return null; + } - const t = -(line.start.dot(this.normal) + this.constant) / denominator; + const t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; + + if ( t < 0 || t > 1 ) { - if (t < 0 || t > 1) { return null; + } - return target.copy(direction).multiplyScalar(t).add(line.start); + return target.copy( direction ).multiplyScalar( t ).add( line.start ); + } - intersectsLine(line) { + 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; + + 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); + intersectsBox( box ) { + + return box.intersectsPlane( this ); + } - intersectsSphere(sphere) { - return sphere.intersectsPlane(this); + intersectsSphere( sphere ) { + + return sphere.intersectsPlane( this ); + } - coplanarPoint(target) { - return target.copy(this.normal).multiplyScalar(-this.constant); + coplanarPoint( target ) { + + return target.copy( this.normal ).multiplyScalar( - this.constant ); + } - applyMatrix4(matrix, optionalNormalMatrix) { - const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix); + 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 ); - 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); + translate( offset ) { + + this.constant -= offset.dot( this.normal ); + return this; + } - equals(plane) { - return plane.normal.equals(this.normal) && plane.constant === this.constant; + equals( plane ) { + + return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); + } clone() { - return new this.constructor().copy(this); + + return new this.constructor().copy( this ); + } } -const _sphere$2 = /*@__PURE__*/new Sphere(); - -const _vector$7 = /*@__PURE__*/new Vector3(); +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]; + + 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) { + set( p0, p1, p2, p3, p4, p5 ) { + const planes = this.planes; - planes[0].copy(p0); - planes[1].copy(p1); - planes[2].copy(p2); - planes[3].copy(p3); - planes[4].copy(p4); - planes[5].copy(p5); + + planes[ 0 ].copy( p0 ); + planes[ 1 ].copy( p1 ); + planes[ 2 ].copy( p2 ); + planes[ 3 ].copy( p3 ); + planes[ 4 ].copy( p4 ); + planes[ 5 ].copy( p5 ); + return this; + } - copy(frustum) { + copy( frustum ) { + const planes = this.planes; - for (let i = 0; i < 6; i++) { - planes[i].copy(frustum.planes[i]); + for ( let i = 0; i < 6; i ++ ) { + + planes[ i ].copy( frustum.planes[ i ] ); + } return this; + } - setFromProjectionMatrix(m) { + setFromProjectionMatrix( m ) { + const planes = this.planes; const me = m.elements; - const me0 = me[0], - me1 = me[1], - me2 = me[2], - me3 = me[3]; - const me4 = me[4], - me5 = me[5], - me6 = me[6], - me7 = me[7]; - const me8 = me[8], - me9 = me[9], - me10 = me[10], - me11 = me[11]; - const me12 = me[12], - me13 = me[13], - me14 = me[14], - me15 = me[15]; - planes[0].setComponents(me3 - me0, me7 - me4, me11 - me8, me15 - me12).normalize(); - planes[1].setComponents(me3 + me0, me7 + me4, me11 + me8, me15 + me12).normalize(); - planes[2].setComponents(me3 + me1, me7 + me5, me11 + me9, me15 + me13).normalize(); - planes[3].setComponents(me3 - me1, me7 - me5, me11 - me9, me15 - me13).normalize(); - planes[4].setComponents(me3 - me2, me7 - me6, me11 - me10, me15 - me14).normalize(); - planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize(); - return this; - } - - intersectsObject(object) { + const me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ]; + const me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ]; + const me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ]; + const me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ]; + + planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize(); + planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize(); + planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize(); + planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize(); + planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize(); + planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize(); + + return this; + + } + + intersectsObject( object ) { + const geometry = object.geometry; - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); - _sphere$2.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld); + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + + _sphere$2.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld ); + + return this.intersectsSphere( _sphere$2 ); - return this.intersectsSphere(_sphere$2); } - intersectsSprite(sprite) { - _sphere$2.center.set(0, 0, 0); + intersectsSprite( sprite ) { + _sphere$2.center.set( 0, 0, 0 ); _sphere$2.radius = 0.7071067811865476; + _sphere$2.applyMatrix4( sprite.matrixWorld ); - _sphere$2.applyMatrix4(sprite.matrixWorld); + return this.intersectsSphere( _sphere$2 ); - return this.intersectsSphere(_sphere$2); } - intersectsSphere(sphere) { + intersectsSphere( sphere ) { + const planes = this.planes; const center = sphere.center; - const negRadius = -sphere.radius; + const negRadius = - sphere.radius; + + for ( let i = 0; i < 6; i ++ ) { - for (let i = 0; i < 6; i++) { - const distance = planes[i].distanceToPoint(center); + const distance = planes[ i ].distanceToPoint( center ); + + if ( distance < negRadius ) { - if (distance < negRadius) { return false; + } + } return true; + } - intersectsBox(box) { + intersectsBox( box ) { + const planes = this.planes; - for (let i = 0; i < 6; i++) { - const plane = planes[i]; // corner at max distance + for ( let i = 0; i < 6; i ++ ) { + + 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) { + if ( plane.distanceToPoint( _vector$7 ) < 0 ) { + return false; + } + } return true; + } - containsPoint(point) { + containsPoint( point ) { + const planes = this.planes; - for (let i = 0; i < 6; i++) { - if (planes[i].distanceToPoint(point) < 0) { + for ( let i = 0; i < 6; i ++ ) { + + if ( planes[ i ].distanceToPoint( point ) < 0 ) { + return false; + } + } return true; + } clone() { - return new this.constructor().copy(this); + + return new this.constructor().copy( this ); + } } function WebGLAnimation() { + let context = null; let isAnimating = false; let animationLoop = null; let requestId = null; - function onAnimationFrame(time, frame) { - animationLoop(time, frame); - requestId = context.requestAnimationFrame(onAnimationFrame); + function onAnimationFrame( time, frame ) { + + animationLoop( time, frame ); + + requestId = context.requestAnimationFrame( onAnimationFrame ); + } return { + start: function () { - if (isAnimating === true) return; - if (animationLoop === null) return; - requestId = context.requestAnimationFrame(onAnimationFrame); + + if ( isAnimating === true ) return; + if ( animationLoop === null ) return; + + requestId = context.requestAnimationFrame( onAnimationFrame ); + isAnimating = true; + }, + stop: function () { - context.cancelAnimationFrame(requestId); + + context.cancelAnimationFrame( requestId ); + isAnimating = false; + }, - setAnimationLoop: function (callback) { + + setAnimationLoop: function ( callback ) { + animationLoop = callback; + }, - setContext: function (value) { + + setContext: function ( value ) { + context = value; + } + }; + } -function WebGLAttributes(gl, capabilities) { +function WebGLAttributes( gl, capabilities ) { + const isWebGL2 = capabilities.isWebGL2; + const buffers = new WeakMap(); - function createBuffer(attribute, bufferType) { + function createBuffer( attribute, bufferType ) { + const array = attribute.array; const usage = attribute.usage; + const buffer = gl.createBuffer(); - gl.bindBuffer(bufferType, buffer); - gl.bufferData(bufferType, array, usage); + + gl.bindBuffer( bufferType, buffer ); + gl.bufferData( bufferType, array, usage ); + attribute.onUploadCallback(); + let type; - if (array instanceof Float32Array) { + if ( array instanceof Float32Array ) { + type = gl.FLOAT; - } else if (array instanceof Uint16Array) { - if (attribute.isFloat16BufferAttribute) { - if (isWebGL2) { + + } else if ( array instanceof Uint16Array ) { + + if ( attribute.isFloat16BufferAttribute ) { + + if ( isWebGL2 ) { + type = gl.HALF_FLOAT; + } else { - throw new Error('THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2.'); + + throw new Error( 'THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2.' ); + } + } else { + type = gl.UNSIGNED_SHORT; + } - } else if (array instanceof Int16Array) { + + } else if ( array instanceof Int16Array ) { + type = gl.SHORT; - } else if (array instanceof Uint32Array) { + + } else if ( array instanceof Uint32Array ) { + type = gl.UNSIGNED_INT; - } else if (array instanceof Int32Array) { + + } else if ( array instanceof Int32Array ) { + type = gl.INT; - } else if (array instanceof Int8Array) { + + } else if ( array instanceof Int8Array ) { + type = gl.BYTE; - } else if (array instanceof Uint8Array) { + + } else if ( array instanceof Uint8Array ) { + type = gl.UNSIGNED_BYTE; - } else if (array instanceof Uint8ClampedArray) { + + } else if ( array instanceof Uint8ClampedArray ) { + type = gl.UNSIGNED_BYTE; + } else { - throw new Error('THREE.WebGLAttributes: Unsupported buffer data format: ' + array); + + throw new Error( 'THREE.WebGLAttributes: Unsupported buffer data format: ' + array ); + } return { @@ -9707,132 +12697,199 @@ function WebGLAttributes(gl, capabilities) { bytesPerElement: array.BYTES_PER_ELEMENT, version: attribute.version }; + } - function updateBuffer(buffer, attribute, bufferType) { + function updateBuffer( buffer, attribute, bufferType ) { + const array = attribute.array; const updateRange = attribute.updateRange; - gl.bindBuffer(bufferType, buffer); - if (updateRange.count === -1) { + gl.bindBuffer( bufferType, buffer ); + + if ( updateRange.count === - 1 ) { + // Not using update ranges - gl.bufferSubData(bufferType, 0, array); + + gl.bufferSubData( bufferType, 0, array ); + } else { - if (isWebGL2) { - gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array, updateRange.offset, updateRange.count); + + if ( isWebGL2 ) { + + gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, + array, updateRange.offset, updateRange.count ); + } else { - gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array.subarray(updateRange.offset, updateRange.offset + updateRange.count)); + + gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, + array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); + } - updateRange.count = -1; // reset range + updateRange.count = - 1; // reset range + } - } // + attribute.onUploadCallback(); + + } + + // + + function get( attribute ) { + + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + + return buffers.get( attribute ); - 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); + function remove( attribute ) { + + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + + const data = buffers.get( attribute ); + + if ( data ) { + + gl.deleteBuffer( data.buffer ); + + buffers.delete( attribute ); - if (data) { - gl.deleteBuffer(data.buffer); - buffers.delete(attribute); } + } - function update(attribute, bufferType) { - if (attribute.isGLBufferAttribute) { - const cached = buffers.get(attribute); + function update( attribute, bufferType ) { + + if ( attribute.isGLBufferAttribute ) { + + const cached = buffers.get( attribute ); - if (!cached || cached.version < attribute.version) { - buffers.set(attribute, { + if ( ! cached || cached.version < attribute.version ) { + + buffers.set( attribute, { buffer: attribute.buffer, type: attribute.type, bytesPerElement: attribute.elementSize, version: attribute.version - }); + } ); + } return; + } - if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; - const data = buffers.get(attribute); + 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 ) { + + updateBuffer( data.buffer, attribute, bufferType ); - if (data === undefined) { - buffers.set(attribute, createBuffer(attribute, bufferType)); - } else if (data.version < attribute.version) { - updateBuffer(data.buffer, attribute, bufferType); data.version = attribute.version; + } + } return { + get: get, remove: remove, update: update + }; + } class PlaneGeometry extends BufferGeometry { - constructor(width = 1, height = 1, widthSegments = 1, heightSegments = 1) { + + constructor( width = 1, height = 1, widthSegments = 1, heightSegments = 1 ) { + super(); + this.type = 'PlaneGeometry'; + this.parameters = { width: width, height: height, widthSegments: widthSegments, heightSegments: heightSegments }; + const width_half = width / 2; const height_half = height / 2; - const gridX = Math.floor(widthSegments); - const gridY = Math.floor(heightSegments); + + const gridX = Math.floor( widthSegments ); + const gridY = Math.floor( heightSegments ); + 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++) { + for ( let iy = 0; iy < gridY1; iy ++ ) { + const y = iy * segment_height - height_half; - for (let ix = 0; ix < gridX1; ix++) { + for ( let ix = 0; ix < gridX1; ix ++ ) { + const x = ix * segment_width - width_half; - vertices.push(x, -y, 0); - normals.push(0, 0, 1); - uvs.push(ix / gridX); - uvs.push(1 - iy / gridY); + + vertices.push( x, - y, 0 ); + + normals.push( 0, 0, 1 ); + + uvs.push( ix / gridX ); + uvs.push( 1 - ( iy / gridY ) ); + } + } - for (let iy = 0; iy < gridY; iy++) { - for (let ix = 0; ix < gridX; ix++) { + for ( let iy = 0; iy < gridY; iy ++ ) { + + for ( let ix = 0; ix < gridX; ix ++ ) { + const a = ix + gridX1 * iy; - const b = ix + gridX1 * (iy + 1); - const c = ix + 1 + gridX1 * (iy + 1); - const d = ix + 1 + gridX1 * iy; - indices.push(a, b, d); - indices.push(b, c, d); + const b = ix + gridX1 * ( iy + 1 ); + const c = ( ix + 1 ) + gridX1 * ( iy + 1 ); + const d = ( ix + 1 ) + gridX1 * iy; + + indices.push( a, b, d ); + 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)); + 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); + static fromJSON( data ) { + + return new PlaneGeometry( data.width, data.height, data.widthSegments, data.heightSegments ); + } } @@ -9853,11 +12910,11 @@ var begin_vertex = "vec3 transformed = vec3( position );"; var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; -var bsdfs = "vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\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 dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( V * D );\n}\n#ifdef USE_IRIDESCENCE\nvec3 BRDF_GGX_Iridescence( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float iridescence, const in vec3 iridescenceFresnel, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\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 dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = mix(F_Schlick( f0, f90, dotVH ), iridescenceFresnel, iridescence);\n\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( V * D );\n}\n#endif\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\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"; +var bsdfs = "vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\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 dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( V * D );\n}\n#ifdef USE_IRIDESCENCE\n\tvec3 BRDF_GGX_Iridescence( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float iridescence, const in vec3 iridescenceFresnel, const in float roughness ) {\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = mix( F_Schlick( f0, f90, dotVH ), iridescenceFresnel, iridescence );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\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"; -var iridescence_fragment = "#ifdef USE_IRIDESCENCE\nconst mat3 XYZ_TO_REC709 = mat3(\n 3.2404542, -0.9692660, 0.0556434,\n -1.5371385, 1.8760108, -0.2040259,\n -0.4985314, 0.0415560, 1.0572252\n);\nvec3 Fresnel0ToIor( vec3 fresnel0 ) {\n vec3 sqrtF0 = sqrt( fresnel0 );\n return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n}\nvec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n return pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n}\nfloat IorToFresnel0( float transmittedIor, float incidentIor ) {\n return pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n}\nvec3 evalSensitivity( float OPD, vec3 shift ) {\n float phase = 2.0 * PI * OPD * 1.0e-9;\n vec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n vec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n vec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n vec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( -pow2( phase ) * var );\n xyz.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 xyz /= 1.0685e-7;\n vec3 srgb = XYZ_TO_REC709 * xyz;\n return srgb;\n}\nvec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n vec3 I;\n float iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n float sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n float cosTheta2Sq = 1.0 - sinTheta2Sq;\n if ( cosTheta2Sq < 0.0 ) {\n return vec3( 1.0 );\n }\n float cosTheta2 = sqrt( cosTheta2Sq );\n float R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\n float R12 = F_Schlick( R0, 1.0, cosTheta1 );\n float R21 = R12;\n float T121 = 1.0 - R12;\n float phi12 = 0.0;\n if ( iridescenceIOR < outsideIOR ) phi12 = PI;\n float phi21 = PI - phi12;\n vec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) ); vec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n vec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n vec3 phi23 = vec3( 0.0 );\n if ( baseIOR[0] < iridescenceIOR ) phi23[0] = PI;\n if ( baseIOR[1] < iridescenceIOR ) phi23[1] = PI;\n if ( baseIOR[2] < iridescenceIOR ) phi23[2] = PI;\n float OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n vec3 phi = vec3( phi21 ) + phi23;\n vec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n vec3 r123 = sqrt( R123 );\n vec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n vec3 C0 = R12 + Rs;\n I = C0;\n vec3 Cm = Rs - T121;\n for ( int m = 1; m <= 2; ++m ) {\n Cm *= r123;\n vec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n I += Cm * Sm;\n }\n return max( I, vec3( 0.0 ) );\n}\n#endif"; +var iridescence_fragment = "#ifdef USE_IRIDESCENCE\n\tconst mat3 XYZ_TO_REC709 = mat3(\n\t\t 3.2404542, -0.9692660, 0.0556434,\n\t\t-1.5371385, 1.8760108, -0.2040259,\n\t\t-0.4985314, 0.0415560, 1.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"; -var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 ) * 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"; +var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, 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"; var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; @@ -9875,9 +12932,9 @@ var color_pars_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\ var 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"; -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 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat 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 linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}"; +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\thighp vec2 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"; @@ -9893,13 +12950,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"; @@ -9911,13 +12968,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"; @@ -9925,17 +12984,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\nfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\nif ( material.iridescenceThickness == 0.0 ) {\n\tmaterial.iridescence = 0.0;\n} else {\n\tmaterial.iridescence = saturate( material.iridescence );\n}\nif ( material.iridescence > 0.0 ) {\n\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n}\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 *= ( 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 *= ( 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 *= ( 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 ) || defined( ENVMAP_TYPE_CUBE ) )\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"; @@ -9969,7 +13028,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"; @@ -9979,7 +13038,7 @@ var normal_pars_vertex = "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef var 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"; -var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN, float faceDirection ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\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"; +var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN, 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"; var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif"; @@ -9989,9 +13048,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"; @@ -10005,13 +13064,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\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\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_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\tvec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#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#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"; @@ -10027,11 +13086,11 @@ var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D spe var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; -var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }"; +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"; @@ -10045,54 +13104,78 @@ 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$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 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 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}"; const vertex$d = "#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}"; + const fragment$d = "#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}"; const vertex$c = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}"; + const fragment$c = "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}"; const vertex$b = "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}"; + 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 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 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 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}"; const vertex$7 = "#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}"; + 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}"; +<<<<<<< HEAD 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\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}"; +======= + +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}"; +>>>>>>> mrdoob-dev const vertex$4 = "#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}"; + const fragment$4 = "#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}"; const vertex$3 = "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}"; + const fragment$3 = "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}"; const vertex$2 = "#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}"; + const fragment$2 = "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}"; const vertex$1 = "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}"; + const fragment$1 = "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}"; const ShaderChunk = { @@ -10137,7 +13220,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, @@ -10201,8 +13285,11 @@ 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, @@ -10240,1435 +13327,1882 @@ const ShaderChunk = { */ const UniformsLib = { + common: { - diffuse: { - value: new Color(0xffffff) - }, - opacity: { - value: 1.0 - }, - map: { - value: null - }, - uvTransform: { - value: new Matrix3() - }, - uv2Transform: { - value: new Matrix3() - }, - alphaMap: { - value: null - }, - alphaTest: { - value: 0 - } + + diffuse: { value: /*@__PURE__*/ new Color( 0xffffff ) }, + opacity: { value: 1.0 }, + + map: { value: null }, + uvTransform: { value: /*@__PURE__*/ new Matrix3() }, + uv2Transform: { value: /*@__PURE__*/ new Matrix3() }, + + alphaMap: { value: null }, + alphaTest: { value: 0 } + }, + specularmap: { - specularMap: { - value: null - } + + specularMap: { value: null }, + }, + envmap: { - envMap: { - value: null - }, - flipEnvMap: { - value: -1 - }, - reflectivity: { - value: 1.0 - }, - // basic, lambert, phong - ior: { - value: 1.5 - }, - // physical - refractionRatio: { - value: 0.98 - } // basic, lambert, phong + + envMap: { value: null }, + flipEnvMap: { value: - 1 }, + reflectivity: { value: 1.0 }, // basic, lambert, phong + ior: { value: 1.5 }, // physical + refractionRatio: { value: 0.98 }, // basic, lambert, phong }, + aomap: { - aoMap: { - value: null - }, - aoMapIntensity: { - value: 1 - } + + aoMap: { value: null }, + aoMapIntensity: { value: 1 } + }, + lightmap: { - lightMap: { - value: null - }, - lightMapIntensity: { - value: 1 - } + + lightMap: { value: null }, + lightMapIntensity: { value: 1 } + }, + emissivemap: { - emissiveMap: { - value: null - } + + emissiveMap: { value: null } + }, + bumpmap: { - bumpMap: { - value: null - }, - bumpScale: { - value: 1 - } + + bumpMap: { value: null }, + bumpScale: { value: 1 } + }, + normalmap: { - normalMap: { - value: null - }, - normalScale: { - value: new Vector2(1, 1) - } + + normalMap: { value: null }, + normalScale: { value: /*@__PURE__*/ new Vector2( 1, 1 ) } + }, + displacementmap: { - displacementMap: { - value: null - }, - displacementScale: { - value: 1 - }, - displacementBias: { - value: 0 - } + + displacementMap: { value: null }, + displacementScale: { value: 1 }, + displacementBias: { value: 0 } + }, + roughnessmap: { - roughnessMap: { - value: null - } + + roughnessMap: { value: null } + }, + metalnessmap: { - metalnessMap: { - value: null - } + + metalnessMap: { value: null } + }, + gradientmap: { - gradientMap: { - value: null - } + + gradientMap: { value: null } + }, + fog: { - fogDensity: { - value: 0.00025 - }, - fogNear: { - value: 1 - }, - fogFar: { - value: 2000 - }, - fogColor: { - value: new Color(0xffffff) - } + + fogDensity: { value: 0.00025 }, + fogNear: { value: 1 }, + fogFar: { value: 2000 }, + fogColor: { value: /*@__PURE__*/ new Color( 0xffffff ) } + }, + lights: { - ambientLightColor: { - value: [] - }, - lightProbe: { - value: [] - }, - directionalLights: { - value: [], - properties: { - direction: {}, - color: {} - } - }, - directionalLightShadows: { - value: [], - properties: { - shadowBias: {}, - shadowNormalBias: {}, - shadowRadius: {}, - shadowMapSize: {} - } - }, - directionalShadowMap: { - value: [] - }, - directionalShadowMatrix: { - value: [] - }, - spotLights: { - value: [], - properties: { - color: {}, - position: {}, - direction: {}, - distance: {}, - coneCos: {}, - penumbraCos: {}, - decay: {} - } - }, - spotLightShadows: { - value: [], - properties: { - shadowBias: {}, - shadowNormalBias: {}, - shadowRadius: {}, - shadowMapSize: {} - } - }, - spotShadowMap: { - value: [] - }, - spotShadowMatrix: { - value: [] - }, - pointLights: { - value: [], - properties: { - color: {}, - position: {}, - decay: {}, - distance: {} - } - }, - pointLightShadows: { - value: [], - properties: { - shadowBias: {}, - shadowNormalBias: {}, - shadowRadius: {}, - shadowMapSize: {}, - shadowCameraNear: {}, - shadowCameraFar: {} - } - }, - pointShadowMap: { - value: [] - }, - pointShadowMatrix: { - value: [] - }, - hemisphereLights: { - value: [], - properties: { - direction: {}, - skyColor: {}, - groundColor: {} - } - }, + + 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: {} + } }, + // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src - rectAreaLights: { - value: [], - properties: { - color: {}, - position: {}, - width: {}, - height: {} - } - }, - ltc_1: { - value: null - }, - ltc_2: { - value: null - } + rectAreaLights: { value: [], properties: { + color: {}, + position: {}, + width: {}, + height: {} + } }, + + ltc_1: { value: null }, + ltc_2: { value: null } + }, + points: { - diffuse: { - value: new Color(0xffffff) - }, - opacity: { - value: 1.0 - }, - size: { - value: 1.0 - }, - scale: { - value: 1.0 - }, - map: { - value: null - }, - alphaMap: { - value: null - }, - alphaTest: { - value: 0 - }, - uvTransform: { - value: new Matrix3() - } + + diffuse: { value: /*@__PURE__*/ new Color( 0xffffff ) }, + opacity: { value: 1.0 }, + size: { value: 1.0 }, + scale: { value: 1.0 }, + map: { value: null }, + alphaMap: { value: null }, + alphaTest: { value: 0 }, + uvTransform: { value: /*@__PURE__*/ new Matrix3() } + }, + sprite: { - diffuse: { - value: new Color(0xffffff) - }, - opacity: { - value: 1.0 - }, - center: { - value: new Vector2(0.5, 0.5) - }, - rotation: { - value: 0.0 - }, - map: { - value: null - }, - alphaMap: { - value: null - }, - alphaTest: { - value: 0 - }, - uvTransform: { - value: new Matrix3() - } + + diffuse: { value: /*@__PURE__*/ new Color( 0xffffff ) }, + opacity: { value: 1.0 }, + center: { value: /*@__PURE__*/ new Vector2( 0.5, 0.5 ) }, + rotation: { value: 0.0 }, + map: { value: null }, + alphaMap: { value: null }, + alphaTest: { value: 0 }, + uvTransform: { value: /*@__PURE__*/ new Matrix3() } + } + }; const ShaderLib = { + basic: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.fog]), + + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.fog + ] ), + vertexShader: ShaderChunk.meshbasic_vert, fragmentShader: ShaderChunk.meshbasic_frag + }, + lambert: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.fog, UniformsLib.lights, { - emissive: { - value: new Color(0x000000) - } - }]), + + 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 ) } + } + ] ), + vertexShader: ShaderChunk.meshlambert_vert, fragmentShader: ShaderChunk.meshlambert_frag + }, + phong: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, UniformsLib.lights, { - emissive: { - value: new Color(0x000000) - }, - specular: { - value: new Color(0x111111) - }, - shininess: { - value: 30 - } - }]), + + 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 ) }, + specular: { value: /*@__PURE__*/ new Color( 0x111111 ) }, + shininess: { value: 30 } + } + ] ), + vertexShader: ShaderChunk.meshphong_vert, fragmentShader: ShaderChunk.meshphong_frag + }, + standard: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.roughnessmap, UniformsLib.metalnessmap, UniformsLib.fog, UniformsLib.lights, { - emissive: { - value: new Color(0x000000) - }, - roughness: { - value: 1.0 - }, - metalness: { - value: 0.0 - }, - envMapIntensity: { - value: 1 - } // temporary - }]), + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.roughnessmap, + UniformsLib.metalnessmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: /*@__PURE__*/ new Color( 0x000000 ) }, + roughness: { value: 1.0 }, + metalness: { value: 0.0 }, + envMapIntensity: { value: 1 } // temporary + } + ] ), + vertexShader: ShaderChunk.meshphysical_vert, fragmentShader: ShaderChunk.meshphysical_frag + }, + toon: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.gradientmap, UniformsLib.fog, UniformsLib.lights, { - emissive: { - value: new Color(0x000000) - } - }]), + + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.gradientmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: /*@__PURE__*/ new Color( 0x000000 ) } + } + ] ), + vertexShader: ShaderChunk.meshtoon_vert, fragmentShader: ShaderChunk.meshtoon_frag + }, + matcap: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, { - matcap: { - value: null + + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.fog, + { + matcap: { value: null } } - }]), + ] ), + vertexShader: ShaderChunk.meshmatcap_vert, fragmentShader: ShaderChunk.meshmatcap_frag + }, + points: { - uniforms: mergeUniforms([UniformsLib.points, UniformsLib.fog]), + + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.points, + UniformsLib.fog + ] ), + vertexShader: ShaderChunk.points_vert, fragmentShader: ShaderChunk.points_frag + }, + dashed: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.fog, { - scale: { - value: 1 - }, - dashSize: { - value: 1 - }, - totalSize: { - value: 2 + + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.fog, + { + scale: { value: 1 }, + dashSize: { value: 1 }, + totalSize: { value: 2 } } - }]), + ] ), + vertexShader: ShaderChunk.linedashed_vert, fragmentShader: ShaderChunk.linedashed_frag + }, + depth: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.displacementmap]), + + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.displacementmap + ] ), + vertexShader: ShaderChunk.depth_vert, fragmentShader: ShaderChunk.depth_frag + }, + normal: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, { - opacity: { - value: 1.0 + + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + { + opacity: { value: 1.0 } } - }]), + ] ), + vertexShader: ShaderChunk.meshnormal_vert, fragmentShader: ShaderChunk.meshnormal_frag + }, + sprite: { - uniforms: mergeUniforms([UniformsLib.sprite, UniformsLib.fog]), + + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.sprite, + UniformsLib.fog + ] ), + vertexShader: ShaderChunk.sprite_vert, fragmentShader: ShaderChunk.sprite_frag + }, + background: { + uniforms: { - uvTransform: { - value: new Matrix3() - }, - t2D: { - value: null - } + uvTransform: { value: /*@__PURE__*/ new Matrix3() }, + 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 map shader - ------------------------------------------------------------------------- */ cube: { - uniforms: 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 + }, + equirect: { + uniforms: { - tEquirect: { - value: null - } + tEquirect: { value: null }, }, + vertexShader: ShaderChunk.equirect_vert, fragmentShader: ShaderChunk.equirect_frag + }, + distanceRGBA: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.displacementmap, { - referencePosition: { - value: new Vector3() - }, - nearDistance: { - value: 1 - }, - farDistance: { - value: 1000 + + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.displacementmap, + { + referencePosition: { value: /*@__PURE__*/ new Vector3() }, + nearDistance: { value: 1 }, + farDistance: { value: 1000 } } - }]), + ] ), + vertexShader: ShaderChunk.distanceRGBA_vert, fragmentShader: ShaderChunk.distanceRGBA_frag + }, + shadow: { - uniforms: mergeUniforms([UniformsLib.lights, UniformsLib.fog, { - color: { - value: new Color(0x00000) + + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.lights, + UniformsLib.fog, + { + color: { value: /*@__PURE__*/ new Color( 0x00000 ) }, + opacity: { value: 1.0 } }, - opacity: { - value: 1.0 - } - }]), + ] ), + vertexShader: ShaderChunk.shadow_vert, fragmentShader: ShaderChunk.shadow_frag + } + }; + ShaderLib.physical = { - uniforms: mergeUniforms([ShaderLib.standard.uniforms, { - clearcoat: { - value: 0 - }, - clearcoatMap: { - value: null - }, - clearcoatRoughness: { - value: 0 - }, - clearcoatRoughnessMap: { - value: null - }, - clearcoatNormalScale: { - value: new Vector2(1, 1) - }, - clearcoatNormalMap: { - value: null - }, - 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 Color(0x000000) - }, - sheenColorMap: { - value: null - }, - sheenRoughness: { - value: 1 - }, - sheenRoughnessMap: { - value: null - }, - transmission: { - value: 0 - }, - transmissionMap: { - value: null - }, - transmissionSamplerSize: { - value: new Vector2() - }, - transmissionSamplerMap: { - value: null - }, - thickness: { - value: 0 - }, - thicknessMap: { - value: null - }, - attenuationDistance: { - value: 0 - }, - attenuationColor: { - value: new Color(0x000000) - }, - specularIntensity: { - value: 1 - }, - specularIntensityMap: { - value: null - }, - specularColor: { - value: new Color(1, 1, 1) - }, - specularColorMap: { - value: null - } - }]), + + uniforms: /*@__PURE__*/ mergeUniforms( [ + ShaderLib.standard.uniforms, + { + clearcoat: { value: 0 }, + clearcoatMap: { value: null }, + clearcoatRoughness: { value: 0 }, + clearcoatRoughnessMap: { value: null }, + clearcoatNormalScale: { value: /*@__PURE__*/ new Vector2( 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: /*@__PURE__*/ new Color( 0x000000 ) }, + sheenColorMap: { value: null }, + sheenRoughness: { value: 1 }, + sheenRoughnessMap: { value: null }, + transmission: { value: 0 }, + transmissionMap: { value: null }, + transmissionSamplerSize: { value: /*@__PURE__*/ new Vector2() }, + transmissionSamplerMap: { value: null }, + thickness: { value: 0 }, + thicknessMap: { value: null }, + attenuationDistance: { value: 0 }, + attenuationColor: { value: /*@__PURE__*/ new Color( 0x000000 ) }, + specularIntensity: { value: 1 }, + specularIntensityMap: { value: null }, + specularColor: { value: /*@__PURE__*/ new Color( 1, 1, 1 ) }, + specularColorMap: { value: null }, + } + ] ), + vertexShader: ShaderChunk.meshphysical_vert, fragmentShader: ShaderChunk.meshphysical_frag + }; -function WebGLBackground(renderer, cubemaps, state, objects, alpha, premultipliedAlpha) { - const clearColor = new Color(0x000000); +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; let boxMesh; + let currentBackground = null; let currentBackgroundVersion = 0; let currentTonemapping = null; - function render(renderList, scene) { + 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. + if ( background && background.isTexture ) { + + 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') { + if ( session && session.environmentBlendMode === 'additive' ) { + background = null; + } - if (background === null) { - setClear(clearColor, clearAlpha); - } else if (background && background.isColor) { - setClear(background, 1); + 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 ( 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, - side: BackSide, - depthTest: false, - depthWrite: false, - fog: false - })); - boxMesh.geometry.deleteAttribute('normal'); - boxMesh.geometry.deleteAttribute('uv'); + if ( background && ( background.isCubeTexture || background.mapping === CubeUVReflectionMapping ) ) { - boxMesh.onBeforeRender = function (renderer, scene, camera) { - this.matrixWorld.copyPosition(camera.matrixWorld); - }; // enable code injection for non-built-in material + if ( boxMesh === undefined ) { + boxMesh = new Mesh( + new BoxGeometry( 1, 1, 1 ), + new ShaderMaterial( { + name: 'BackgroundCubeMaterial', + uniforms: cloneUniforms( ShaderLib.backgroundCube.uniforms ), + vertexShader: ShaderLib.backgroundCube.vertexShader, + fragmentShader: ShaderLib.backgroundCube.fragmentShader, + side: BackSide, + depthTest: false, + depthWrite: false, + fog: false + } ) + ); - Object.defineProperty(boxMesh.material, 'envMap', { - get: function () { - return this.uniforms.envMap.value; - } - }); - objects.update(boxMesh); - } + boxMesh.geometry.deleteAttribute( 'normal' ); + boxMesh.geometry.deleteAttribute( 'uv' ); - boxMesh.material.uniforms.envMap.value = background; - boxMesh.material.uniforms.flipEnvMap.value = background.isCubeTexture && background.isRenderTargetTexture === false ? -1 : 1; + boxMesh.onBeforeRender = function ( renderer, scene, camera ) { - if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { - boxMesh.material.needsUpdate = true; - currentBackground = background; + this.matrixWorld.copyPosition( camera.matrixWorld ); + + }; + + // 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; + + } + + } ); + + 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; + boxMesh.material.toneMapped = ( background.encoding === sRGBEncoding ) ? false : true; + + if ( currentBackground !== background || + currentBackgroundVersion !== background.version || + currentTonemapping !== renderer.toneMapping ) { + + boxMesh.material.needsUpdate = true; + + currentBackground = background; currentBackgroundVersion = background.version; currentTonemapping = renderer.toneMapping; + } - boxMesh.layers.enableAll(); // push to the pre-sorted opaque render list - - renderList.unshift(boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null); - } else if (background && background.isTexture) { - if (planeMesh === undefined) { - planeMesh = new Mesh(new PlaneGeometry(2, 2), new ShaderMaterial({ - name: 'BackgroundMaterial', - uniforms: cloneUniforms(ShaderLib.background.uniforms), - vertexShader: ShaderLib.background.vertexShader, - fragmentShader: ShaderLib.background.fragmentShader, - side: FrontSide, - depthTest: false, - depthWrite: false, - fog: false - })); - planeMesh.geometry.deleteAttribute('normal'); // enable code injection for non-built-in material - - Object.defineProperty(planeMesh.material, 'map', { + boxMesh.layers.enableAll(); + + // push to the pre-sorted opaque render list + renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null ); + + } else if ( background && background.isTexture ) { + + if ( planeMesh === undefined ) { + + planeMesh = new Mesh( + new PlaneGeometry( 2, 2 ), + new ShaderMaterial( { + name: 'BackgroundMaterial', + uniforms: cloneUniforms( ShaderLib.background.uniforms ), + vertexShader: ShaderLib.background.vertexShader, + fragmentShader: ShaderLib.background.fragmentShader, + side: FrontSide, + depthTest: false, + depthWrite: false, + fog: false + } ) + ); + + planeMesh.geometry.deleteAttribute( 'normal' ); + + // 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; + } - }); - objects.update(planeMesh); + + } ); + + objects.update( planeMesh ); + } planeMesh.material.uniforms.t2D.value = background; + planeMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; + planeMesh.material.toneMapped = ( background.encoding === sRGBEncoding ) ? false : true; + + if ( background.matrixAutoUpdate === true ) { - if (background.matrixAutoUpdate === true) { background.updateMatrix(); + } - planeMesh.material.uniforms.uvTransform.value.copy(background.matrix); + planeMesh.material.uniforms.uvTransform.value.copy( background.matrix ); + + if ( currentBackground !== background || + currentBackgroundVersion !== background.version || + currentTonemapping !== renderer.toneMapping ) { - if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { planeMesh.material.needsUpdate = true; + currentBackground = background; currentBackgroundVersion = background.version; currentTonemapping = renderer.toneMapping; + } - planeMesh.layers.enableAll(); // push to the pre-sorted opaque render list + planeMesh.layers.enableAll(); + + // push to the pre-sorted opaque render list + renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null ); - 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); + function setClear( color, alpha ) { + + color.getRGB( _rgb, getUnlitUniformColorSpace( renderer ) ); + + state.buffers.color.setClear( _rgb.r, _rgb.g, _rgb.b, alpha, premultipliedAlpha ); + } return { + getClearColor: function () { + return clearColor; + }, - setClearColor: function (color, alpha = 1) { - clearColor.set(color); + setClearColor: function ( color, alpha = 1 ) { + + clearColor.set( color ); clearAlpha = alpha; - setClear(clearColor, clearAlpha); + setClear( clearColor, clearAlpha ); + }, getClearAlpha: function () { + return clearAlpha; + }, - setClearAlpha: function (alpha) { + setClearAlpha: function ( alpha ) { + clearAlpha = alpha; - setClear(clearColor, clearAlpha); + setClear( clearColor, clearAlpha ); + }, render: render + }; + } -function WebGLBindingStates(gl, extensions, attributes, capabilities) { - const maxVertexAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); - const extension = capabilities.isWebGL2 ? null : extensions.get('OES_vertex_array_object'); +function WebGLBindingStates( gl, extensions, attributes, capabilities ) { + + const maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); + + const extension = capabilities.isWebGL2 ? null : extensions.get( 'OES_vertex_array_object' ); const vaoAvailable = capabilities.isWebGL2 || extension !== null; + const bindingStates = {}; - const defaultState = createBindingState(null); + + const defaultState = createBindingState( null ); let currentState = defaultState; let forceUpdate = false; - function setup(object, material, program, geometry, index) { + function setup( object, material, program, geometry, index ) { + let updateBuffers = false; - if (vaoAvailable) { - const state = getBindingState(geometry, program, material); + if ( vaoAvailable ) { + + const state = getBindingState( geometry, program, material ); + + if ( currentState !== state ) { - if (currentState !== state) { currentState = state; - bindVertexArrayObject(currentState.object); + bindVertexArrayObject( currentState.object ); + } - updateBuffers = needsUpdate(object, geometry, program, index); - if (updateBuffers) saveCache(object, geometry, program, index); + 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) { + 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; currentState.wireframe = wireframe; + updateBuffers = true; + } + } - if (index !== null) { - attributes.update(index, gl.ELEMENT_ARRAY_BUFFER); + if ( index !== null ) { + + attributes.update( index, gl.ELEMENT_ARRAY_BUFFER ); + } - if (updateBuffers || forceUpdate) { + if ( updateBuffers || forceUpdate ) { + forceUpdate = false; - setupVertexAttributes(object, material, program, geometry); - if (index !== null) { - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, attributes.get(index).buffer); + 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(); + + if ( capabilities.isWebGL2 ) return gl.createVertexArray(); + return extension.createVertexArrayOES(); + } - function bindVertexArrayObject(vao) { - if (capabilities.isWebGL2) return gl.bindVertexArray(vao); - return extension.bindVertexArrayOES(vao); + 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 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]; + function getBindingState( geometry, program, material ) { + + const wireframe = ( material.wireframe === true ); + + let programMap = bindingStates[ geometry.id ]; + + if ( programMap === undefined ) { - if (programMap === undefined) { programMap = {}; - bindingStates[geometry.id] = programMap; + bindingStates[ geometry.id ] = programMap; + } - let stateMap = programMap[program.id]; + let stateMap = programMap[ program.id ]; + + if ( stateMap === undefined ) { - if (stateMap === undefined) { stateMap = {}; - programMap[program.id] = stateMap; + programMap[ program.id ] = stateMap; + } - let state = stateMap[wireframe]; + let state = stateMap[ wireframe ]; + + if ( state === undefined ) { + + state = createBindingState( createVertexArrayObject() ); + stateMap[ wireframe ] = state; - if (state === undefined) { - state = createBindingState(createVertexArrayObject()); - stateMap[wireframe] = state; } return state; + } - function createBindingState(vao) { + 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; + 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, program: null, wireframe: false, + newAttributes: newAttributes, enabledAttributes: enabledAttributes, attributeDivisors: attributeDivisors, object: vao, attributes: {}, index: null + }; + } - function needsUpdate(object, geometry, program, index) { + 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]; + for ( const name in programAttributes ) { + + const programAttribute = programAttributes[ name ]; + + if ( programAttribute.location >= 0 ) { + + const cachedAttribute = cachedAttributes[ name ]; + let geometryAttribute = geometryAttributes[ 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 (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 ( 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; + if ( currentState.attributesNum !== attributesNum ) return true; + + if ( currentState.index !== index ) return true; + return false; + } - function saveCache(object, geometry, program, index) { + 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]; + for ( const name in programAttributes ) { + + const programAttribute = programAttributes[ name ]; - if (programAttribute.location >= 0) { - let attribute = attributes[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; - 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) { + if ( attribute && attribute.data ) { + data.data = attribute.data; + } - cache[name] = data; - attributesNum++; + 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; + for ( let i = 0, il = newAttributes.length; i < il; i ++ ) { + + newAttributes[ i ] = 0; + } + } - function enableAttribute(attribute) { - enableAttributeAndDivisor(attribute, 0); + function enableAttribute( attribute ) { + + enableAttributeAndDivisor( attribute, 0 ); + } - function enableAttributeAndDivisor(attribute, meshPerAttribute) { + 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; + 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; + 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); - enabledAttributes[i] = 0; + for ( let i = 0, il = enabledAttributes.length; i < il; i ++ ) { + + if ( enabledAttributes[ i ] !== newAttributes[ i ] ) { + + gl.disableVertexAttribArray( i ); + enabledAttributes[ i ] = 0; + } + } + } - 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); + 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 ); + } else { - gl.vertexAttribPointer(index, size, type, normalized, stride, offset); + + 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; + 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]; + for ( const name in programAttributes ) { + + const programAttribute = programAttributes[ name ]; + + if ( programAttribute.location >= 0 ) { - if (programAttribute.location >= 0) { - let geometryAttribute = geometryAttributes[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 (geometryAttribute === undefined) { - if (name === 'instanceMatrix' && object.instanceMatrix) geometryAttribute = object.instanceMatrix; - if (name === 'instanceColor' && object.instanceColor) geometryAttribute = object.instanceColor; } - if (geometryAttribute !== undefined) { + 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 - if (attribute === undefined) continue; + 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) { + 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 ( data.isInstancedInterleavedBuffer ) { + + for ( let i = 0; i < programAttribute.locationSize; i ++ ) { + + enableAttributeAndDivisor( programAttribute.location + i, data.meshPerAttribute ); + } - if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) { + if ( object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined ) { + geometry._maxInstanceCount = data.meshPerAttribute * data.count; + } + } else { - for (let i = 0; i < programAttribute.locationSize; i++) { - enableAttribute(programAttribute.location + i); + + for ( let i = 0; i < programAttribute.locationSize; i ++ ) { + + enableAttribute( programAttribute.location + i ); + } + } - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + 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 + ); - 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); } + } else { - if (geometryAttribute.isInstancedBufferAttribute) { - for (let i = 0; i < programAttribute.locationSize; i++) { - enableAttributeAndDivisor(programAttribute.location + i, geometryAttribute.meshPerAttribute); + + if ( geometryAttribute.isInstancedBufferAttribute ) { + + for ( let i = 0; i < programAttribute.locationSize; i ++ ) { + + enableAttributeAndDivisor( programAttribute.location + i, geometryAttribute.meshPerAttribute ); + } - if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) { + if ( object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined ) { + geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; + } + } else { - for (let i = 0; i < programAttribute.locationSize; i++) { - enableAttribute(programAttribute.location + i); + + for ( let i = 0; i < programAttribute.locationSize; i ++ ) { + + enableAttribute( programAttribute.location + i ); + } + } - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + 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 + ); - 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) { + } else if ( materialDefaultAttributeValues !== undefined ) { + + const value = materialDefaultAttributeValues[ name ]; + + if ( value !== undefined ) { + + switch ( value.length ) { + case 2: - gl.vertexAttrib2fv(programAttribute.location, value); + gl.vertexAttrib2fv( programAttribute.location, value ); break; case 3: - gl.vertexAttrib3fv(programAttribute.location, value); + gl.vertexAttrib3fv( programAttribute.location, value ); break; case 4: - gl.vertexAttrib4fv(programAttribute.location, value); + gl.vertexAttrib4fv( programAttribute.location, value ); break; default: - gl.vertexAttrib1fv(programAttribute.location, value); + gl.vertexAttrib1fv( programAttribute.location, value ); + } + } + } + } + } disableUnusedAttributes(); + } function dispose() { + reset(); - for (const geometryId in bindingStates) { - const programMap = bindingStates[geometryId]; + for ( const geometryId in bindingStates ) { + + const programMap = bindingStates[ geometryId ]; + + for ( const programId in programMap ) { + + const stateMap = programMap[ programId ]; - for (const programId in programMap) { - const stateMap = programMap[programId]; + for ( const wireframe in stateMap ) { + + deleteVertexArrayObject( stateMap[ wireframe ].object ); + + delete stateMap[ wireframe ]; - for (const wireframe in stateMap) { - deleteVertexArrayObject(stateMap[wireframe].object); - delete stateMap[wireframe]; } - delete programMap[programId]; + delete programMap[ programId ]; + } - delete bindingStates[geometryId]; + delete bindingStates[ geometryId ]; + } + } - function releaseStatesOfGeometry(geometry) { - if (bindingStates[geometry.id] === undefined) return; - const programMap = bindingStates[geometry.id]; + function releaseStatesOfGeometry( geometry ) { + + if ( bindingStates[ geometry.id ] === undefined ) return; + + const programMap = bindingStates[ geometry.id ]; + + for ( const programId in programMap ) { - for (const programId in programMap) { - const stateMap = programMap[programId]; + const stateMap = programMap[ programId ]; + + for ( const wireframe in stateMap ) { + + deleteVertexArrayObject( stateMap[ wireframe ].object ); + + delete stateMap[ wireframe ]; - for (const wireframe in stateMap) { - deleteVertexArrayObject(stateMap[wireframe].object); - delete stateMap[wireframe]; } - delete programMap[programId]; + delete programMap[ programId ]; + } - delete bindingStates[geometry.id]; + 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]; + 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 ]; - for (const wireframe in stateMap) { - deleteVertexArrayObject(stateMap[wireframe].object); - delete stateMap[wireframe]; } - delete programMap[program.id]; + delete programMap[ program.id ]; + } + } function reset() { + resetDefaultState(); forceUpdate = true; - if (currentState === defaultState) return; + + if ( currentState === defaultState ) return; + currentState = defaultState; - bindVertexArrayObject(currentState.object); - } // for backward-compatibility + bindVertexArrayObject( currentState.object ); + + } + // for backward-compatibility function resetDefaultState() { + defaultState.geometry = null; defaultState.program = null; defaultState.wireframe = false; + } return { + setup: setup, reset: reset, resetDefaultState: resetDefaultState, dispose: dispose, releaseStatesOfGeometry: releaseStatesOfGeometry, releaseStatesOfProgram: releaseStatesOfProgram, + initAttributes: initAttributes, enableAttribute: enableAttribute, disableUnusedAttributes: disableUnusedAttributes + }; + } -function WebGLBufferRenderer(gl, extensions, info, capabilities) { +function WebGLBufferRenderer( gl, extensions, info, capabilities ) { + const isWebGL2 = capabilities.isWebGL2; + let mode; - function setMode(value) { + function setMode( value ) { + mode = value; + } - function render(start, count) { - gl.drawArrays(mode, start, count); - info.update(count, mode, 1); + function render( start, count ) { + + gl.drawArrays( mode, start, count ); + + info.update( count, mode, 1 ); + } - function renderInstances(start, count, primcount) { - if (primcount === 0) return; + function renderInstances( start, count, primcount ) { + + if ( primcount === 0 ) return; + let extension, methodName; - if (isWebGL2) { + if ( isWebGL2 ) { + extension = gl; methodName = 'drawArraysInstanced'; + } else { - extension = extensions.get('ANGLE_instanced_arrays'); + + 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.'); + 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); - } // + extension[ methodName ]( mode, start, count, primcount ); + info.update( count, mode, primcount ); + + } + + // this.setMode = setMode; this.render = render; this.renderInstances = renderInstances; + } -function WebGLCapabilities(gl, extensions, parameters) { +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); + 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) { + 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) { + 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; + const isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext; + let precision = parameters.precision !== undefined ? parameters.precision : 'highp'; - const maxPrecision = getMaxPrecision(precision); + const maxPrecision = getMaxPrecision( precision ); + + if ( maxPrecision !== precision ) { - if (maxPrecision !== precision) { - console.warn('THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.'); + console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' ); precision = maxPrecision; + } - const drawBuffers = isWebGL2 || extensions.has('WEBGL_draw_buffers'); + const drawBuffers = isWebGL2 || extensions.has( 'WEBGL_draw_buffers' ); + const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; - const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); - const maxVertexTextures = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); - const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); - const maxCubemapSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); - const maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); - const maxVertexUniforms = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS); - const maxVaryings = gl.getParameter(gl.MAX_VARYING_VECTORS); - const maxFragmentUniforms = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS); + + const maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS ); + const maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); + const maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE ); + const maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE ); + + const maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); + const maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS ); + const maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS ); + const maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS ); + const vertexTextures = maxVertexTextures > 0; - const floatFragmentTextures = isWebGL2 || extensions.has('OES_texture_float'); + const floatFragmentTextures = isWebGL2 || extensions.has( 'OES_texture_float' ); const floatVertexTextures = vertexTextures && floatFragmentTextures; - const maxSamples = isWebGL2 ? gl.getParameter(gl.MAX_SAMPLES) : 0; + + const maxSamples = isWebGL2 ? gl.getParameter( gl.MAX_SAMPLES ) : 0; + return { + isWebGL2: isWebGL2, + drawBuffers: drawBuffers, + getMaxAnisotropy: getMaxAnisotropy, getMaxPrecision: getMaxPrecision, + precision: precision, logarithmicDepthBuffer: logarithmicDepthBuffer, + maxTextures: maxTextures, maxVertexTextures: maxVertexTextures, maxTextureSize: maxTextureSize, maxCubemapSize: maxCubemapSize, + maxAttributes: maxAttributes, maxVertexUniforms: maxVertexUniforms, maxVaryings: maxVaryings, maxFragmentUniforms: maxFragmentUniforms, + vertexTextures: vertexTextures, floatFragmentTextures: floatFragmentTextures, floatVertexTextures: floatVertexTextures, + maxSamples: maxSamples + }; + } -function WebGLClipping(properties) { +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 - // run another frame in order to reset the state: - numGlobalPlanes !== 0 || localClippingEnabled; + this.init = function ( planes, enableLocalClipping ) { + + 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; - globalState = projectPlanes(planes, camera, 0); + numGlobalPlanes = planes.length; + return enabled; + }; this.beginShadows = function () { + renderingShadows = true; - projectPlanes(null); + projectPlanes( null ); + }; this.endShadows = function () { + renderingShadows = false; - resetGlobalState(); + + }; + + this.setGlobalState = function ( planes, camera ) { + + globalState = projectPlanes( planes, camera, 0 ); + }; - this.setState = function (material, camera, useCache) { + this.setState = function ( material, camera, useCache ) { + const planes = material.clippingPlanes, - clipIntersection = material.clipIntersection, - clipShadows = material.clipShadows; - const materialProperties = properties.get(material); + clipIntersection = material.clipIntersection, + clipShadows = material.clipShadows; + + const materialProperties = properties.get( material ); + + if ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) { - if (!localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && !clipShadows) { // there's no local clipping - if (renderingShadows) { + + if ( renderingShadows ) { + // there's no global clipping - projectPlanes(null); + + 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); + dstArray = projectPlanes( planes, camera, lGlobal, useCache ); + + for ( let i = 0; i !== lGlobal; ++ i ) { + + dstArray[ i ] = globalState[ i ]; - 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) { + + if ( uniform.value !== globalState ) { + uniform.value = globalState; uniform.needsUpdate = numGlobalPlanes > 0; + } scope.numPlanes = numGlobalPlanes; scope.numIntersection = 0; + } - function projectPlanes(planes, camera, dstOffset, skipTransform) { + function projectPlanes( planes, camera, dstOffset, skipTransform ) { + const nPlanes = planes !== null ? planes.length : 0; let dstArray = null; - if (nPlanes !== 0) { + if ( nPlanes !== 0 ) { + dstArray = uniform.value; - if (skipTransform !== true || dstArray === null) { + if ( skipTransform !== true || dstArray === null ) { + const flatSize = dstOffset + nPlanes * 4, - viewMatrix = camera.matrixWorldInverse; - viewNormalMatrix.getNormalMatrix(viewMatrix); + viewMatrix = camera.matrixWorldInverse; + + viewNormalMatrix.getNormalMatrix( viewMatrix ); + + if ( dstArray === null || dstArray.length < flatSize ) { + + dstArray = new Float32Array( flatSize ); - 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; + 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; + } + } -function WebGLCubeMaps(renderer) { +function WebGLCubeMaps( renderer ) { + let cubemaps = new WeakMap(); - function mapTextureMapping(texture, mapping) { - if (mapping === EquirectangularReflectionMapping) { + function mapTextureMapping( texture, mapping ) { + + if ( mapping === EquirectangularReflectionMapping ) { + texture.mapping = CubeReflectionMapping; - } else if (mapping === EquirectangularRefractionMapping) { + + } else if ( mapping === EquirectangularRefractionMapping ) { + texture.mapping = CubeRefractionMapping; + } return texture; + } - function get(texture) { - if (texture && texture.isTexture && texture.isRenderTargetTexture === false) { + 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); + 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); - cubemaps.set(texture, renderTarget); - texture.addEventListener('dispose', onTextureDispose); - return mapTextureMapping(renderTarget.texture, texture.mapping); + if ( image && image.height > 0 ) { + + const renderTarget = new WebGLCubeRenderTarget( image.height / 2 ); + renderTarget.fromEquirectangularTexture( renderer, texture ); + cubemaps.set( texture, renderTarget ); + + texture.addEventListener( 'dispose', onTextureDispose ); + + return mapTextureMapping( renderTarget.texture, texture.mapping ); + } else { + // image not yet ready. try the conversion next frame + return null; + } + } + } + } return texture; + } - function onTextureDispose(event) { + function onTextureDispose( event ) { + const texture = event.target; - texture.removeEventListener('dispose', onTextureDispose); - const cubemap = cubemaps.get(texture); - if (cubemap !== undefined) { - cubemaps.delete(texture); + 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 }; + } class OrthographicCamera extends Camera { - constructor(left = -1, right = 1, top = 1, bottom = -1, near = 0.1, far = 2000) { + + constructor( left = - 1, right = 1, top = 1, bottom = - 1, near = 0.1, far = 2000 ) { + super(); + this.isOrthographicCamera = true; + this.type = 'OrthographicCamera'; + this.zoom = 1; this.view = null; + this.left = left; this.right = right; this.top = top; this.bottom = bottom; + this.near = near; this.far = far; + this.updateProjectionMatrix(); + } - copy(source, recursive) { - super.copy(source, recursive); + copy( source, recursive ) { + + super.copy( source, recursive ); + this.left = source.left; this.right = source.right; this.top = source.top; this.bottom = source.bottom; this.near = source.near; this.far = source.far; + this.zoom = source.zoom; - this.view = source.view === null ? null : Object.assign({}, source.view); + this.view = source.view === null ? null : Object.assign( {}, source.view ); + return this; + } - setViewOffset(fullWidth, fullHeight, x, y, width, height) { - if (this.view === null) { + setViewOffset( fullWidth, fullHeight, x, y, width, height ) { + + if ( this.view === null ) { + this.view = { enabled: true, fullWidth: 1, @@ -11678,6 +15212,7 @@ class OrthographicCamera extends Camera { width: 1, height: 1 }; + } this.view.enabled = true; @@ -11687,42 +15222,57 @@ class OrthographicCamera extends Camera { this.view.offsetY = y; this.view.width = width; this.view.height = height; + this.updateProjectionMatrix(); + } clearViewOffset() { - if (this.view !== null) { + + if ( this.view !== null ) { + this.view.enabled = false; + } this.updateProjectionMatrix(); + } updateProjectionMatrix() { - const dx = (this.right - this.left) / (2 * this.zoom); - const dy = (this.top - this.bottom) / (2 * this.zoom); - const cx = (this.right + this.left) / 2; - const cy = (this.top + this.bottom) / 2; + + const dx = ( this.right - this.left ) / ( 2 * this.zoom ); + const dy = ( this.top - this.bottom ) / ( 2 * this.zoom ); + const cx = ( this.right + this.left ) / 2; + const cy = ( this.top + this.bottom ) / 2; + let left = cx - dx; let right = cx + dx; let top = cy + dy; let bottom = cy - dy; - if (this.view !== null && this.view.enabled) { - const scaleW = (this.right - this.left) / this.view.fullWidth / this.zoom; - const scaleH = (this.top - this.bottom) / this.view.fullHeight / this.zoom; + if ( this.view !== null && this.view.enabled ) { + + const scaleW = ( this.right - this.left ) / this.view.fullWidth / this.zoom; + const scaleH = ( this.top - this.bottom ) / this.view.fullHeight / this.zoom; + left += scaleW * this.view.offsetX; right = left + scaleW * this.view.width; top -= scaleH * this.view.offsetY; bottom = top - scaleH * this.view.height; + } - this.projectionMatrix.makeOrthographic(left, right, top, bottom, this.near, this.far); - this.projectionMatrixInverse.copy(this.projectionMatrix).invert(); + this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far ); + + this.projectionMatrixInverse.copy( this.projectionMatrix ).invert(); + } - toJSON(meta) { - const data = super.toJSON(meta); + toJSON( meta ) { + + const data = super.toJSON( meta ); + data.object.zoom = this.zoom; data.object.left = this.left; data.object.right = this.right; @@ -11730,33 +15280,49 @@ class OrthographicCamera extends Camera { data.object.bottom = this.bottom; data.object.near = this.near; data.object.far = this.far; - if (this.view !== null) data.object.view = Object.assign({}, this.view); + + 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 _flatCamera = /*@__PURE__*/ new OrthographicCamera(); +const _clearColor = /*@__PURE__*/ new Color(); +let _oldTarget = null; -const _clearColor = /*@__PURE__*/new Color(); +// Golden Ratio +const PHI = ( 1 + Math.sqrt( 5 ) ) / 2; +const INV_PHI = 1 / PHI; -let _oldTarget = null; // Golden Ratio - -const PHI = (1 + Math.sqrt(5)) / 2; -const INV_PHI = 1 / PHI; // Vertices of a dodecahedron (except the opposites, which represent the +// 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 ) ]; -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 @@ -11773,20 +15339,26 @@ const _axisDirections = [/*@__PURE__*/new Vector3(1, 1, 1), /*@__PURE__*/new Vec */ class PMREMGenerator { - constructor(renderer) { + + constructor( renderer ) { + this._renderer = renderer; 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); + 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 @@ -11794,7 +15366,9 @@ 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 ) { +<<<<<<< HEAD fromScene(scene, sigma = 0, near = 0.1, far = 100, cubeUVRenderTarget = null, pingPongRenderTarget = null) { _oldTarget = this._renderer.getRenderTarget(); @@ -11809,21 +15383,31 @@ class PMREMGenerator { this._setSize(256); +======= + _oldTarget = this._renderer.getRenderTarget(); + + this._setSize( 256 ); + + const cubeUVRenderTarget = this._allocateTargets(); +>>>>>>> mrdoob-dev cubeUVRenderTarget.depthBuffer = true; - this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); + this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget ); - if (sigma > 0) { - this._blur(cubeUVRenderTarget, 0, 0, sigma); - } + if ( sigma > 0 ) { - this._applyPMREM(cubeUVRenderTarget); + this._blur( cubeUVRenderTarget, 0, 0, sigma ); + + } - this._cleanup(cubeUVRenderTarget); + this._applyPMREM( cubeUVRenderTarget ); + this._cleanup( cubeUVRenderTarget ); return cubeUVRenderTarget; + } +<<<<<<< HEAD prepareForRenderTarget(cubeUVRenderTarget, pingPongRenderTarget = null, cubeSize = 256) { this._setSize(cubeSize); @@ -11865,113 +15449,133 @@ class PMREMGenerator { return cubeUVRenderTarget; } +======= +>>>>>>> mrdoob-dev /** * 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 ); - 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 ); - 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 ) { - compileCubemapShader() { - if (this._cubemapMaterial === null) { this._cubemapMaterial = _getCubemapMaterial(); + this._compileMaterial( this._cubemapMaterial ); - 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 ) { - compileEquirectangularShader() { - if (this._equirectMaterial === null) { this._equirectMaterial = _getEquirectMaterial(); + this._compileMaterial( this._equirectMaterial ); - 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 + if ( this._cubemapMaterial !== null ) this._cubemapMaterial.dispose(); + if ( this._equirectMaterial !== null ) this._equirectMaterial.dispose(); + + } + + // private interface + _setSize( cubeSize ) { + + this._lodMax = Math.floor( Math.log2( cubeSize ) ); + this._cubeSize = Math.pow( 2, this._lodMax ); - _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(); + 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); + _cleanup( outputTarget ) { + this._renderer.setRenderTarget( _oldTarget ); outputTarget.scissorTest = false; + _setViewport( outputTarget, 0, 0, outputTarget.width, outputTarget.height ); - _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); - } + _fromTexture( texture, renderTarget ) { - _oldTarget = this._renderer.getRenderTarget(); + if ( texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping ) { - const cubeUVRenderTarget = renderTarget || this._allocateTargets(); + this._setSize( texture.image.length === 0 ? 16 : ( texture.image[ 0 ].width || texture.image[ 0 ].image.width ) ); - this._textureToCubeUV(texture, cubeUVRenderTarget); + } else { // Equirectangular - this._applyPMREM(cubeUVRenderTarget); + this._setSize( texture.image.width / 4 ); + + } - this._cleanup(cubeUVRenderTarget); + _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 width = 3 * Math.max( this._cubeSize, 16 * 7 ); const height = 4 * this._cubeSize; + const params = { magFilter: LinearFilter, minFilter: LinearFilter, @@ -11982,143 +15586,189 @@ class PMREMGenerator { depthBuffer: false }; - const cubeUVRenderTarget = _createRenderTarget(width, height, params); + const cubeUVRenderTarget = _createRenderTarget( width, height, params ); + + if ( this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width || this._pingPongRenderTarget.height !== height ) { + + if ( this._pingPongRenderTarget !== null ) { - if (this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width) { - if (this._pingPongRenderTarget !== null) { this._dispose(); + } - this._pingPongRenderTarget = _createRenderTarget(width, height, params); - const { - _lodMax - } = this; - ({ - sizeLods: this._sizeLods, - lodPlanes: this._lodPlanes, - sigmas: this._sigmas - } = _createPlanes(_lodMax)); - this._blurMaterial = _getBlurShader(_lodMax, width, height); + this._pingPongRenderTarget = _createRenderTarget( width, height, params ); + + const { _lodMax } = this; + ( { sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas } = _createPlanes( _lodMax ) ); + + this._blurMaterial = _getBlurShader( _lodMax, width, height ); + } return cubeUVRenderTarget; + } - _compileMaterial(material) { - const tmpMesh = new Mesh(this._lodPlanes[0], material); + _compileMaterial( material ) { + + const tmpMesh = new Mesh( this._lodPlanes[ 0 ], material ); + this._renderer.compile( tmpMesh, _flatCamera ); - this._renderer.compile(tmpMesh, _flatCamera); } - _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { + _sceneToCubeUV( scene, near, far, cubeUVRenderTarget ) { + const fov = 90; const aspect = 1; - const cubeCamera = new PerspectiveCamera(fov, aspect, near, far); - const upSign = [1, -1, 1, 1, 1, 1]; - const forwardSign = [1, 1, 1, -1, -1, -1]; + const cubeCamera = new PerspectiveCamera( fov, aspect, near, far ); + const upSign = [ 1, - 1, 1, 1, 1, 1 ]; + const forwardSign = [ 1, 1, 1, - 1, - 1, - 1 ]; const renderer = this._renderer; + const originalAutoClear = renderer.autoClear; const toneMapping = renderer.toneMapping; - renderer.getClearColor(_clearColor); + renderer.getClearColor( _clearColor ); + renderer.toneMapping = NoToneMapping; renderer.autoClear = false; - const backgroundMaterial = new MeshBasicMaterial({ + + const backgroundMaterial = new MeshBasicMaterial( { name: 'PMREM.Background', side: BackSide, depthWrite: false, - depthTest: false - }); - const backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial); + depthTest: false, + } ); + + const backgroundBox = new Mesh( new BoxGeometry(), backgroundMaterial ); + let useSolidColor = false; const background = scene.background; - if (background) { - if (background.isColor) { - backgroundMaterial.color.copy(background); + if ( background ) { + + if ( background.isColor ) { + + backgroundMaterial.color.copy( background ); scene.background = null; useSolidColor = true; + } + } else { - backgroundMaterial.color.copy(_clearColor); + + backgroundMaterial.color.copy( _clearColor ); useSolidColor = true; + } - for (let i = 0; i < 6; i++) { + 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); - } else if (col === 1) { - cubeCamera.up.set(0, 0, upSign[i]); - cubeCamera.lookAt(0, forwardSign[i], 0); + if ( col === 0 ) { + + cubeCamera.up.set( 0, upSign[ i ], 0 ); + cubeCamera.lookAt( forwardSign[ i ], 0, 0 ); + + } else if ( col === 1 ) { + + cubeCamera.up.set( 0, 0, upSign[ i ] ); + cubeCamera.lookAt( 0, forwardSign[ i ], 0 ); + } else { - cubeCamera.up.set(0, upSign[i], 0); - cubeCamera.lookAt(0, 0, forwardSign[i]); + + 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); + _setViewport( cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size ); - renderer.setRenderTarget(cubeUVRenderTarget); + renderer.setRenderTarget( cubeUVRenderTarget ); - if (useSolidColor) { - renderer.render(backgroundBox, cubeCamera); - } + if ( useSolidColor ) { + + renderer.render( backgroundBox, cubeCamera ); + + } + + renderer.render( scene, cubeCamera ); - renderer.render(scene, cubeCamera); } backgroundBox.geometry.dispose(); backgroundBox.material.dispose(); + renderer.toneMapping = toneMapping; renderer.autoClear = originalAutoClear; scene.background = background; + } - _textureToCubeUV(texture, cubeUVRenderTarget) { + _textureToCubeUV( texture, cubeUVRenderTarget ) { + const renderer = this._renderer; - const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping; - if (isCubeTexture) { - if (this._cubemapMaterial === null) { + 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; + this._cubemapMaterial.uniforms.flipEnvMap.value = ( texture.isRenderTargetTexture === false ) ? - 1 : 1; + } else { - if (this._equirectMaterial === null) { + + if ( this._equirectMaterial === null ) { + this._equirectMaterial = _getEquirectMaterial(); + } + } const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; - const mesh = new Mesh(this._lodPlanes[0], material); + const mesh = new Mesh( this._lodPlanes[ 0 ], material ); + const uniforms = material.uniforms; - uniforms['envMap'].value = texture; + + uniforms[ 'envMap' ].value = texture; + const size = this._cubeSize; - _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); + _setViewport( cubeUVRenderTarget, 0, 0, 3 * size, 2 * size ); + + renderer.setRenderTarget( cubeUVRenderTarget ); + renderer.render( mesh, _flatCamera ); - renderer.setRenderTarget(cubeUVRenderTarget); - renderer.render(mesh, _flatCamera); } - _applyPMREM(cubeUVRenderTarget) { + _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]; + 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 ); - 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 @@ -12126,193 +15776,242 @@ 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 ) { - - _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { const pingPongRenderTarget = this._pingPongRenderTarget; - this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); + this._halfBlur( + cubeUVRenderTarget, + pingPongRenderTarget, + lodIn, + lodOut, + sigma, + 'latitudinal', + poleAxis ); + + this._halfBlur( + pingPongRenderTarget, + cubeUVRenderTarget, + lodOut, + lodOut, + sigma, + 'longitudinal', + poleAxis ); - this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis); } - _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, 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. + 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. const STANDARD_DEVIATIONS = 3; - const blurMesh = new Mesh(this._lodPlanes[lodOut], blurMaterial); + + const blurMesh = new Mesh( this._lodPlanes[ lodOut ], blurMaterial ); const blurUniforms = blurMaterial.uniforms; - const pixels = this._sizeLods[lodIn] - 1; - const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES - 1); + + const pixels = this._sizeLods[ lodIn ] - 1; + 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; + 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}` ); - 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) { + for ( let i = 0; i < MAX_SAMPLES; ++ i ) { + const x = i / sigmaPixels; - const weight = Math.exp(-x * x / 2); - weights.push(weight); + const weight = Math.exp( - x * x / 2 ); + weights.push( weight ); + + if ( i === 0 ) { - if (i === 0) { sum += weight; - } else if (i < samples) { + + } else if ( i < samples ) { + sum += 2 * weight; + } + } - for (let i = 0; i < weights.length; i++) { - weights[i] = weights[i] / sum; + 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'; + blurUniforms[ 'envMap' ].value = targetIn.texture; + blurUniforms[ 'samples' ].value = samples; + blurUniforms[ 'weights' ].value = weights; + blurUniforms[ 'latitudinal' ].value = direction === 'latitudinal'; + + if ( poleAxis ) { + + blurUniforms[ 'poleAxis' ].value = poleAxis; - if (poleAxis) { - blurUniforms['poleAxis'].value = poleAxis; } - const { - _lodMax - } = this; - blurUniforms['dTheta'].value = radiansPerPixel; - blurUniforms['mipInt'].value = _lodMax - lodIn; - const outputSize = this._sizeLods[lodOut]; - const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0); - const y = 4 * (this._cubeSize - outputSize); + const { _lodMax } = this; + blurUniforms[ 'dTheta' ].value = radiansPerPixel; + blurUniforms[ 'mipInt' ].value = _lodMax - lodIn; - _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); + 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 ); - renderer.setRenderTarget(targetOut); - renderer.render(blurMesh, _flatCamera); } } -function _createPlanes(lodMax) { + + +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); + 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) { + 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; + sigmas.push( sigma ); + + const texelSize = 1.0 / ( sizeLod - 2 ); + const min = - texelSize; const max = 1 + texelSize; - const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; + const uv1 = [ min, min, max, min, max, max, min, min, max, max, min, max ]; + const cubeFaces = 6; const vertices = 6; const positionSize = 3; const uvSize = 2; const faceIndexSize = 1; - 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; - const coordinates = [x, y, 0, x + 2 / 3, y, 0, x + 2 / 3, y + 1, 0, x, y, 0, x + 2 / 3, y + 1, 0, x, y + 1, 0]; - position.set(coordinates, positionSize * vertices * face); - uv.set(uv1, uvSize * vertices * face); - const fill = [face, face, face, face, face, face]; - faceIndex.set(fill, faceIndexSize * vertices * face); + 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; + const coordinates = [ + x, y, 0, + x + 2 / 3, y, 0, + x + 2 / 3, y + 1, 0, + x, y, 0, + x + 2 / 3, y + 1, 0, + x, y + 1, 0 + ]; + position.set( coordinates, positionSize * vertices * face ); + uv.set( uv1, uvSize * vertices * face ); + 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); + 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 --; - if (lod > LOD_MIN) { - lod--; } + } - return { - lodPlanes, - sizeLods, - sigmas - }; + return { lodPlanes, sizeLods, sigmas }; + } -function _createRenderTarget(width, height, params) { - const cubeUVRenderTarget = new WebGLRenderTarget(width, height, params); +function _createRenderTarget( width, height, params ) { + + const cubeUVRenderTarget = new WebGLRenderTarget( width, height, params ); cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; cubeUVRenderTarget.scissorTest = true; return cubeUVRenderTarget; + } -function _setViewport(target, x, y, width, height) { - target.viewport.set(x, y, width, height); - target.scissor.set(x, y, width, height); +function _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); - const shaderMaterial = new ShaderMaterial({ +function _getBlurShader( lodMax, width, height ) { + + const weights = new Float32Array( MAX_SAMPLES ); + const poleAxis = new Vector3( 0, 1, 0 ); + const shaderMaterial = new ShaderMaterial( { + name: 'SphericalGaussianBlur', + defines: { 'n': MAX_SAMPLES, 'CUBEUV_TEXEL_WIDTH': 1.0 / width, 'CUBEUV_TEXEL_HEIGHT': 1.0 / height, - 'CUBEUV_MAX_MIP': `${lodMax}.0` + 'CUBEUV_MAX_MIP': `${lodMax}.0`, }, + uniforms: { - 'envMap': { - value: null - }, - 'samples': { - value: 1 - }, - 'weights': { - value: weights - }, - 'latitudinal': { - value: false - }, - 'dTheta': { - value: 0 - }, - 'mipInt': { - value: 0 - }, - 'poleAxis': { - value: poleAxis - } + 'envMap': { value: null }, + 'samples': { value: 1 }, + 'weights': { value: weights }, + 'latitudinal': { value: false }, + 'dTheta': { value: 0 }, + 'mipInt': { value: 0 }, + 'poleAxis': { value: poleAxis } }, + vertexShader: _getCommonVertexShader(), - fragmentShader: - /* glsl */ - ` + + fragmentShader: /* glsl */` precision mediump float; precision mediump int; @@ -12373,25 +16072,30 @@ function _getBlurShader(lodMax, width, height) { } `, + blending: NoBlending, depthTest: false, depthWrite: false - }); + + } ); + return shaderMaterial; + } function _getEquirectMaterial() { - return new ShaderMaterial({ + + return new ShaderMaterial( { + name: 'EquirectangularToCubeUV', + uniforms: { - 'envMap': { - value: null - } + 'envMap': { value: null } }, + vertexShader: _getCommonVertexShader(), - fragmentShader: - /* glsl */ - ` + + fragmentShader: /* glsl */` precision mediump float; precision mediump int; @@ -12411,27 +16115,29 @@ function _getEquirectMaterial() { } `, + blending: NoBlending, depthTest: false, depthWrite: false - }); + + } ); + } function _getCubemapMaterial() { - return new ShaderMaterial({ + + return new ShaderMaterial( { + name: 'CubemapToCubeUV', + uniforms: { - 'envMap': { - value: null - }, - 'flipEnvMap': { - value: -1 - } + 'envMap': { value: null }, + 'flipEnvMap': { value: - 1 } }, + vertexShader: _getCommonVertexShader(), - fragmentShader: - /* glsl */ - ` + + fragmentShader: /* glsl */` precision mediump float; precision mediump int; @@ -12448,16 +16154,18 @@ function _getCubemapMaterial() { } `, + blending: NoBlending, depthTest: false, depthWrite: false - }); + + } ); + } function _getCommonVertexShader() { - return ( - /* glsl */ - ` + + return /* glsl */` precision mediump float; precision mediump int; @@ -12523,336 +16231,496 @@ function _getCommonVertexShader() { gl_Position = vec4( position, 1.0 ); } - ` - ); + `; + } -function WebGLCubeUVMaps(renderer) { +function WebGLCubeUVMaps( renderer ) { + let cubeUVmaps = new WeakMap(); + let pmremGenerator = null; - function get(texture) { - if (texture && texture.isTexture) { + 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 - if (isEquirectMap || isCubeMap) { - if (texture.isRenderTargetTexture && texture.needsPMREMUpdate === true) { + const isEquirectMap = ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping ); + const isCubeMap = ( mapping === CubeReflectionMapping || mapping === CubeRefractionMapping ); + + // equirect/cube map to cubeUV conversion + + if ( isEquirectMap || isCubeMap ) { + + if ( texture.isRenderTargetTexture && texture.needsPMREMUpdate === true ) { + texture.needsPMREMUpdate = false; - let renderTarget = cubeUVmaps.get(texture); - if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer); - renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture, renderTarget) : pmremGenerator.fromCubemap(texture, renderTarget); - cubeUVmaps.set(texture, renderTarget); + + let renderTarget = cubeUVmaps.get( texture ); + + if ( pmremGenerator === null ) pmremGenerator = new PMREMGenerator( renderer ); + + renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular( texture, renderTarget ) : pmremGenerator.fromCubemap( texture, renderTarget ); + cubeUVmaps.set( texture, renderTarget ); + return renderTarget.texture; + } else { - if (cubeUVmaps.has(texture)) { - return cubeUVmaps.get(texture).texture; + + if ( cubeUVmaps.has( texture ) ) { + + 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); - cubeUVmaps.set(texture, renderTarget); - texture.addEventListener('dispose', onTextureDispose); + 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 ); + cubeUVmaps.set( texture, renderTarget ); + + texture.addEventListener( 'dispose', onTextureDispose ); + return renderTarget.texture; + } else { + // image not yet ready. try the conversion next frame + return null; + } + } + } + } + } return texture; + } - function isCubeTextureComplete(image) { + function isCubeTextureComplete( image ) { + let count = 0; const length = 6; - for (let i = 0; i < length; i++) { - if (image[i] !== undefined) count++; + for ( let i = 0; i < length; i ++ ) { + + if ( image[ i ] !== undefined ) count ++; + } return count === length; + + } - function onTextureDispose(event) { + function onTextureDispose( event ) { + const texture = event.target; - texture.removeEventListener('dispose', onTextureDispose); - const cubemapUV = cubeUVmaps.get(texture); - if (cubemapUV !== undefined) { - cubeUVmaps.delete(texture); + 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) { + if ( pmremGenerator !== null ) { + pmremGenerator.dispose(); pmremGenerator = null; + } + } return { get: get, dispose: dispose }; + } -function WebGLExtensions(gl) { +function WebGLExtensions( gl ) { + const extensions = {}; - function getExtension(name) { - if (extensions[name] !== undefined) { - return extensions[name]; + function getExtension( name ) { + + if ( extensions[ name ] !== undefined ) { + + return extensions[ name ]; + } let extension; - switch (name) { + switch ( name ) { + case 'WEBGL_depth_texture': - extension = gl.getExtension('WEBGL_depth_texture') || gl.getExtension('MOZ_WEBGL_depth_texture') || gl.getExtension('WEBKIT_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'); + 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'); + 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'); + extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' ); break; default: - extension = gl.getExtension(name); + extension = gl.getExtension( name ); + } - extensions[name] = extension; + extensions[ name ] = extension; + return extension; + } return { - has: function (name) { - return getExtension(name) !== null; + + has: function ( name ) { + + return getExtension( name ) !== null; + }, - init: function (capabilities) { - if (capabilities.isWebGL2) { - getExtension('EXT_color_buffer_float'); + + init: function ( capabilities ) { + + if ( capabilities.isWebGL2 ) { + + getExtension( 'EXT_color_buffer_float' ); + } else { - getExtension('WEBGL_depth_texture'); - getExtension('OES_texture_float'); - getExtension('OES_texture_half_float'); - getExtension('OES_texture_half_float_linear'); - getExtension('OES_standard_derivatives'); - getExtension('OES_element_index_uint'); - 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'); + + getExtension( 'WEBGL_depth_texture' ); + getExtension( 'OES_texture_float' ); + getExtension( 'OES_texture_half_float' ); + getExtension( 'OES_texture_half_float_linear' ); + getExtension( 'OES_standard_derivatives' ); + getExtension( 'OES_element_index_uint' ); + 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.'); + get: function ( name ) { + + const extension = getExtension( name ); + + if ( extension === null ) { + + console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); + } return extension; + } + }; + } -function WebGLGeometries(gl, attributes, info, bindingStates) { +function WebGLGeometries( gl, attributes, info, bindingStates ) { + const geometries = {}; const wireframeAttributes = new WeakMap(); - function onGeometryDispose(event) { + function onGeometryDispose( event ) { + const geometry = event.target; - if (geometry.index !== null) { - attributes.remove(geometry.index); + if ( geometry.index !== null ) { + + attributes.remove( geometry.index ); + } - for (const name in geometry.attributes) { - attributes.remove(geometry.attributes[name]); + for ( const name in geometry.attributes ) { + + attributes.remove( geometry.attributes[ name ] ); + } - geometry.removeEventListener('dispose', onGeometryDispose); - delete geometries[geometry.id]; - const attribute = wireframeAttributes.get(geometry); + geometry.removeEventListener( 'dispose', onGeometryDispose ); + + delete geometries[ geometry.id ]; + + const attribute = wireframeAttributes.get( geometry ); + + if ( attribute ) { + + attributes.remove( attribute ); + wireframeAttributes.delete( geometry ); - if (attribute) { - attributes.remove(attribute); - wireframeAttributes.delete(geometry); } - bindingStates.releaseStatesOfGeometry(geometry); + bindingStates.releaseStatesOfGeometry( geometry ); + + if ( geometry.isInstancedBufferGeometry === true ) { - if (geometry.isInstancedBufferGeometry === true) { delete geometry._maxInstanceCount; - } // + } + + // + + info.memory.geometries --; - info.memory.geometries--; } - function get(object, geometry) { - if (geometries[geometry.id] === true) return geometry; - geometry.addEventListener('dispose', onGeometryDispose); - geometries[geometry.id] = true; - info.memory.geometries++; + function get( object, geometry ) { + + if ( geometries[ geometry.id ] === true ) return geometry; + + geometry.addEventListener( 'dispose', onGeometryDispose ); + + geometries[ geometry.id ] = true; + + info.memory.geometries ++; + return geometry; + } - function update(geometry) { - const geometryAttributes = geometry.attributes; // Updating index buffer in VAO now. See WebGLBindingStates. + function update( geometry ) { - for (const name in geometryAttributes) { - attributes.update(geometryAttributes[name], gl.ARRAY_BUFFER); - } // morph targets + 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 const morphAttributes = geometry.morphAttributes; - for (const name in morphAttributes) { - const array = morphAttributes[name]; + 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 ); - for (let i = 0, l = array.length; i < l; i++) { - attributes.update(array[i], gl.ARRAY_BUFFER); } + } + } - function updateWireframeAttribute(geometry) { + function updateWireframeAttribute( geometry ) { + const indices = []; + const geometryIndex = geometry.index; const geometryPosition = geometry.attributes.position; let version = 0; - if (geometryIndex !== null) { + 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]; - const c = array[i + 2]; - indices.push(a, b, b, c, c, a); + for ( let i = 0, l = array.length; i < l; i += 3 ) { + + const a = array[ i + 0 ]; + const b = array[ i + 1 ]; + const c = array[ i + 2 ]; + + indices.push( a, b, b, c, c, a ); + } + } else { + const array = geometryPosition.array; version = geometryPosition.version; - for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { + for ( let i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) { + const a = i + 0; const b = i + 1; const c = i + 2; - indices.push(a, b, b, c, c, a); + + 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 + const attribute = new ( arrayNeedsUint32( indices ) ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 ); + attribute.version = version; + + // Updating index buffer in VAO now. See WebGLBindingStates + + // + + const previousAttribute = wireframeAttributes.get( geometry ); + + if ( previousAttribute ) attributes.remove( previousAttribute ); + // - const previousAttribute = wireframeAttributes.get(geometry); - if (previousAttribute) attributes.remove(previousAttribute); // + wireframeAttributes.set( geometry, attribute ); - wireframeAttributes.set(geometry, attribute); } - function getWireframeAttribute(geometry) { - const currentAttribute = wireframeAttributes.get(geometry); + function getWireframeAttribute( geometry ) { + + const currentAttribute = wireframeAttributes.get( geometry ); + + if ( currentAttribute ) { - if (currentAttribute) { const geometryIndex = geometry.index; - if (geometryIndex !== null) { + if ( geometryIndex !== null ) { + // if the attribute is obsolete, create a new one - if (currentAttribute.version < geometryIndex.version) { - updateWireframeAttribute(geometry); + + if ( currentAttribute.version < geometryIndex.version ) { + + updateWireframeAttribute( geometry ); + } + } + } else { - updateWireframeAttribute(geometry); + + updateWireframeAttribute( geometry ); + } - return wireframeAttributes.get(geometry); + return wireframeAttributes.get( geometry ); + } return { + get: get, update: update, + getWireframeAttribute: getWireframeAttribute + }; + } -function WebGLIndexedBufferRenderer(gl, extensions, info, capabilities) { +function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) { + const isWebGL2 = capabilities.isWebGL2; + let mode; - function setMode(value) { + function setMode( value ) { + mode = value; + } let type, bytesPerElement; - function setIndex(value) { + 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 render( start, count ) { + + gl.drawElements( mode, count, type, start * bytesPerElement ); + + info.update( count, mode, 1 ); + } - function renderInstances(start, count, primcount) { - if (primcount === 0) return; + function renderInstances( start, count, primcount ) { + + if ( primcount === 0 ) return; + let extension, methodName; - if (isWebGL2) { + if ( isWebGL2 ) { + extension = gl; methodName = 'drawElementsInstanced'; + } else { - extension = extensions.get('ANGLE_instanced_arrays'); + + 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.'); + 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); - } // + extension[ methodName ]( mode, count, type, start * bytesPerElement, primcount ); + + info.update( count, mode, primcount ); + + } + // this.setMode = setMode; this.setIndex = setIndex; this.render = render; this.renderInstances = renderInstances; + } -function WebGLInfo(gl) { +function WebGLInfo( gl ) { + const memory = { geometries: 0, textures: 0 }; + const render = { frame: 0, calls: 0, @@ -12861,20 +16729,22 @@ function WebGLInfo(gl) { lines: 0 }; - function update(count, mode, instanceCount) { - render.calls++; + function update( count, mode, instanceCount ) { + + render.calls ++; + + switch ( mode ) { - switch (mode) { case gl.TRIANGLES: - render.triangles += instanceCount * (count / 3); + render.triangles += instanceCount * ( count / 3 ); break; case gl.LINES: - render.lines += instanceCount * (count / 2); + render.lines += instanceCount * ( count / 2 ); break; case gl.LINE_STRIP: - render.lines += instanceCount * (count - 1); + render.lines += instanceCount * ( count - 1 ); break; case gl.LINE_LOOP: @@ -12886,17 +16756,21 @@ function WebGLInfo(gl) { break; default: - console.error('THREE.WebGLInfo: Unknown draw mode:', mode); + console.error( 'THREE.WebGLInfo: Unknown draw mode:', mode ); break; + } + } function reset() { - render.frame++; + + render.frame ++; render.calls = 0; render.triangles = 0; render.points = 0; render.lines = 0; + } return { @@ -12907,264 +16781,370 @@ function WebGLInfo(gl) { reset: reset, update: update }; -} -function numericalSort(a, b) { - return a[0] - b[0]; } -function absNumericalSort(a, b) { - return Math.abs(b[1]) - Math.abs(a[1]); +function numericalSort( a, b ) { + + return a[ 0 ] - b[ 0 ]; + } -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 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 absNumericalSort( a, b ) { + + return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] ); + } -function WebGLMorphtargets(gl, capabilities, textures) { +function WebGLMorphtargets( gl, capabilities, textures ) { + const influencesList = {}; - const morphInfluences = new Float32Array(8); + 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]; + for ( let i = 0; i < 8; i ++ ) { + + workInfluences[ i ] = [ i, 0 ]; + } - function update(object, geometry, material, program) { + function update( object, geometry, material, program ) { + const objectInfluences = object.morphTargetInfluences; - if (capabilities.isWebGL2 === true) { + 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); + const morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0; + + let entry = morphTextures.get( geometry ); + + if ( entry === undefined || entry.count !== morphTargetsCount ) { + + if ( entry !== undefined ) entry.texture.dispose(); - if (entry === undefined || entry.count !== morphTargetsCount) { - if (entry !== undefined) entry.texture.dispose(); const hasMorphPosition = geometry.morphAttributes.position !== undefined; const hasMorphNormals = geometry.morphAttributes.normal !== undefined; const hasMorphColors = geometry.morphAttributes.color !== undefined; + const morphTargets = geometry.morphAttributes.position || []; const morphNormals = geometry.morphAttributes.normal || []; const morphColors = geometry.morphAttributes.color || []; + let vertexDataCount = 0; - if (hasMorphPosition === true) vertexDataCount = 1; - if (hasMorphNormals === true) vertexDataCount = 2; - if (hasMorphColors === true) vertexDataCount = 3; + + if ( hasMorphPosition === true ) vertexDataCount = 1; + if ( hasMorphNormals === true ) vertexDataCount = 2; + 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); + 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); + 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; + + // 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]; + 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++) { + 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 ( hasMorphPosition === true ) { + + morph.fromBufferAttribute( morphTarget, j ); + + 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 ( hasMorphNormals === true ) { + + morph.fromBufferAttribute( morphNormal, j ); + + 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; - buffer[offset + stride + 11] = morphColor.itemSize === 4 ? morph.w : 1; + if ( hasMorphColors === true ) { + + morph.fromBufferAttribute( morphColor, j ); + + buffer[ offset + stride + 8 ] = morph.x; + buffer[ offset + stride + 9 ] = morph.y; + buffer[ offset + stride + 10 ] = morph.z; + buffer[ offset + stride + 11 ] = ( morphColor.itemSize === 4 ) ? morph.w : 1; + } + } + } entry = { count: morphTargetsCount, texture: texture, - size: new Vector2(width, height) + size: new Vector2( width, height ) }; - morphTextures.set(geometry, entry); + + morphTextures.set( geometry, entry ); function disposeTexture() { + texture.dispose(); - morphTextures.delete(geometry); - geometry.removeEventListener('dispose', disposeTexture); + + morphTextures.delete( geometry ); + + geometry.removeEventListener( 'dispose', disposeTexture ); + } - geometry.addEventListener('dispose', disposeTexture); - } // + geometry.addEventListener( 'dispose', disposeTexture ); + } + + // let morphInfluencesSum = 0; - for (let i = 0; i < objectInfluences.length; i++) { - morphInfluencesSum += objectInfluences[i]; + 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); - program.getUniforms().setValue(gl, 'morphTargetsTexture', entry.texture, textures); - program.getUniforms().setValue(gl, 'morphTargetsTextureSize', entry.size); + + program.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence ); + program.getUniforms().setValue( gl, 'morphTargetInfluences', objectInfluences ); + + program.getUniforms().setValue( gl, 'morphTargetsTexture', entry.texture, textures ); + program.getUniforms().setValue( gl, 'morphTargetsTextureSize', entry.size ); + + } 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) { + let influences = influencesList[ geometry.id ]; + + if ( influences === undefined || influences.length !== length ) { + // initialise list + influences = []; - for (let i = 0; i < length; i++) { - influences[i] = [i, 0]; + for ( let i = 0; i < length; i ++ ) { + + influences[ i ] = [ i, 0 ]; + } - influencesList[geometry.id] = influences; - } // Collect influences + influencesList[ geometry.id ] = influences; + + } + + // Collect influences + + for ( let i = 0; i < length; i ++ ) { + const influence = influences[ i ]; + + influence[ 0 ] = i; + influence[ 1 ] = objectInfluences[ i ]; - for (let i = 0; i < length; i++) { - const influence = influences[i]; - influence[0] = i; - influence[1] = objectInfluences[i]; } - influences.sort(absNumericalSort); + influences.sort( absNumericalSort ); + + for ( let i = 0; i < 8; i ++ ) { + + if ( i < length && influences[ i ][ 1 ] ) { + + workInfluences[ i ][ 0 ] = influences[ i ][ 0 ]; + workInfluences[ i ][ 1 ] = influences[ i ][ 1 ]; - for (let i = 0; i < 8; i++) { - if (i < length && influences[i][1]) { - workInfluences[i][0] = influences[i][0]; - workInfluences[i][1] = influences[i][1]; } else { - workInfluences[i][0] = Number.MAX_SAFE_INTEGER; - workInfluences[i][1] = 0; + + workInfluences[ i ][ 0 ] = Number.MAX_SAFE_INTEGER; + workInfluences[ i ][ 1 ] = 0; + } + } - workInfluences.sort(numericalSort); + 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]; + 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 (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]); + if ( morphNormals && geometry.getAttribute( 'morphNormal' + i ) !== morphNormals[ index ] ) { + + geometry.setAttribute( 'morphNormal' + i, morphNormals[ index ] ); + } - morphInfluences[i] = value; + morphInfluences[ i ] = value; morphInfluencesSum += value; + } else { - if (morphTargets && geometry.hasAttribute('morphTarget' + i) === true) { - geometry.deleteAttribute('morphTarget' + i); + + if ( morphTargets && geometry.hasAttribute( 'morphTarget' + i ) === true ) { + + geometry.deleteAttribute( 'morphTarget' + i ); + } - if (morphNormals && geometry.hasAttribute('morphNormal' + i) === true) { - geometry.deleteAttribute('morphNormal' + i); + if ( morphNormals && geometry.hasAttribute( 'morphNormal' + i ) === true ) { + + geometry.deleteAttribute( 'morphNormal' + i ); + } - morphInfluences[i] = 0; + 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 ); - const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; - program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence); - program.getUniforms().setValue(gl, 'morphTargetInfluences', morphInfluences); } + } return { + update: update + }; + } -function WebGLObjects(gl, geometries, attributes, info) { +function WebGLObjects( gl, geometries, attributes, info ) { + let updateMap = new WeakMap(); - function update(object) { + 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 (updateMap.get(buffergeometry) !== frame) { - geometries.update(buffergeometry); - updateMap.set(buffergeometry, frame); } - if (object.isInstancedMesh) { - if (object.hasEventListener('dispose', onInstancedMeshDispose) === false) { - object.addEventListener('dispose', onInstancedMeshDispose); + if ( object.isInstancedMesh ) { + + if ( object.hasEventListener( 'dispose', onInstancedMeshDispose ) === false ) { + + object.addEventListener( 'dispose', onInstancedMeshDispose ); + } - attributes.update(object.instanceMatrix, gl.ARRAY_BUFFER); + attributes.update( object.instanceMatrix, gl.ARRAY_BUFFER ); + + if ( object.instanceColor !== null ) { + + attributes.update( object.instanceColor, gl.ARRAY_BUFFER ); - if (object.instanceColor !== null) { - attributes.update(object.instanceColor, gl.ARRAY_BUFFER); } + } return buffergeometry; + } function dispose() { + updateMap = new WeakMap(); + } - function onInstancedMeshDispose(event) { + function onInstancedMeshDispose( event ) { + const instancedMesh = event.target; - instancedMesh.removeEventListener('dispose', onInstancedMeshDispose); - attributes.remove(instancedMesh.instanceMatrix); - if (instancedMesh.instanceColor !== null) attributes.remove(instancedMesh.instanceColor); + + instancedMesh.removeEventListener( 'dispose', onInstancedMeshDispose ); + + attributes.remove( instancedMesh.instanceMatrix ); + + if ( instancedMesh.instanceColor !== null ) attributes.remove( instancedMesh.instanceColor ); + } return { + update: update, dispose: dispose + }; + } /** @@ -13184,7 +17164,7 @@ function WebGLObjects(gl, geometries, attributes, info) { * .setValue( gl, value, [textures] ) * * uploads a uniform value(s) - * the 'textures' parameter is needed for sampler uniforms + * the 'textures' parameter is needed for sampler uniforms * * * Static methods of the top-level container (textures factorizations): @@ -13202,824 +17182,584 @@ function WebGLObjects(gl, geometries, attributes, info) { * * .setValue( gl, name, value, textures ) * - * sets uniform with name 'name' to 'value' + * sets uniform with name 'name' to 'value' * * .setOptional( gl, obj, prop ) * * like .set for an optional property of the object * */ -const emptyTexture = new Texture(); -const emptyArrayTexture = new DataArrayTexture(); -const empty3dTexture = new Data3DTexture(); -const emptyCubeTexture = new CubeTexture(); // --- Utilities --- + +const emptyTexture = /*@__PURE__*/ new Texture(); +const emptyArrayTexture = /*@__PURE__*/ new DataArrayTexture(); +const empty3dTexture = /*@__PURE__*/ new Data3DTexture(); +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 ); -const mat4array = new Float32Array(16); -const mat3array = new Float32Array(9); -const mat2array = new Float32Array(4); // Flattening for arrays of vectors and matrices +// 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 ) +function flatten( array, nBlocks, blockSize ) { + + const firstElem = array[ 0 ]; + + if ( firstElem <= 0 || firstElem > 0 ) return array; + // unoptimized: ! isNaN( firstElem ) // see http://jacksondunstan.com/articles/983 const n = nBlocks * blockSize; - let r = arrayCacheF32[n]; + let r = arrayCacheF32[ n ]; + + if ( r === undefined ) { + + r = new Float32Array( n ); + arrayCacheF32[ n ] = r; - if (r === undefined) { - r = new Float32Array(n); - arrayCacheF32[n] = r; } - if (nBlocks !== 0) { - firstElem.toArray(r, 0); + if ( nBlocks !== 0 ) { + + firstElem.toArray( r, 0 ); + + for ( let i = 1, offset = 0; i !== nBlocks; ++ i ) { - for (let i = 1, offset = 0; i !== nBlocks; ++i) { offset += blockSize; - array[i].toArray(r, offset); + array[ i ].toArray( r, offset ); + } + } return r; + } -function arraysEqual(a, b) { - if (a.length !== b.length) return false; +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; - 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]; +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 ]; -function allocTexUnits(textures, n) { - let r = arrayCacheI32[n]; + if ( r === undefined ) { + + r = new Int32Array( n ); + arrayCacheI32[ n ] = r; - if (r === undefined) { - r = new Int32Array(n); - arrayCacheI32[n] = r; } - for (let i = 0; i !== n; ++i) { - r[i] = textures.allocateTextureUnit(); + 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 +function setValueV1f( gl, v ) { -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) + if ( cache[ 0 ] === v ) return; -function setValueV2f(gl, v) { - const cache = this.cache; + gl.uniform1f( this.addr, v ); + + cache[ 0 ] = v; - if (v.x !== undefined) { - if (cache[0] !== v.x || cache[1] !== v.y) { - gl.uniform2f(this.addr, v.x, v.y); - cache[0] = v.x; - cache[1] = v.y; - } - } else { - if (arraysEqual(cache, v)) return; - gl.uniform2fv(this.addr, v); - copyArray(cache, v); - } } -function setValueV3f(gl, v) { - const cache = this.cache; +// Single float vector (from flat array or THREE.VectorN) - if (v.x !== undefined) { - if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) { - gl.uniform3f(this.addr, v.x, v.y, v.z); - cache[0] = v.x; - cache[1] = v.y; - cache[2] = v.z; - } - } else if (v.r !== undefined) { - if (cache[0] !== v.r || cache[1] !== v.g || cache[2] !== v.b) { - gl.uniform3f(this.addr, v.r, v.g, v.b); - cache[0] = v.r; - cache[1] = v.g; - cache[2] = v.b; - } - } else { - if (arraysEqual(cache, v)) return; - gl.uniform3fv(this.addr, v); - copyArray(cache, v); - } -} +function setValueV2f( gl, 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); - cache[0] = v.x; - cache[1] = v.y; - cache[2] = v.z; - cache[3] = v.w; - } - } else { - if (arraysEqual(cache, v)) return; - gl.uniform4fv(this.addr, v); - copyArray(cache, v); - } -} // Single matrix (from flat array or THREE.MatrixN) + if ( v.x !== undefined ) { + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { -function setValueM2(gl, v) { - const cache = this.cache; - const elements = v.elements; + gl.uniform2f( this.addr, v.x, v.y ); - if (elements === undefined) { - if (arraysEqual(cache, v)) return; - gl.uniformMatrix2fv(this.addr, false, v); - copyArray(cache, v); - } else { - if (arraysEqual(cache, elements)) return; - mat2array.set(elements); - gl.uniformMatrix2fv(this.addr, false, mat2array); - copyArray(cache, elements); - } -} + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; -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); - copyArray(cache, v); } else { - if (arraysEqual(cache, elements)) return; - mat3array.set(elements); - gl.uniformMatrix3fv(this.addr, false, mat3array); - copyArray(cache, elements); - } -} -function setValueM4(gl, v) { - const cache = this.cache; - const elements = v.elements; - - if (elements === undefined) { - if (arraysEqual(cache, v)) return; - gl.uniformMatrix4fv(this.addr, false, v); - copyArray(cache, v); - } else { - if (arraysEqual(cache, elements)) return; - mat4array.set(elements); - gl.uniformMatrix4fv(this.addr, false, mat4array); - copyArray(cache, elements); - } -} // Single integer / boolean + if ( arraysEqual( cache, v ) ) return; + gl.uniform2fv( this.addr, v ); -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) + copyArray( cache, v ); + } -function setValueV2i(gl, v) { - const cache = this.cache; - 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); -} +function setValueV3f( gl, 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 ) { -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) + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) { + gl.uniform3f( this.addr, v.x, v.y, v.z ); -function setValueV2ui(gl, v) { - const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform2uiv(this.addr, v); - copyArray(cache, v); -} + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + cache[ 2 ] = v.z; -function setValueV3ui(gl, v) { - const cache = this.cache; - 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) + } else if ( v.r !== undefined ) { + if ( cache[ 0 ] !== v.r || cache[ 1 ] !== v.g || cache[ 2 ] !== v.b ) { -function setValueT1(gl, v, textures) { - const cache = this.cache; - const unit = textures.allocateTextureUnit(); + gl.uniform3f( this.addr, v.r, v.g, v.b ); - if (cache[0] !== unit) { - gl.uniform1i(this.addr, unit); - cache[0] = unit; - } + cache[ 0 ] = v.r; + cache[ 1 ] = v.g; + cache[ 2 ] = v.b; - textures.setTexture2D(v || emptyTexture, unit); -} + } -function setValueT3D1(gl, v, textures) { - const cache = this.cache; - const unit = textures.allocateTextureUnit(); + } else { - if (cache[0] !== unit) { - gl.uniform1i(this.addr, unit); - cache[0] = unit; - } + if ( arraysEqual( cache, v ) ) return; - textures.setTexture3D(v || empty3dTexture, unit); -} + gl.uniform3fv( this.addr, v ); -function setValueT6(gl, v, textures) { - const cache = this.cache; - const unit = textures.allocateTextureUnit(); + copyArray( cache, v ); - if (cache[0] !== unit) { - gl.uniform1i(this.addr, unit); - cache[0] = unit; } - textures.setTextureCube(v || emptyCubeTexture, unit); } -function setValueT2DArray1(gl, v, textures) { +function setValueV4f( gl, v ) { + const cache = this.cache; - const unit = textures.allocateTextureUnit(); - if (cache[0] !== unit) { - gl.uniform1i(this.addr, unit); - cache[0] = unit; - } + if ( v.x !== undefined ) { - textures.setTexture2DArray(v || emptyArrayTexture, unit); -} // Helper to pick the right setter for the singular case + 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 ); -function getSingularSetter(type) { - switch (type) { - case 0x1406: - return setValueV1f; - // FLOAT + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + cache[ 2 ] = v.z; + cache[ 3 ] = v.w; - case 0x8b50: - return setValueV2f; - // _VEC2 + } - case 0x8b51: - return setValueV3f; - // _VEC3 + } else { - case 0x8b52: - return setValueV4f; - // _VEC4 + if ( arraysEqual( cache, v ) ) return; - case 0x8b5a: - return setValueM2; - // _MAT2 + gl.uniform4fv( this.addr, v ); - case 0x8b5b: - return setValueM3; - // _MAT3 + copyArray( cache, v ); - case 0x8b5c: - return setValueM4; - // _MAT4 + } - case 0x1404: - case 0x8b56: - return setValueV1i; - // INT, BOOL +} - case 0x8b53: - case 0x8b57: - return setValueV2i; - // _VEC2 +// Single matrix (from flat array or THREE.MatrixN) - case 0x8b54: - case 0x8b58: - return setValueV3i; - // _VEC3 +function setValueM2( gl, v ) { - case 0x8b55: - case 0x8b59: - return setValueV4i; - // _VEC4 + const cache = this.cache; + const elements = v.elements; - case 0x1405: - return setValueV1ui; - // UINT + if ( elements === undefined ) { - case 0x8dc6: - return setValueV2ui; - // _VEC2 + if ( arraysEqual( cache, v ) ) return; - case 0x8dc7: - return setValueV3ui; - // _VEC3 + gl.uniformMatrix2fv( this.addr, false, v ); - case 0x8dc8: - return setValueV4ui; - // _VEC4 + copyArray( cache, v ); - case 0x8b5e: // SAMPLER_2D + } else { - case 0x8d66: // SAMPLER_EXTERNAL_OES + if ( arraysEqual( cache, elements ) ) return; - case 0x8dca: // INT_SAMPLER_2D + mat2array.set( elements ); - case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D + gl.uniformMatrix2fv( this.addr, false, mat2array ); - case 0x8b62: - // SAMPLER_2D_SHADOW - return setValueT1; + copyArray( cache, elements ); - case 0x8b5f: // SAMPLER_3D + } - case 0x8dcb: // INT_SAMPLER_3D +} - case 0x8dd3: - // UNSIGNED_INT_SAMPLER_3D - return setValueT3D1; +function setValueM3( gl, v ) { - case 0x8b60: // SAMPLER_CUBE + const cache = this.cache; + const elements = v.elements; - case 0x8dcc: // INT_SAMPLER_CUBE + if ( elements === undefined ) { - case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE + if ( arraysEqual( cache, v ) ) return; - case 0x8dc5: - // SAMPLER_CUBE_SHADOW - return setValueT6; + gl.uniformMatrix3fv( this.addr, false, v ); - case 0x8dc1: // SAMPLER_2D_ARRAY + copyArray( cache, v ); - case 0x8dcf: // INT_SAMPLER_2D_ARRAY + } else { - case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY + if ( arraysEqual( cache, elements ) ) return; - case 0x8dc4: - // SAMPLER_2D_ARRAY_SHADOW - return setValueT2DArray1; - } -} // Array of scalars + mat3array.set( elements ); + gl.uniformMatrix3fv( this.addr, false, mat3array ); -function setValueV1fArray(gl, v) { - gl.uniform1fv(this.addr, v); -} // Array of vectors (from flat array or array of THREE.VectorN) + copyArray( cache, elements ); + } -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 setValueM4( gl, v ) { + + const cache = this.cache; + const elements = v.elements; -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) + if ( elements === undefined ) { + if ( arraysEqual( cache, v ) ) return; -function setValueM2Array(gl, v) { - const data = flatten(v, this.size, 4); - gl.uniformMatrix2fv(this.addr, false, data); -} + gl.uniformMatrix4fv( this.addr, false, v ); -function setValueM3Array(gl, v) { - const data = flatten(v, this.size, 9); - gl.uniformMatrix3fv(this.addr, false, data); -} + copyArray( cache, v ); -function setValueM4Array(gl, v) { - const data = flatten(v, this.size, 16); - gl.uniformMatrix4fv(this.addr, false, data); -} // Array of integer / boolean + } else { + if ( arraysEqual( cache, elements ) ) return; -function setValueV1iArray(gl, v) { - gl.uniform1iv(this.addr, v); -} // Array of integer / boolean vectors (from flat array) + mat4array.set( elements ); + gl.uniformMatrix4fv( this.addr, false, mat4array ); -function setValueV2iArray(gl, v) { - gl.uniform2iv(this.addr, v); -} + copyArray( cache, elements ); + + } -function setValueV3iArray(gl, v) { - gl.uniform3iv(this.addr, v); } -function setValueV4iArray(gl, v) { - gl.uniform4iv(this.addr, v); -} // Array of unsigned integer +// Single integer / boolean +function setValueV1i( gl, v ) { -function setValueV1uiArray(gl, v) { - gl.uniform1uiv(this.addr, v); -} // Array of unsigned integer vectors (from flat array) + const cache = this.cache; + if ( cache[ 0 ] === v ) return; -function setValueV2uiArray(gl, v) { - gl.uniform2uiv(this.addr, v); -} + gl.uniform1i( this.addr, v ); + + cache[ 0 ] = 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) +// Single integer / boolean vector (from flat array or THREE.VectorN) +function setValueV2i( gl, v ) { -function setValueT1Array(gl, v, textures) { - const n = v.length; - const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); + const cache = this.cache; - for (let i = 0; i !== n; ++i) { - textures.setTexture2D(v[i] || emptyTexture, units[i]); - } -} + if ( v.x !== undefined ) { -function setValueT3DArray(gl, v, textures) { - const n = v.length; - const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { - for (let i = 0; i !== n; ++i) { - textures.setTexture3D(v[i] || empty3dTexture, units[i]); - } -} + gl.uniform2i( this.addr, v.x, v.y ); -function setValueT6Array(gl, v, textures) { - const n = v.length; - const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + + } + + } else { + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform2iv( this.addr, v ); + + copyArray( cache, v ); - for (let i = 0; i !== n; ++i) { - textures.setTextureCube(v[i] || emptyCubeTexture, units[i]); } + } -function setValueT2DArrayArray(gl, v, textures) { - const n = v.length; - const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); +function setValueV3i( gl, v ) { + + const cache = this.cache; + + 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 ); - 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 +} -function getPureArraySetter(type) { - switch (type) { - case 0x1406: - return setValueV1fArray; - // FLOAT +function setValueV4i( gl, v ) { - case 0x8b50: - return setValueV2fArray; - // _VEC2 + const cache = this.cache; - case 0x8b51: - return setValueV3fArray; - // _VEC3 + if ( v.x !== undefined ) { - case 0x8b52: - return setValueV4fArray; - // _VEC4 + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) { - case 0x8b5a: - return setValueM2Array; - // _MAT2 + gl.uniform4i( this.addr, v.x, v.y, v.z, v.w ); - case 0x8b5b: - return setValueM3Array; - // _MAT3 + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + cache[ 2 ] = v.z; + cache[ 3 ] = v.w; - case 0x8b5c: - return setValueM4Array; - // _MAT4 + } - case 0x1404: - case 0x8b56: - return setValueV1iArray; - // INT, BOOL + } else { - case 0x8b53: - case 0x8b57: - return setValueV2iArray; - // _VEC2 + if ( arraysEqual( cache, v ) ) return; - case 0x8b54: - case 0x8b58: - return setValueV3iArray; - // _VEC3 + gl.uniform4iv( this.addr, v ); - case 0x8b55: - case 0x8b59: - return setValueV4iArray; - // _VEC4 + copyArray( cache, v ); - case 0x1405: - return setValueV1uiArray; - // UINT + } - case 0x8dc6: - return setValueV2uiArray; - // _VEC2 +} - case 0x8dc7: - return setValueV3uiArray; - // _VEC3 +// Single unsigned integer - case 0x8dc8: - return setValueV4uiArray; - // _VEC4 +function setValueV1ui( gl, v ) { - case 0x8b5e: // SAMPLER_2D + const cache = this.cache; - case 0x8d66: // SAMPLER_EXTERNAL_OES + if ( cache[ 0 ] === v ) return; - case 0x8dca: // INT_SAMPLER_2D + gl.uniform1ui( this.addr, v ); - case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D + cache[ 0 ] = v; - case 0x8b62: - // SAMPLER_2D_SHADOW - return setValueT1Array; +} - case 0x8b5f: // SAMPLER_3D +// Single unsigned integer vector (from flat array or THREE.VectorN) - case 0x8dcb: // INT_SAMPLER_3D +function setValueV2ui( gl, v ) { - case 0x8dd3: - // UNSIGNED_INT_SAMPLER_3D - return setValueT3DArray; + const cache = this.cache; - case 0x8b60: // SAMPLER_CUBE + if ( v.x !== undefined ) { - case 0x8dcc: // INT_SAMPLER_CUBE + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { - case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE + gl.uniform2ui( this.addr, v.x, v.y ); - case 0x8dc5: - // SAMPLER_CUBE_SHADOW - return setValueT6Array; + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; - case 0x8dc1: // SAMPLER_2D_ARRAY + } - case 0x8dcf: // INT_SAMPLER_2D_ARRAY + } else { - case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY + if ( arraysEqual( cache, v ) ) return; - case 0x8dc4: - // SAMPLER_2D_ARRAY_SHADOW - return setValueT2DArrayArray; - } -} // --- Uniform Classes --- + gl.uniform2uiv( this.addr, v ); + copyArray( cache, v ); -class SingleUniform { - constructor(id, activeInfo, addr) { - this.id = id; - this.addr = addr; - this.cache = []; - this.setValue = getSingularSetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG } } -class PureArrayUniform { - constructor(id, activeInfo, addr) { - this.id = id; - this.addr = addr; - this.cache = []; - this.size = activeInfo.size; - this.setValue = getPureArraySetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG - } +function setValueV3ui( gl, v ) { -} + const cache = this.cache; -class StructuredUniform { - constructor(id) { - this.id = id; - this.seq = []; - this.map = {}; - } + if ( v.x !== undefined ) { - setValue(gl, value, textures) { - const seq = this.seq; + 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; - for (let i = 0, n = seq.length; i !== n; ++i) { - const u = seq[i]; - u.setValue(gl, value[u.id], textures); } - } -} // --- Top-level --- -// Parser - builds up the property tree from the path strings + } else { + if ( arraysEqual( cache, v ) ) return; -const RePathPart = /(\w+)(\])?(\[|\.)?/g; // extracts -// - the identifier (member name or array index) -// - followed by an optional right bracket (found when array index) -// - followed by an optional left bracket or dot (type of subscript) -// -// Note: These portions can be read in a non-overlapping fashion and -// allow straightforward parsing of the hierarchy that WebGL encodes -// in the uniform names. + gl.uniform3uiv( this.addr, v ); + + copyArray( cache, v ); + + } -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 +function setValueV4ui( gl, v ) { - RePathPart.lastIndex = 0; + const cache = this.cache; - while (true) { - const match = RePathPart.exec(path), - matchEnd = RePathPart.lastIndex; - let id = match[1]; - const idIsIndex = match[2] === ']', - subscript = match[3]; - if (idIsIndex) id = id | 0; // convert to integer + if ( v.x !== undefined ) { - 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 ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) { - if (next === undefined) { - next = new StructuredUniform(id); - addUniform(container, next); - } + 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; - container = next; } - } -} // Root Container + } else { -class WebGLUniforms { - constructor(gl, program) { - this.seq = []; - this.map = {}; - const n = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + if ( arraysEqual( cache, v ) ) return; - for (let i = 0; i < n; ++i) { - const info = gl.getActiveUniform(program, i), - addr = gl.getUniformLocation(program, info.name); - parseUniform(info, addr, this); - } - } + gl.uniform4uiv( this.addr, v ); - setValue(gl, name, value, textures) { - const u = this.map[name]; - if (u !== undefined) u.setValue(gl, value, textures); - } + copyArray( cache, v ); - 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]; +} + - if (v.needsUpdate !== false) { - // note: always updating when .needsUpdate is undefined - u.setValue(gl, v.value, textures); - } - } - } +// Single texture (2D / Cube) - static seqWithValue(seq, values) { - const r = []; +function setValueT1( gl, v, textures ) { - for (let i = 0, n = seq.length; i !== n; ++i) { - const u = seq[i]; - if (u.id in values) r.push(u); - } + const cache = this.cache; + const unit = textures.allocateTextureUnit(); + + if ( cache[ 0 ] !== unit ) { + + gl.uniform1i( this.addr, unit ); + cache[ 0 ] = unit; - return r; } -} + textures.setTexture2D( v || emptyTexture, unit ); -function WebGLShader(gl, type, string) { - const shader = gl.createShader(type); - gl.shaderSource(shader, string); - gl.compileShader(shader); - return shader; } -let programIdCount = 0; +function setValueT3D1( gl, v, textures ) { -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); + const cache = this.cache; + const unit = textures.allocateTextureUnit(); + + if ( cache[ 0 ] !== unit ) { + + gl.uniform1i( this.addr, unit ); + cache[ 0 ] = unit; +<<<<<<< HEAD for (let i = from; i < to; i++) { const line = i + 1; lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`); +======= +>>>>>>> mrdoob-dev } - return lines2.join('\n'); + textures.setTexture3D( v || empty3dTexture, unit ); + } -function getEncodingComponents(encoding) { - switch (encoding) { - case LinearEncoding: - return ['Linear', '( value )']; +function setValueT6( gl, v, textures ) { - case sRGBEncoding: - return ['sRGB', '( value )']; + const cache = this.cache; + const unit = textures.allocateTextureUnit(); + + if ( cache[ 0 ] !== unit ) { + + gl.uniform1i( this.addr, unit ); + cache[ 0 ] = unit; - default: - console.warn('THREE.WebGLProgram: Unsupported encoding:', encoding); - return ['Linear', '( value )']; } + + textures.setTextureCube( v || emptyCubeTexture, unit ); + } -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); +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; + +<<<<<<< HEAD if (errorMatches) { // --enable-privileged-webgl-extension // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); @@ -14027,261 +17767,165 @@ function getShaderErrors(gl, shader, type) { return type.toUpperCase() + '\n\n' + errors + '\n\n' + handleSource(gl.getShaderSource(shader), errorLine); } else { return errors; +======= +>>>>>>> mrdoob-dev } -} -function getTexelEncodingFunction(functionName, encoding) { - const components = getEncodingComponents(encoding); - return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[0] + components[1] + '; }'; + textures.setTexture2DArray( v || emptyArrayTexture, unit ); + } -function getToneMappingFunction(functionName, toneMapping) { - let toneMappingName; +// Helper to pick the right setter for the singular case - switch (toneMapping) { - case LinearToneMapping: - toneMappingName = 'Linear'; - break; +function getSingularSetter( type ) { - case ReinhardToneMapping: - toneMappingName = 'Reinhard'; - break; + switch ( type ) { - case CineonToneMapping: - toneMappingName = 'OptimizedCineon'; - break; + case 0x1406: return setValueV1f; // FLOAT + case 0x8b50: return setValueV2f; // _VEC2 + case 0x8b51: return setValueV3f; // _VEC3 + case 0x8b52: return setValueV4f; // _VEC4 - case ACESFilmicToneMapping: - toneMappingName = 'ACESFilmic'; - break; + case 0x8b5a: return setValueM2; // _MAT2 + case 0x8b5b: return setValueM3; // _MAT3 + case 0x8b5c: return setValueM4; // _MAT4 - case CustomToneMapping: - toneMappingName = 'Custom'; - break; + case 0x1404: 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; // _VEC4 - default: - console.warn('THREE.WebGLProgram: Unsupported toneMapping:', toneMapping); - toneMappingName = 'Linear'; - } + case 0x1405: return setValueV1ui; // UINT + case 0x8dc6: return setValueV2ui; // _VEC2 + case 0x8dc7: return setValueV3ui; // _VEC3 + case 0x8dc8: return setValueV4ui; // _VEC4 - return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }'; -} + 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; -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'); -} + case 0x8b5f: // SAMPLER_3D + case 0x8dcb: // INT_SAMPLER_3D + case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D + return setValueT3D1; -function generateDefines(defines) { - const chunks = []; + 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; - 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 ); +// Array of scalars - attributes[name] = { - type: info.type, - location: gl.getAttribLocation(program, name), - locationSize: locationSize - }; - } +function setValueV1fArray( gl, v ) { - return attributes; -} + gl.uniform1fv( this.addr, v ); -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); -} +// Array of vectors (from flat array or array of THREE.VectorN) -function replaceClippingPlaneNums(string, parameters) { - return string.replace(/NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, parameters.numClippingPlanes - parameters.numClipIntersection); -} // Resolve Includes +function setValueV2fArray( gl, v ) { + const data = flatten( v, this.size, 2 ); -const includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; + gl.uniform2fv( this.addr, data ); -function resolveIncludes(string) { - return string.replace(includePattern, includeReplacer); } -function includeReplacer(match, include) { - const string = ShaderChunk[include]; +function setValueV3fArray( gl, v ) { - if (string === undefined) { - throw new Error('Can not resolve #include <' + include + '>'); - } + const data = flatten( v, this.size, 3 ); - return resolveIncludes(string); -} // Unroll Loops + gl.uniform3fv( this.addr, data ); +} -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 setValueV4fArray( gl, v ) { + + const data = flatten( v, this.size, 4 ); + + gl.uniform4fv( this.addr, data ); -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); +// 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 loopReplacer(match, start, end, snippet) { - let string = ''; +function setValueM3Array( gl, v ) { - for (let i = parseInt(start); i < parseInt(end); i++) { - string += snippet.replace(/\[\s*i\s*\]/g, '[ ' + i + ' ]').replace(/UNROLLED_LOOP_INDEX/g, i); - } + const data = flatten( v, this.size, 9 ); - return string; -} // + gl.uniformMatrix3fv( this.addr, false, data ); +} -function generatePrecision(parameters) { - let precisionstring = 'precision ' + parameters.precision + ' float;\nprecision ' + parameters.precision + ' int;'; +function setValueM4Array( gl, v ) { - if (parameters.precision === 'highp') { - precisionstring += '\n#define HIGH_PRECISION'; - } else if (parameters.precision === 'mediump') { - precisionstring += '\n#define MEDIUM_PRECISION'; - } else if (parameters.precision === 'lowp') { - precisionstring += '\n#define LOW_PRECISION'; - } + const data = flatten( v, this.size, 16 ); + + gl.uniformMatrix4fv( this.addr, false, data ); - return precisionstring; } -function generateShadowMapTypeDefine(parameters) { - let shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; +// Array of integer / boolean - if (parameters.shadowMapType === PCFShadowMap) { - shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; - } else if (parameters.shadowMapType === PCFSoftShadowMap) { - shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; - } else if (parameters.shadowMapType === VSMShadowMap) { - shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; - } +function setValueV1iArray( gl, v ) { + + gl.uniform1iv( this.addr, v ); - return shadowMapTypeDefine; } -function generateEnvMapTypeDefine(parameters) { - let envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; +// Array of integer / boolean vectors (from flat array) - if (parameters.envMap) { - switch (parameters.envMapMode) { - case CubeReflectionMapping: - case CubeRefractionMapping: - envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; - break; +function setValueV2iArray( gl, v ) { - case CubeUVReflectionMapping: - envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; - break; - } - } + gl.uniform2iv( this.addr, v ); - return envMapTypeDefine; } -function generateEnvMapModeDefine(parameters) { - let envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; +function setValueV3iArray( gl, v ) { - if (parameters.envMap) { - switch (parameters.envMapMode) { - case CubeRefractionMapping: - envMapModeDefine = 'ENVMAP_MODE_REFRACTION'; - break; - } - } + gl.uniform3iv( this.addr, v ); - 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; - } - } +function setValueV4iArray( gl, v ) { - return envMapBlendingDefine; -} + gl.uniform4iv( this.addr, v ); -function generateCubeUVSize(parameters) { - const imageHeight = parameters.envMapCubeUVHeight; - if (imageHeight === null) return null; - const maxMip = Math.log2(imageHeight) - 2; - const texelHeight = 1.0 / imageHeight; - const texelWidth = 1.0 / (3 * Math.max(Math.pow(2, maxMip), 7 * 16)); - return { - texelWidth, - texelHeight, - 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; - let fragmentShader = parameters.fragmentShader; - const shadowMapTypeDefine = generateShadowMapTypeDefine(parameters); - const envMapTypeDefine = generateEnvMapTypeDefine(parameters); - const envMapModeDefine = generateEnvMapModeDefine(parameters); - const envMapBlendingDefine = generateEnvMapBlendingDefine(parameters); - const envMapCubeUVSize = generateCubeUVSize(parameters); - const customExtensions = parameters.isWebGL2 ? '' : generateExtensions(parameters); - const customDefines = generateDefines(defines); - const program = gl.createProgram(); - let prefixVertex, prefixFragment; - let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : ''; +// Array of unsigned integer - if (parameters.isRawShaderMaterial) { - prefixVertex = [customDefines].filter(filterEmptyLine).join('\n'); +function setValueV1uiArray( gl, v ) { - if (prefixVertex.length > 0) { - prefixVertex += '\n'; - } + gl.uniform1uiv( this.addr, v ); - prefixFragment = [customExtensions, customDefines].filter(filterEmptyLine).join('\n'); +} +<<<<<<< HEAD if (prefixFragment.length > 0) { prefixFragment += '\n'; } @@ -14329,254 +17973,124 @@ function WebGLProgram(renderer, cacheKey, parameters, bindingStates) { const glFragmentShader = WebGLShader(gl, gl.FRAGMENT_SHADER, fragmentGlsl); gl.attachShader(program, glVertexShader); gl.attachShader(program, glFragmentShader); // Force a particular attribute to index 0. +======= +// Array of unsigned integer vectors (from flat array) - if (parameters.index0AttributeName !== undefined) { - gl.bindAttribLocation(program, 0, parameters.index0AttributeName); - } else if (parameters.morphTargets === true) { - // programs with morphTargets displace position out of attribute 0 - gl.bindAttribLocation(program, 0, 'position'); - } +function setValueV2uiArray( gl, v ) { - gl.linkProgram(program); // check for link errors + gl.uniform2uiv( this.addr, v ); +>>>>>>> mrdoob-dev - 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'); - const fragmentErrors = getShaderErrors(gl, glFragmentShader, 'fragment'); - console.error('THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' + 'VALIDATE_STATUS ' + gl.getProgramParameter(program, gl.VALIDATE_STATUS) + '\n\n' + 'Program Info Log: ' + programLog + '\n' + vertexErrors + '\n' + fragmentErrors); - } else if (programLog !== '') { - console.warn('THREE.WebGLProgram: Program Info Log:', programLog); - } else if (vertexLog === '' || fragmentLog === '') { - haveDiagnostics = false; - } +function setValueV3uiArray( gl, v ) { - if (haveDiagnostics) { - this.diagnostics = { - runnable: runnable, - programLog: programLog, - vertexShader: { - log: vertexLog, - prefix: prefixVertex - }, - fragmentShader: { - log: fragmentLog, - prefix: prefixFragment - } - }; - } - } // Clean up - // Crashes in iOS9 and iOS10. #18402 - // gl.detachShader( program, glVertexShader ); - // gl.detachShader( program, glFragmentShader ); + gl.uniform3uiv( this.addr, v ); + +} +function setValueV4uiArray( gl, v ) { - gl.deleteShader(glVertexShader); - gl.deleteShader(glFragmentShader); // set up caching for uniform locations + gl.uniform4uiv( this.addr, v ); - let cachedUniforms; +} - this.getUniforms = function () { - if (cachedUniforms === undefined) { - cachedUniforms = new WebGLUniforms(gl, program); - } - return cachedUniforms; - }; // set up caching for attribute locations +// Array of textures (2D / 3D / Cube / 2DArray) +function setValueT1Array( gl, v, textures ) { - let cachedAttributes; + const cache = this.cache; - this.getAttributes = function () { - if (cachedAttributes === undefined) { - cachedAttributes = fetchAttributeLocations(gl, program); - } + const n = v.length; - return cachedAttributes; - }; // free resource + const units = allocTexUnits( textures, n ); + if ( ! arraysEqual( cache, units ) ) { - this.destroy = function () { - bindingStates.releaseStatesOfProgram(this); - gl.deleteProgram(program); - this.program = undefined; - }; // + gl.uniform1iv( this.addr, units ); + copyArray( cache, units ); - this.name = parameters.shaderName; - this.id = programIdCount++; - this.cacheKey = cacheKey; - this.usedTimes = 1; - this.program = program; - this.vertexShader = glVertexShader; - this.fragmentShader = glFragmentShader; - return this; -} + } -let _id = 0; + for ( let i = 0; i !== n; ++ i ) { + + textures.setTexture2D( v[ i ] || emptyTexture, units[ i ] ); -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); +function setValueT3DArray( gl, v, textures ) { - const fragmentShaderStage = this._getShaderStage(fragmentShader); + const cache = this.cache; - const materialShaders = this._getShaderCacheForMaterial(material); + const n = v.length; - if (materialShaders.has(vertexShaderStage) === false) { - materialShaders.add(vertexShaderStage); - vertexShaderStage.usedTimes++; - } + const units = allocTexUnits( textures, n ); - if (materialShaders.has(fragmentShaderStage) === false) { - materialShaders.add(fragmentShaderStage); - fragmentShaderStage.usedTimes++; - } + if ( ! arraysEqual( cache, units ) ) { + + gl.uniform1iv( this.addr, units ); + + copyArray( cache, units ); - return this; } - remove(material) { - const materialShaders = this.materialCache.get(material); + for ( let i = 0; i !== n; ++ i ) { - for (const shaderStage of materialShaders) { - shaderStage.usedTimes--; - if (shaderStage.usedTimes === 0) this.shaderCache.delete(shaderStage.code); - } + textures.setTexture3D( v[ i ] || empty3dTexture, units[ i ] ); - this.materialCache.delete(material); - return this; } - getVertexShaderID(material) { - return this._getShaderStage(material.vertexShader).id; - } +} - getFragmentShaderID(material) { - return this._getShaderStage(material.fragmentShader).id; - } +function setValueT6Array( gl, v, textures ) { - dispose() { - this.shaderCache.clear(); - this.materialCache.clear(); - } + const cache = this.cache; - _getShaderCacheForMaterial(material) { - const cache = this.materialCache; + const n = v.length; - if (cache.has(material) === false) { - cache.set(material, new Set()); - } + const units = allocTexUnits( textures, n ); - return cache.get(material); - } + if ( ! arraysEqual( cache, units ) ) { - _getShaderStage(code) { - const cache = this.shaderCache; + gl.uniform1iv( this.addr, units ); - if (cache.has(code) === false) { - const stage = new WebGLShaderStage(code); - cache.set(code, stage); - } + copyArray( cache, units ); - return cache.get(code); } -} + for ( let i = 0; i !== n; ++ i ) { + + textures.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] ); -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; - const vertexTextures = capabilities.vertexTextures; - let precision = capabilities.precision; - const shaderIDs = { - MeshDepthMaterial: 'depth', - MeshDistanceMaterial: 'distanceRGBA', - MeshNormalMaterial: 'normal', - MeshBasicMaterial: 'basic', - MeshLambertMaterial: 'lambert', - MeshPhongMaterial: 'phong', - MeshToonMaterial: 'toon', - MeshStandardMaterial: 'physical', - MeshPhysicalMaterial: 'physical', - MeshMatcapMaterial: 'matcap', - LineBasicMaterial: 'basic', - LineDashedMaterial: 'dashed', - PointsMaterial: 'points', - ShadowMaterial: 'shadow', - SpriteMaterial: 'sprite' - }; +function setValueT2DArrayArray( gl, v, textures ) { - 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 - // (not to blow over maxLights budget) + const cache = this.cache; - if (material.precision !== null) { - precision = capabilities.getMaxPrecision(material.precision); + const n = v.length; - if (precision !== material.precision) { - console.warn('THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.'); - } - } // + const units = allocTexUnits( textures, n ); + if ( ! arraysEqual( cache, units ) ) { - 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; // + gl.uniform1iv( this.addr, units ); - let vertexShader, fragmentShader; - let customVertexShaderID, customFragmentShaderID; + copyArray( cache, units ); - if (shaderID) { - const shader = ShaderLib[shaderID]; - vertexShader = shader.vertexShader; - fragmentShader = shader.fragmentShader; - } else { - vertexShader = material.vertexShader; - fragmentShader = material.fragmentShader; + } - _customShaders.update(material); + for ( let i = 0; i !== n; ++ i ) { - customVertexShaderID = _customShaders.getVertexShaderID(material); - customFragmentShaderID = _customShaders.getFragmentShaderID(material); - } + textures.setTexture2DArray( v[ i ] || emptyArrayTexture, units[ i ] ); +<<<<<<< HEAD const currentRenderTarget = renderer.getRenderTarget(); const useAlphaTest = material.alphaTest > 0; const useClearcoat = material.clearcoat > 0; @@ -14683,31 +18197,18 @@ function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, extraProgramCacheKey: renderer.extraProgramCacheKey }; return parameters; +======= +>>>>>>> mrdoob-dev } - 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]); - } - } +// Helper to pick the right setter for a pure (bottom-level) array - if (parameters.isRawShaderMaterial === false) { - getProgramCacheKeyParameters(array, parameters); - getProgramCacheKeyBooleans(array, parameters); - array.push(renderer.outputEncoding); - } +function getPureArraySetter( type ) { +<<<<<<< HEAD array.push(parameters.customProgramCacheKey); if (renderer.extraProgramCacheKey) { @@ -14716,4147 +18217,2182 @@ function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, return array.join(); } +======= + switch ( type ) { +>>>>>>> mrdoob-dev - function getProgramCacheKeyParameters(array, parameters) { - array.push(parameters.precision); - array.push(parameters.outputEncoding); - array.push(parameters.envMapMode); - array.push(parameters.envMapCubeUVHeight); - array.push(parameters.combine); - array.push(parameters.vertexUvs); - array.push(parameters.fogExp2); - array.push(parameters.sizeAttenuation); - array.push(parameters.morphTargetsCount); - array.push(parameters.morphAttributeCount); - array.push(parameters.numDirLights); - array.push(parameters.numPointLights); - array.push(parameters.numSpotLights); - array.push(parameters.numHemiLights); - array.push(parameters.numRectAreaLights); - array.push(parameters.numDirLightShadows); - array.push(parameters.numPointLightShadows); - array.push(parameters.numSpotLightShadows); - 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(); + case 0x1406: return setValueV1fArray; // FLOAT + case 0x8b50: return setValueV2fArray; // _VEC2 + case 0x8b51: return setValueV3fArray; // _VEC3 + case 0x8b52: return setValueV4fArray; // _VEC4 - if (parameters.isWebGL2) _programLayers.enable(0); - if (parameters.supportsVertexTextures) _programLayers.enable(1); - if (parameters.instancing) _programLayers.enable(2); - if (parameters.instancingColor) _programLayers.enable(3); - if (parameters.map) _programLayers.enable(4); - if (parameters.matcap) _programLayers.enable(5); - if (parameters.envMap) _programLayers.enable(6); - if (parameters.lightMap) _programLayers.enable(7); - if (parameters.aoMap) _programLayers.enable(8); - if (parameters.emissiveMap) _programLayers.enable(9); - if (parameters.bumpMap) _programLayers.enable(10); - if (parameters.normalMap) _programLayers.enable(11); - if (parameters.objectSpaceNormalMap) _programLayers.enable(12); - if (parameters.tangentSpaceNormalMap) _programLayers.enable(13); - if (parameters.clearcoat) _programLayers.enable(14); - if (parameters.clearcoatMap) _programLayers.enable(15); - if (parameters.clearcoatRoughnessMap) _programLayers.enable(16); - if (parameters.clearcoatNormalMap) _programLayers.enable(17); - if (parameters.iridescence) _programLayers.enable(18); - if (parameters.iridescenceMap) _programLayers.enable(19); - if (parameters.iridescenceThicknessMap) _programLayers.enable(20); - if (parameters.displacementMap) _programLayers.enable(21); - if (parameters.specularMap) _programLayers.enable(22); - if (parameters.roughnessMap) _programLayers.enable(23); - if (parameters.metalnessMap) _programLayers.enable(24); - if (parameters.gradientMap) _programLayers.enable(25); - if (parameters.alphaMap) _programLayers.enable(26); - if (parameters.alphaTest) _programLayers.enable(27); - if (parameters.vertexColors) _programLayers.enable(28); - if (parameters.vertexAlphas) _programLayers.enable(29); - 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); + case 0x8b5a: return setValueM2Array; // _MAT2 + case 0x8b5b: return setValueM3Array; // _MAT3 + case 0x8b5c: return setValueM4Array; // _MAT4 - _programLayers.disableAll(); + case 0x1404: 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; // _VEC4 - 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); - array.push(_programLayers.mask); - } - - function getUniforms(material) { - const shaderID = shaderIDs[material.type]; - let uniforms; + case 0x1405: return setValueV1uiArray; // UINT + case 0x8dc6: return setValueV2uiArray; // _VEC2 + case 0x8dc7: return setValueV3uiArray; // _VEC3 + case 0x8dc8: return setValueV4uiArray; // _VEC4 - if (shaderID) { - const shader = ShaderLib[shaderID]; - uniforms = UniformsUtils.clone(shader.uniforms); - } else { - uniforms = material.uniforms; - } + 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; - return uniforms; } - function acquireProgram(parameters, cacheKey) { - let program; // Check if code has been already compiled +} - for (let p = 0, pl = programs.length; p < pl; p++) { - const preexistingProgram = programs[p]; +// --- Uniform Classes --- - if (preexistingProgram.cacheKey === cacheKey) { - program = preexistingProgram; - ++program.usedTimes; - break; - } - } +class SingleUniform { - if (program === undefined) { - program = new WebGLProgram(renderer, cacheKey, parameters, bindingStates); - programs.push(program); - } + constructor( id, activeInfo, addr ) { - return program; - } + this.id = id; + this.addr = addr; + this.cache = []; + this.setValue = getSingularSetter( activeInfo.type ); - 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 + // this.path = activeInfo.name; // DEBUG - program.destroy(); - } } - function releaseShaderCache(material) { - _customShaders.remove(material); - } +} + +class PureArrayUniform { + + constructor( id, activeInfo, addr ) { + + this.id = id; + this.addr = addr; + this.cache = []; + this.size = activeInfo.size; + this.setValue = getPureArraySetter( activeInfo.type ); + + // this.path = activeInfo.name; // DEBUG - function dispose() { - _customShaders.dispose(); } - return { - getParameters: getParameters, - getProgramCacheKey: getProgramCacheKey, - getUniforms: getUniforms, - acquireProgram: acquireProgram, - releaseProgram: releaseProgram, - releaseShaderCache: releaseShaderCache, - // Exposed for resource monitoring & error feedback via renderer.info: - programs: programs, - dispose: dispose - }; } -function WebGLProperties() { - let properties = new WeakMap(); +class StructuredUniform { - function get(object) { - let map = properties.get(object); + constructor( id ) { - if (map === undefined) { - map = {}; - properties.set(object, map); - } + this.id = id; - return map; - } + this.seq = []; + this.map = {}; - function remove(object) { - properties.delete(object); } - function update(object, key, value) { - properties.get(object)[key] = value; - } + setValue( gl, value, textures ) { - function dispose() { - properties = new WeakMap(); - } + const seq = this.seq; - return { - get: get, - remove: remove, - update: update, - dispose: dispose - }; -} + for ( let i = 0, n = seq.length; i !== n; ++ i ) { + + const u = seq[ i ]; + u.setValue( gl, value[ u.id ], textures ); + + } -function painterSortStable(a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else if (a.material.id !== b.material.id) { - return a.material.id - b.material.id; - } else if (a.z !== b.z) { - return a.z - b.z; - } else { - return a.id - b.id; } + } -function reversePainterSortStable(a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else if (a.z !== b.z) { - return b.z - a.z; - } else { - return a.id - b.id; - } +// --- Top-level --- + +// Parser - builds up the property tree from the path strings + +const RePathPart = /(\w+)(\])?(\[|\.)?/g; + +// extracts +// - the identifier (member name or array index) +// - followed by an optional right bracket (found when array index) +// - followed by an optional left bracket or dot (type of subscript) +// +// Note: These portions can be read in a non-overlapping fashion and +// allow straightforward parsing of the hierarchy that WebGL encodes +// in the uniform names. + +function addUniform( container, uniformObject ) { + + container.seq.push( uniformObject ); + container.map[ uniformObject.id ] = uniformObject; + } -function WebGLRenderList() { - const renderItems = []; - let renderItemsIndex = 0; - const opaque = []; - const transmissive = []; - const transparent = []; +function parseUniform( activeInfo, addr, container ) { - function init() { - renderItemsIndex = 0; - opaque.length = 0; - transmissive.length = 0; - transparent.length = 0; - } + const path = activeInfo.name, + pathLength = path.length; - function getNextRenderItem(object, geometry, material, groupOrder, z, group) { - let renderItem = renderItems[renderItemsIndex]; + // reset RegExp object, because of the early exit of a previous run + RePathPart.lastIndex = 0; - if (renderItem === undefined) { - renderItem = { - id: object.id, - object: object, - geometry: geometry, - material: material, - groupOrder: groupOrder, - renderOrder: object.renderOrder, - z: z, - group: group - }; - renderItems[renderItemsIndex] = renderItem; - } else { - renderItem.id = object.id; - renderItem.object = object; - renderItem.geometry = geometry; - renderItem.material = material; - renderItem.groupOrder = groupOrder; - renderItem.renderOrder = object.renderOrder; - renderItem.z = z; - renderItem.group = group; - } + while ( true ) { - renderItemsIndex++; - return renderItem; - } + const match = RePathPart.exec( path ), + matchEnd = RePathPart.lastIndex; - function push(object, geometry, material, groupOrder, z, group) { - const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); + let id = match[ 1 ]; + const idIsIndex = match[ 2 ] === ']', + subscript = match[ 3 ]; - if (material.transmission > 0.0) { - transmissive.push(renderItem); - } else if (material.transparent === true) { - transparent.push(renderItem); - } else { - opaque.push(renderItem); - } - } + 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 ) ); - function unshift(object, geometry, material, groupOrder, z, group) { - const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); + break; - if (material.transmission > 0.0) { - transmissive.unshift(renderItem); - } else if (material.transparent === true) { - transparent.unshift(renderItem); } else { - 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); - } + // 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; - 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; - renderItem.id = null; - renderItem.object = null; - renderItem.geometry = null; - renderItem.material = null; - renderItem.group = null; } + } - return { - opaque: opaque, - transmissive: transmissive, - transparent: transparent, - init: init, - push: push, - unshift: unshift, - finish: finish, - sort: sort - }; } -function WebGLRenderLists() { - let lists = new WeakMap(); +// Root Container - function get(scene, renderCallDepth) { - let list; +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 ); + + parseUniform( info, addr, this ); - if (lists.has(scene) === false) { - list = new WebGLRenderList(); - lists.set(scene, [list]); - } else { - if (renderCallDepth >= lists.get(scene).length) { - list = new WebGLRenderList(); - lists.get(scene).push(list); - } else { - list = lists.get(scene)[renderCallDepth]; - } } - return list; } - function dispose() { - lists = new WeakMap(); + setValue( gl, name, value, textures ) { + + const u = this.map[ name ]; + + if ( u !== undefined ) u.setValue( gl, value, textures ); + } - return { - get: get, - dispose: dispose - }; -} + setOptional( gl, object, name ) { -function UniformsCache() { - const lights = {}; - return { - get: function (light) { - if (lights[light.id] !== undefined) { - return lights[light.id]; - } + const v = object[ name ]; - let uniforms; + if ( v !== undefined ) this.setValue( gl, name, v ); - switch (light.type) { - case 'DirectionalLight': - uniforms = { - direction: new Vector3(), - color: new Color() - }; - break; + } - case 'SpotLight': - uniforms = { - position: new Vector3(), - direction: new Vector3(), - color: new Color(), - distance: 0, - coneCos: 0, - penumbraCos: 0, - decay: 0 - }; - break; + static upload( gl, seq, values, textures ) { - case 'PointLight': - uniforms = { - position: new Vector3(), - color: new Color(), - distance: 0, - decay: 0 - }; - break; + for ( let i = 0, n = seq.length; i !== n; ++ i ) { - case 'HemisphereLight': - uniforms = { - direction: new Vector3(), - skyColor: new Color(), - groundColor: new Color() - }; - break; + const u = seq[ i ], + v = values[ u.id ]; + + if ( v.needsUpdate !== false ) { + + // note: always updating when .needsUpdate is undefined + u.setValue( gl, v.value, textures ); - case 'RectAreaLight': - uniforms = { - color: new Color(), - position: new Vector3(), - halfWidth: new Vector3(), - halfHeight: new Vector3() - }; - break; } - lights[light.id] = uniforms; - return uniforms; } - }; -} -function ShadowUniformsCache() { - const lights = {}; - return { - get: function (light) { - if (lights[light.id] !== undefined) { - return lights[light.id]; - } + } - let uniforms; + static seqWithValue( seq, values ) { - switch (light.type) { - case 'DirectionalLight': - uniforms = { - shadowBias: 0, - shadowNormalBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2() - }; - break; + const r = []; - case 'SpotLight': - uniforms = { - shadowBias: 0, - shadowNormalBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2() - }; - break; + for ( let i = 0, n = seq.length; i !== n; ++ i ) { - case 'PointLight': - uniforms = { - shadowBias: 0, - shadowNormalBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2(), - shadowCameraNear: 1, - shadowCameraFar: 1000 - }; - break; - // TODO (abelnation): set RectAreaLight shadow uniforms - } + const u = seq[ i ]; + if ( u.id in values ) r.push( u ); - lights[light.id] = uniforms; - return uniforms; } - }; -} -let nextVersion = 0; + return r; + + } -function shadowCastingLightsFirst(lightA, lightB) { - return (lightB.castShadow ? 1 : 0) - (lightA.castShadow ? 1 : 0); } -function WebGLLights(extensions, capabilities) { - const cache = new UniformsCache(); - const shadowCache = ShadowUniformsCache(); - const state = { - version: 0, - hash: { - directionalLength: -1, - pointLength: -1, - spotLength: -1, - rectAreaLength: -1, - hemiLength: -1, - numDirectionalShadows: -1, - numPointShadows: -1, - numSpotShadows: -1 - }, - ambient: [0, 0, 0], - probe: [], - directional: [], - directionalShadow: [], - directionalShadowMap: [], - directionalShadowMatrix: [], - spot: [], - spotShadow: [], - spotShadowMap: [], - spotShadowMatrix: [], - rectArea: [], - rectAreaLTC1: null, - rectAreaLTC2: null, - point: [], - pointShadow: [], - pointShadowMap: [], - pointShadowMatrix: [], - hemi: [] - }; +function WebGLShader( gl, type, string ) { - for (let i = 0; i < 9; i++) state.probe.push(new Vector3()); + const shader = gl.createShader( type ); - const vector3 = new Vector3(); - const matrix4 = new Matrix4(); - const matrix42 = new Matrix4(); + gl.shaderSource( shader, string ); + gl.compileShader( shader ); - function setup(lights, physicallyCorrectLights) { - let r = 0, - g = 0, - b = 0; - - for (let i = 0; i < 9; i++) state.probe[i].set(0, 0, 0); + return shader; - let directionalLength = 0; - let pointLength = 0; - let spotLength = 0; - let rectAreaLength = 0; - let hemiLength = 0; - let numDirectionalShadows = 0; - let numPointShadows = 0; - let numSpotShadows = 0; - lights.sort(shadowCastingLightsFirst); // artist-friendly light intensity scaling factor +} - const scaleFactor = physicallyCorrectLights !== true ? Math.PI : 1; +let programIdCount = 0; - 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; +function handleSource( string, errorLine ) { - if (light.isAmbientLight) { - r += color.r * intensity * scaleFactor; - g += color.g * intensity * scaleFactor; - b += color.b * intensity * scaleFactor; - } else if (light.isLightProbe) { - for (let j = 0; j < 9; j++) { - state.probe[j].addScaledVector(light.sh.coefficients[j], intensity); - } - } else if (light.isDirectionalLight) { - const uniforms = cache.get(light); - uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor); + const lines = string.split( '\n' ); + const lines2 = []; - if (light.castShadow) { - const shadow = light.shadow; - const shadowUniforms = shadowCache.get(light); - shadowUniforms.shadowBias = shadow.bias; - shadowUniforms.shadowNormalBias = shadow.normalBias; - shadowUniforms.shadowRadius = shadow.radius; - shadowUniforms.shadowMapSize = shadow.mapSize; - state.directionalShadow[directionalLength] = shadowUniforms; - state.directionalShadowMap[directionalLength] = shadowMap; - state.directionalShadowMatrix[directionalLength] = light.shadow.matrix; - numDirectionalShadows++; - } - - state.directional[directionalLength] = uniforms; - directionalLength++; - } else if (light.isSpotLight) { - const uniforms = cache.get(light); - uniforms.position.setFromMatrixPosition(light.matrixWorld); - uniforms.color.copy(color).multiplyScalar(intensity * scaleFactor); - uniforms.distance = distance; - uniforms.coneCos = Math.cos(light.angle); - uniforms.penumbraCos = Math.cos(light.angle * (1 - light.penumbra)); - uniforms.decay = light.decay; + const from = Math.max( errorLine - 6, 0 ); + const to = Math.min( errorLine + 6, lines.length ); - if (light.castShadow) { - const shadow = light.shadow; - const shadowUniforms = shadowCache.get(light); - shadowUniforms.shadowBias = shadow.bias; - shadowUniforms.shadowNormalBias = shadow.normalBias; - shadowUniforms.shadowRadius = shadow.radius; - shadowUniforms.shadowMapSize = shadow.mapSize; - state.spotShadow[spotLength] = shadowUniforms; - state.spotShadowMap[spotLength] = shadowMap; - state.spotShadowMatrix[spotLength] = light.shadow.matrix; - numSpotShadows++; - } - - 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); - uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0); - state.rectArea[rectAreaLength] = uniforms; - rectAreaLength++; - } else if (light.isPointLight) { - const uniforms = cache.get(light); - uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor); - uniforms.distance = light.distance; - uniforms.decay = light.decay; + for ( let i = from; i < to; i ++ ) { - if (light.castShadow) { - const shadow = light.shadow; - const shadowUniforms = shadowCache.get(light); - shadowUniforms.shadowBias = shadow.bias; - shadowUniforms.shadowNormalBias = shadow.normalBias; - shadowUniforms.shadowRadius = shadow.radius; - shadowUniforms.shadowMapSize = shadow.mapSize; - shadowUniforms.shadowCameraNear = shadow.camera.near; - shadowUniforms.shadowCameraFar = shadow.camera.far; - state.pointShadow[pointLength] = shadowUniforms; - state.pointShadowMap[pointLength] = shadowMap; - state.pointShadowMatrix[pointLength] = light.shadow.matrix; - numPointShadows++; - } + const line = i + 1; + lines2.push( `${line === errorLine ? '>' : ' '} ${line}: ${lines[ i ]}` ); - state.point[pointLength] = uniforms; - pointLength++; - } else if (light.isHemisphereLight) { - const uniforms = cache.get(light); - uniforms.skyColor.copy(light.color).multiplyScalar(intensity * scaleFactor); - uniforms.groundColor.copy(light.groundColor).multiplyScalar(intensity * scaleFactor); - state.hemi[hemiLength] = uniforms; - 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; - } else if (extensions.has('OES_texture_half_float_linear') === true) { - state.rectAreaLTC1 = UniformsLib.LTC_HALF_1; - state.rectAreaLTC2 = UniformsLib.LTC_HALF_2; - } else { - console.error('THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.'); - } - } - } + return lines2.join( '\n' ); - 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) { - state.directional.length = directionalLength; - state.spot.length = spotLength; - state.rectArea.length = rectAreaLength; - state.point.length = pointLength; - state.hemi.length = hemiLength; - state.directionalShadow.length = numDirectionalShadows; - state.directionalShadowMap.length = numDirectionalShadows; - state.pointShadow.length = numPointShadows; - state.pointShadowMap.length = numPointShadows; - state.spotShadow.length = numSpotShadows; - state.spotShadowMap.length = numSpotShadows; - state.directionalShadowMatrix.length = numDirectionalShadows; - state.pointShadowMatrix.length = numPointShadows; - state.spotShadowMatrix.length = numSpotShadows; - hash.directionalLength = directionalLength; - hash.pointLength = pointLength; - hash.spotLength = spotLength; - hash.rectAreaLength = rectAreaLength; - hash.hemiLength = hemiLength; - hash.numDirectionalShadows = numDirectionalShadows; - hash.numPointShadows = numPointShadows; - hash.numSpotShadows = numSpotShadows; - state.version = nextVersion++; - } - } +function getEncodingComponents( encoding ) { - function setupView(lights, camera) { - let directionalLength = 0; - let pointLength = 0; - let spotLength = 0; - let rectAreaLength = 0; - let hemiLength = 0; - const viewMatrix = camera.matrixWorldInverse; + switch ( encoding ) { - 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); - vector3.setFromMatrixPosition(light.target.matrixWorld); - uniforms.direction.sub(vector3); - uniforms.direction.transformDirection(viewMatrix); - directionalLength++; - } else if (light.isSpotLight) { - const uniforms = state.spot[spotLength]; - uniforms.position.setFromMatrixPosition(light.matrixWorld); - uniforms.position.applyMatrix4(viewMatrix); - uniforms.direction.setFromMatrixPosition(light.matrixWorld); - vector3.setFromMatrixPosition(light.target.matrixWorld); - uniforms.direction.sub(vector3); - uniforms.direction.transformDirection(viewMatrix); - spotLength++; - } 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 + case LinearEncoding: + return [ 'Linear', '( value )' ]; + case sRGBEncoding: + return [ 'sRGB', '( value )' ]; + default: + console.warn( 'THREE.WebGLProgram: Unsupported encoding:', encoding ); + return [ 'Linear', '( value )' ]; - matrix42.identity(); - matrix4.copy(light.matrixWorld); - matrix4.premultiply(viewMatrix); - matrix42.extractRotation(matrix4); - uniforms.halfWidth.set(light.width * 0.5, 0.0, 0.0); - uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0); - uniforms.halfWidth.applyMatrix4(matrix42); - uniforms.halfHeight.applyMatrix4(matrix42); - rectAreaLength++; - } else if (light.isPointLight) { - const uniforms = state.point[pointLength]; - uniforms.position.setFromMatrixPosition(light.matrixWorld); - uniforms.position.applyMatrix4(viewMatrix); - pointLength++; - } else if (light.isHemisphereLight) { - const uniforms = state.hemi[hemiLength]; - uniforms.direction.setFromMatrixPosition(light.matrixWorld); - uniforms.direction.transformDirection(viewMatrix); - hemiLength++; - } - } } - return { - setup: setup, - setupView: setupView, - state: state - }; } -function WebGLRenderState(extensions, capabilities) { - const lights = new WebGLLights(extensions, capabilities); - const lightsArray = []; - const shadowsArray = []; +function getShaderErrors( gl, shader, type ) { - function init() { - lightsArray.length = 0; - shadowsArray.length = 0; - } + const status = gl.getShaderParameter( shader, gl.COMPILE_STATUS ); + const errors = gl.getShaderInfoLog( shader ).trim(); - function pushLight(light) { - lightsArray.push(light); - } + if ( status && errors === '' ) return ''; - function pushShadow(shadowLight) { - shadowsArray.push(shadowLight); - } + const errorMatches = /ERROR: 0:(\d+)/.exec( errors ); + if ( errorMatches ) { - function setupLights(physicallyCorrectLights) { - lights.setup(lightsArray, physicallyCorrectLights); - } + // --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 setupLightsView(camera) { - lights.setupView(lightsArray, camera); } - const state = { - lightsArray: lightsArray, - shadowsArray: shadowsArray, - lights: lights - }; - return { - init: init, - state: state, - setupLights: setupLights, - setupLightsView: setupLightsView, - pushLight: pushLight, - pushShadow: pushShadow - }; } -function WebGLRenderStates(extensions, capabilities) { - let renderStates = new WeakMap(); +function getTexelEncodingFunction( functionName, encoding ) { - function get(scene, renderCallDepth = 0) { - let renderState; + const components = getEncodingComponents( encoding ); + return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[ 0 ] + components[ 1 ] + '; }'; - if (renderStates.has(scene) === false) { - renderState = new WebGLRenderState(extensions, capabilities); - renderStates.set(scene, [renderState]); - } else { - if (renderCallDepth >= renderStates.get(scene).length) { - renderState = new WebGLRenderState(extensions, capabilities); - renderStates.get(scene).push(renderState); - } else { - renderState = renderStates.get(scene)[renderCallDepth]; - } - } +} - return renderState; - } +function getToneMappingFunction( functionName, toneMapping ) { - function dispose() { - renderStates = new WeakMap(); - } + let toneMappingName; - return { - get: get, - dispose: dispose - }; -} + switch ( toneMapping ) { -class MeshDepthMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshDepthMaterial = true; - this.type = 'MeshDepthMaterial'; - this.depthPacking = BasicDepthPacking; - this.map = null; - this.alphaMap = null; - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.setValues(parameters); - } + case LinearToneMapping: + toneMappingName = 'Linear'; + break; - copy(source) { - super.copy(source); - this.depthPacking = source.depthPacking; - this.map = source.map; - this.alphaMap = source.alphaMap; - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - return this; - } + case ReinhardToneMapping: + toneMappingName = 'Reinhard'; + break; -} + case CineonToneMapping: + toneMappingName = 'OptimizedCineon'; + break; -class MeshDistanceMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshDistanceMaterial = true; - this.type = 'MeshDistanceMaterial'; - this.referencePosition = new Vector3(); - this.nearDistance = 1; - this.farDistance = 1000; - this.map = null; - this.alphaMap = null; - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.setValues(parameters); - } + case ACESFilmicToneMapping: + toneMappingName = 'ACESFilmic'; + break; + + case CustomToneMapping: + toneMappingName = 'Custom'; + break; + + default: + console.warn( 'THREE.WebGLProgram: Unsupported toneMapping:', toneMapping ); + toneMappingName = 'Linear'; - copy(source) { - super.copy(source); - this.referencePosition.copy(source.referencePosition); - this.nearDistance = source.nearDistance; - this.farDistance = source.farDistance; - this.map = source.map; - this.alphaMap = source.alphaMap; - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - return this; } + return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }'; + } -const vertex = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; -const fragment = "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}"; +function generateExtensions( parameters ) { -function WebGLShadowMap(_renderer, _objects, _capabilities) { - let _frustum = new Frustum(); + 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' : '' + ]; - const _shadowMapSize = new Vector2(), - _viewportSize = new Vector2(), - _viewport = new Vector4(), - _depthMaterial = new MeshDepthMaterial({ - depthPacking: RGBADepthPacking - }), - _distanceMaterial = new MeshDistanceMaterial(), - _materialCache = {}, - _maxTextureSize = _capabilities.maxTextureSize; - - const shadowSide = { - 0: BackSide, - 1: FrontSide, - 2: DoubleSide - }; - const shadowMaterialVertical = new ShaderMaterial({ - defines: { - VSM_SAMPLES: 8 - }, - uniforms: { - shadow_pass: { - value: null - }, - resolution: { - value: new Vector2() - }, - radius: { - value: 4.0 - } - }, - vertexShader: vertex, - fragmentShader: fragment - }); - const shadowMaterialHorizontal = shadowMaterialVertical.clone(); - shadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1; - const fullScreenTri = new BufferGeometry(); - fullScreenTri.setAttribute('position', new BufferAttribute(new Float32Array([-1, -1, 0.5, 3, -1, 0.5, -1, 3, 0.5]), 3)); - const fullScreenMesh = new Mesh(fullScreenTri, shadowMaterialVertical); - const scope = this; - this.enabled = false; - this.autoUpdate = true; - this.needsUpdate = false; - this.type = PCFShadowMap; + return chunks.filter( filterEmptyLine ).join( '\n' ); - 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(); +function generateDefines( defines ) { - const activeCubeFace = _renderer.getActiveCubeFace(); + const chunks = []; - const activeMipmapLevel = _renderer.getActiveMipmapLevel(); + for ( const name in defines ) { - const _state = _renderer.state; // Set GL state for depth map. + const value = defines[ name ]; - _state.setBlending(NoBlending); + if ( value === false ) continue; - _state.buffers.color.setClear(1, 1, 1, 1); + chunks.push( '#define ' + name + ' ' + value ); - _state.buffers.depth.setTest(true); + } - _state.setScissorTest(false); // render depth map + return chunks.join( '\n' ); +} - for (let i = 0, il = lights.length; i < il; i++) { - const light = lights[i]; - const shadow = light.shadow; +function fetchAttributeLocations( gl, program ) { - if (shadow === undefined) { - console.warn('THREE.WebGLShadowMap:', light, 'has no shadow.'); - continue; - } + const attributes = {}; - if (shadow.autoUpdate === false && shadow.needsUpdate === false) continue; + const n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES ); - _shadowMapSize.copy(shadow.mapSize); + for ( let i = 0; i < n; i ++ ) { - const shadowFrameExtents = shadow.getFrameExtents(); + const info = gl.getActiveAttrib( program, i ); + const name = info.name; - _shadowMapSize.multiply(shadowFrameExtents); + 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; - _viewportSize.copy(shadow.mapSize); + // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); - 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 && !shadow.isPointLightShadow && this.type === VSMShadowMap) { - shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y); - shadow.map.texture.name = light.name + '.shadowMap'; - shadow.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y); - shadow.camera.updateProjectionMatrix(); - } - - if (shadow.map === null) { - const pars = { - minFilter: NearestFilter, - magFilter: NearestFilter, - format: RGBAFormat - }; - shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars); - shadow.map.texture.name = light.name + '.shadowMap'; - shadow.camera.updateProjectionMatrix(); - } - - _renderer.setRenderTarget(shadow.map); + attributes[ name ] = { + type: info.type, + location: gl.getAttribLocation( program, name ), + locationSize: locationSize + }; - _renderer.clear(); + } - const viewportCount = shadow.getViewportCount(); + return attributes; - 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); +function filterEmptyLine( string ) { - _state.viewport(_viewport); + return string !== ''; - shadow.updateMatrices(light, vp); - _frustum = shadow.getFrustum(); - renderObject(scene, camera, shadow.camera, light, this.type); - } // do blur pass for VSM +} +function replaceLightNums( string, parameters ) { - if (!shadow.isPointLightShadow && this.type === VSMShadowMap) { - VSMPass(shadow, camera); - } + const numSpotLightCoords = parameters.numSpotLightShadows + parameters.numSpotLightMaps - parameters.numSpotLightShadowsWithMaps; - shadow.needsUpdate = false; - } + 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 ); - scope.needsUpdate = false; +} - _renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel); - }; +function replaceClippingPlaneNums( string, parameters ) { - function VSMPass(shadow, camera) { - const geometry = _objects.update(fullScreenMesh); + return string + .replace( /NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes ) + .replace( /UNION_CLIPPING_PLANES/g, ( parameters.numClippingPlanes - parameters.numClipIntersection ) ); - 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; - } // vertical pass +} +// Resolve Includes - shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; - shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; - shadowMaterialVertical.uniforms.radius.value = shadow.radius; +const includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; - _renderer.setRenderTarget(shadow.mapPass); +function resolveIncludes( string ) { - _renderer.clear(); + return string.replace( includePattern, includeReplacer ); - _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); // horizontal pass +} +function includeReplacer( match, include ) { - shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture; - shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize; - shadowMaterialHorizontal.uniforms.radius.value = shadow.radius; + const string = ShaderChunk[ include ]; - _renderer.setRenderTarget(shadow.map); + if ( string === undefined ) { - _renderer.clear(); + throw new Error( 'Can not resolve #include <' + include + '>' ); - _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; + return resolveIncludes( string ); - if (customMaterial !== undefined) { - result = customMaterial; - } else { - result = light.isPointLight === true ? _distanceMaterial : _depthMaterial; - } +} - if (_renderer.localClippingEnabled && material.clipShadows === true && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0) { - // in this case we need a unique material instance reflecting the - // appropriate state - const keyA = result.uuid, - keyB = material.uuid; - let materialsForVariant = _materialCache[keyA]; +// Unroll Loops - if (materialsForVariant === undefined) { - materialsForVariant = {}; - _materialCache[keyA] = materialsForVariant; - } +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; - let cachedMaterial = materialsForVariant[keyB]; +function unrollLoops( string ) { - if (cachedMaterial === undefined) { - cachedMaterial = result.clone(); - materialsForVariant[keyB] = cachedMaterial; - } + return string.replace( unrollLoopPattern, loopReplacer ); - result = cachedMaterial; - } +} - result.visible = material.visible; - result.wireframe = material.wireframe; +function loopReplacer( match, start, end, snippet ) { - if (type === VSMShadowMap) { - result.side = material.shadowSide !== null ? material.shadowSide : material.side; - } else { - result.side = material.shadowSide !== null ? material.shadowSide : shadowSide[material.side]; - } + let string = ''; - result.alphaMap = material.alphaMap; - result.alphaTest = material.alphaTest; - result.clipShadows = material.clipShadows; - result.clippingPlanes = material.clippingPlanes; - result.clipIntersection = material.clipIntersection; - result.displacementMap = material.displacementMap; - result.displacementScale = material.displacementScale; - result.displacementBias = material.displacementBias; - result.wireframeLinewidth = material.wireframeLinewidth; - result.linewidth = material.linewidth; + for ( let i = parseInt( start ); i < parseInt( end ); i ++ ) { - if (light.isPointLight === true && result.isMeshDistanceMaterial === true) { - result.referencePosition.setFromMatrixPosition(light.matrixWorld); - result.nearDistance = shadowCameraNear; - result.farDistance = shadowCameraFar; - } + string += snippet + .replace( /\[\s*i\s*\]/g, '[ ' + i + ' ]' ) + .replace( /UNROLLED_LOOP_INDEX/g, i ); - 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; + return string; - 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); +function generatePrecision( parameters ) { - _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group); - } - } - } else if (material.visible) { - const depthMaterial = getDepthMaterial(object, material, light, shadowCamera.near, shadowCamera.far, type); + let precisionstring = 'precision ' + parameters.precision + ' float;\nprecision ' + parameters.precision + ' int;'; - _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, null); - } - } - } + if ( parameters.precision === 'highp' ) { - const children = object.children; + precisionstring += '\n#define HIGH_PRECISION'; - for (let i = 0, l = children.length; i < l; i++) { - renderObject(children[i], camera, shadowCamera, light, type); - } - } -} + } else if ( parameters.precision === 'mediump' ) { -function WebGLState(gl, extensions, capabilities) { - const isWebGL2 = capabilities.isWebGL2; + precisionstring += '\n#define MEDIUM_PRECISION'; - function ColorBuffer() { - let locked = false; - const color = new Vector4(); - let currentColorMask = null; - const currentColorClear = new Vector4(0, 0, 0, 0); - return { - setMask: function (colorMask) { - if (currentColorMask !== colorMask && !locked) { - gl.colorMask(colorMask, colorMask, colorMask, colorMask); - currentColorMask = colorMask; - } - }, - setLocked: function (lock) { - locked = lock; - }, - setClear: function (r, g, b, a, premultipliedAlpha) { - if (premultipliedAlpha === true) { - r *= a; - g *= a; - b *= a; - } + } else if ( parameters.precision === 'lowp' ) { - color.set(r, g, b, a); + precisionstring += '\n#define LOW_PRECISION'; - if (currentColorClear.equals(color) === false) { - gl.clearColor(r, g, b, a); - currentColorClear.copy(color); - } - }, - reset: function () { - locked = false; - currentColorMask = null; - currentColorClear.set(-1, 0, 0, 0); // set to invalid state - } - }; } - function DepthBuffer() { - let locked = false; - let currentDepthMask = null; - let currentDepthFunc = null; - let currentDepthClear = null; - return { - setTest: function (depthTest) { - if (depthTest) { - enable(gl.DEPTH_TEST); - } else { - disable(gl.DEPTH_TEST); - } - }, - setMask: function (depthMask) { - if (currentDepthMask !== depthMask && !locked) { - gl.depthMask(depthMask); - currentDepthMask = depthMask; - } - }, - setFunc: function (depthFunc) { - if (currentDepthFunc !== depthFunc) { - if (depthFunc) { - switch (depthFunc) { - case NeverDepth: - gl.depthFunc(gl.NEVER); - break; + return precisionstring; - case AlwaysDepth: - gl.depthFunc(gl.ALWAYS); - break; +} - case LessDepth: - gl.depthFunc(gl.LESS); - break; +function generateShadowMapTypeDefine( parameters ) { - case LessEqualDepth: - gl.depthFunc(gl.LEQUAL); - break; + let shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; - case EqualDepth: - gl.depthFunc(gl.EQUAL); - break; + if ( parameters.shadowMapType === PCFShadowMap ) { - case GreaterEqualDepth: - gl.depthFunc(gl.GEQUAL); - break; + shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; - case GreaterDepth: - gl.depthFunc(gl.GREATER); - break; + } else if ( parameters.shadowMapType === PCFSoftShadowMap ) { - case NotEqualDepth: - gl.depthFunc(gl.NOTEQUAL); - break; + shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; - default: - gl.depthFunc(gl.LEQUAL); - } - } else { - gl.depthFunc(gl.LEQUAL); - } + } else if ( parameters.shadowMapType === VSMShadowMap ) { + + shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; - currentDepthFunc = depthFunc; - } - }, - setLocked: function (lock) { - locked = lock; - }, - setClear: function (depth) { - if (currentDepthClear !== depth) { - gl.clearDepth(depth); - currentDepthClear = depth; - } - }, - reset: function () { - locked = false; - currentDepthMask = null; - currentDepthFunc = null; - currentDepthClear = null; - } - }; } - function StencilBuffer() { - let locked = false; - let currentStencilMask = null; - let currentStencilFunc = null; - let currentStencilRef = null; - let currentStencilFuncMask = null; - let currentStencilFail = null; - let currentStencilZFail = null; - let currentStencilZPass = null; - let currentStencilClear = null; - return { - setTest: function (stencilTest) { - if (!locked) { - if (stencilTest) { - enable(gl.STENCIL_TEST); - } else { - disable(gl.STENCIL_TEST); - } - } - }, - setMask: function (stencilMask) { - if (currentStencilMask !== stencilMask && !locked) { - gl.stencilMask(stencilMask); - currentStencilMask = stencilMask; - } - }, - setFunc: function (stencilFunc, stencilRef, stencilMask) { - if (currentStencilFunc !== stencilFunc || currentStencilRef !== stencilRef || currentStencilFuncMask !== stencilMask) { - gl.stencilFunc(stencilFunc, stencilRef, stencilMask); - currentStencilFunc = stencilFunc; - currentStencilRef = stencilRef; - currentStencilFuncMask = stencilMask; - } - }, - setOp: function (stencilFail, stencilZFail, stencilZPass) { - if (currentStencilFail !== stencilFail || currentStencilZFail !== stencilZFail || currentStencilZPass !== stencilZPass) { - gl.stencilOp(stencilFail, stencilZFail, stencilZPass); - currentStencilFail = stencilFail; - currentStencilZFail = stencilZFail; - currentStencilZPass = stencilZPass; - } - }, - setLocked: function (lock) { - locked = lock; - }, - setClear: function (stencil) { - if (currentStencilClear !== stencil) { - gl.clearStencil(stencil); - currentStencilClear = stencil; - } - }, - reset: function () { - locked = false; - currentStencilMask = null; - currentStencilFunc = null; - currentStencilRef = null; - currentStencilFuncMask = null; - currentStencilFail = null; - currentStencilZFail = null; - currentStencilZPass = null; - currentStencilClear = null; - } - }; - } // + return shadowMapTypeDefine; +} - const colorBuffer = new ColorBuffer(); - const depthBuffer = new DepthBuffer(); - const stencilBuffer = new StencilBuffer(); - let enabledCapabilities = {}; - let currentBoundFramebuffers = {}; - let currentDrawbuffers = new WeakMap(); - let defaultDrawbuffers = []; - let currentProgram = null; - let currentBlendingEnabled = false; - let currentBlending = null; - let currentBlendEquation = null; - let currentBlendSrc = null; - let currentBlendDst = null; - let currentBlendEquationAlpha = null; - let currentBlendSrcAlpha = null; - let currentBlendDstAlpha = null; - let currentPremultipledAlpha = false; - let currentFlipSided = null; - let currentCullFace = null; - let currentLineWidth = null; - let currentPolygonOffsetFactor = null; - let currentPolygonOffsetUnits = null; - const maxTextures = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS); - let lineWidthAvailable = false; - let version = 0; - const glVersion = gl.getParameter(gl.VERSION); +function generateEnvMapTypeDefine( parameters ) { - if (glVersion.indexOf('WebGL') !== -1) { - version = parseFloat(/^WebGL (\d)/.exec(glVersion)[1]); - lineWidthAvailable = version >= 1.0; - } else if (glVersion.indexOf('OpenGL ES') !== -1) { - version = parseFloat(/^OpenGL ES (\d)/.exec(glVersion)[1]); - lineWidthAvailable = version >= 2.0; - } + let envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; - 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); + if ( parameters.envMap ) { - function createTexture(type, target, count) { - const data = new Uint8Array(4); // 4 is required to match default unpack alignment of 4. + switch ( parameters.envMapMode ) { - 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); + case CubeReflectionMapping: + case CubeRefractionMapping: + envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; + break; + + case CubeUVReflectionMapping: + envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; + break; - 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 + return envMapTypeDefine; - colorBuffer.setClear(0, 0, 0, 1); - depthBuffer.setClear(1); - stencilBuffer.setClear(0); - enable(gl.DEPTH_TEST); - depthBuffer.setFunc(LessEqualDepth); - setFlipSided(false); - setCullFace(CullFaceBack); - enable(gl.CULL_FACE); - setBlending(NoBlending); // +} - function enable(id) { - if (enabledCapabilities[id] !== true) { - gl.enable(id); - enabledCapabilities[id] = true; - } - } +function generateEnvMapModeDefine( parameters ) { - function disable(id) { - if (enabledCapabilities[id] !== false) { - gl.disable(id); - enabledCapabilities[id] = false; - } - } + let envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; - function bindFramebuffer(target, framebuffer) { - if (currentBoundFramebuffers[target] !== framebuffer) { - gl.bindFramebuffer(target, framebuffer); - currentBoundFramebuffers[target] = framebuffer; + if ( parameters.envMap ) { - if (isWebGL2) { - // gl.DRAW_FRAMEBUFFER is equivalent to gl.FRAMEBUFFER - if (target === gl.DRAW_FRAMEBUFFER) { - currentBoundFramebuffers[gl.FRAMEBUFFER] = framebuffer; - } + switch ( parameters.envMapMode ) { - if (target === gl.FRAMEBUFFER) { - currentBoundFramebuffers[gl.DRAW_FRAMEBUFFER] = framebuffer; - } - } + case CubeRefractionMapping: + + envMapModeDefine = 'ENVMAP_MODE_REFRACTION'; + break; - return true; } - return false; } - function drawBuffers(renderTarget, framebuffer) { - let drawBuffers = defaultDrawbuffers; - let needsUpdate = false; + return envMapModeDefine; - if (renderTarget) { - drawBuffers = currentDrawbuffers.get(framebuffer); +} - if (drawBuffers === undefined) { - drawBuffers = []; - currentDrawbuffers.set(framebuffer, drawBuffers); - } +function generateEnvMapBlendingDefine( parameters ) { - if (renderTarget.isWebGLMultipleRenderTargets) { - const textures = renderTarget.texture; + let envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; - 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; - } + if ( parameters.envMap ) { - drawBuffers.length = textures.length; - needsUpdate = true; - } - } else { - if (drawBuffers[0] !== gl.COLOR_ATTACHMENT0) { - drawBuffers[0] = gl.COLOR_ATTACHMENT0; - needsUpdate = true; - } - } - } else { - if (drawBuffers[0] !== gl.BACK) { - drawBuffers[0] = gl.BACK; - needsUpdate = true; - } - } + switch ( parameters.combine ) { - if (needsUpdate) { - if (capabilities.isWebGL2) { - gl.drawBuffers(drawBuffers); - } else { - extensions.get('WEBGL_draw_buffers').drawBuffersWEBGL(drawBuffers); - } - } - } + case MultiplyOperation: + envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; + break; + + case MixOperation: + envMapBlendingDefine = 'ENVMAP_BLENDING_MIX'; + break; + + case AddOperation: + envMapBlendingDefine = 'ENVMAP_BLENDING_ADD'; + break; - 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 - }; + return envMapBlendingDefine; - 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; - } - } +function generateCubeUVSize( parameters ) { - const factorToGL = { - [ZeroFactor]: gl.ZERO, - [OneFactor]: gl.ONE, - [SrcColorFactor]: gl.SRC_COLOR, - [SrcAlphaFactor]: gl.SRC_ALPHA, - [SrcAlphaSaturateFactor]: gl.SRC_ALPHA_SATURATE, - [DstColorFactor]: gl.DST_COLOR, - [DstAlphaFactor]: gl.DST_ALPHA, - [OneMinusSrcColorFactor]: gl.ONE_MINUS_SRC_COLOR, - [OneMinusSrcAlphaFactor]: gl.ONE_MINUS_SRC_ALPHA, - [OneMinusDstColorFactor]: gl.ONE_MINUS_DST_COLOR, - [OneMinusDstAlphaFactor]: gl.ONE_MINUS_DST_ALPHA - }; + const imageHeight = parameters.envMapCubeUVHeight; - function setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha) { - if (blending === NoBlending) { - if (currentBlendingEnabled === true) { - disable(gl.BLEND); - currentBlendingEnabled = false; - } + if ( imageHeight === null ) return null; - return; - } + const maxMip = Math.log2( imageHeight ) - 2; - if (currentBlendingEnabled === false) { - enable(gl.BLEND); - currentBlendingEnabled = true; - } + const texelHeight = 1.0 / imageHeight; - if (blending !== CustomBlending) { - if (blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha) { - if (currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation) { - gl.blendEquation(gl.FUNC_ADD); - currentBlendEquation = AddEquation; - currentBlendEquationAlpha = AddEquation; - } + const texelWidth = 1.0 / ( 3 * Math.max( Math.pow( 2, maxMip ), 7 * 16 ) ); - if (premultipliedAlpha) { - switch (blending) { - case NormalBlending: - gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - break; + return { texelWidth, texelHeight, maxMip }; - 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; +function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) { - case MultiplyBlending: - gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA); - break; + // TODO Send this event to Three.js DevTools + // console.log( 'WebGLProgram', cacheKey ); - default: - console.error('THREE.WebGLState: Invalid blending: ', blending); - break; - } - } else { - switch (blending) { - case NormalBlending: - gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - break; + const gl = renderer.getContext(); - case AdditiveBlending: - gl.blendFunc(gl.SRC_ALPHA, gl.ONE); - break; + const defines = parameters.defines; - case SubtractiveBlending: - gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE); - break; + let vertexShader = parameters.vertexShader; + let fragmentShader = parameters.fragmentShader; - case MultiplyBlending: - gl.blendFunc(gl.ZERO, gl.SRC_COLOR); - break; + const shadowMapTypeDefine = generateShadowMapTypeDefine( parameters ); + const envMapTypeDefine = generateEnvMapTypeDefine( parameters ); + const envMapModeDefine = generateEnvMapModeDefine( parameters ); + const envMapBlendingDefine = generateEnvMapBlendingDefine( parameters ); + const envMapCubeUVSize = generateCubeUVSize( parameters ); - default: - console.error('THREE.WebGLState: Invalid blending: ', blending); - break; - } - } + const customExtensions = parameters.isWebGL2 ? '' : generateExtensions( parameters ); - currentBlendSrc = null; - currentBlendDst = null; - currentBlendSrcAlpha = null; - currentBlendDstAlpha = null; - currentBlending = blending; - currentPremultipledAlpha = premultipliedAlpha; - } + const customDefines = generateDefines( defines ); - return; - } // custom blending + const program = gl.createProgram(); + let prefixVertex, prefixFragment; + let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : ''; - blendEquationAlpha = blendEquationAlpha || blendEquation; - blendSrcAlpha = blendSrcAlpha || blendSrc; - blendDstAlpha = blendDstAlpha || blendDst; + if ( parameters.isRawShaderMaterial ) { - if (blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha) { - gl.blendEquationSeparate(equationToGL[blendEquation], equationToGL[blendEquationAlpha]); - currentBlendEquation = blendEquation; - currentBlendEquationAlpha = blendEquationAlpha; - } + prefixVertex = [ - if (blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha) { - gl.blendFuncSeparate(factorToGL[blendSrc], factorToGL[blendDst], factorToGL[blendSrcAlpha], factorToGL[blendDstAlpha]); - currentBlendSrc = blendSrc; - currentBlendDst = blendDst; - currentBlendSrcAlpha = blendSrcAlpha; - currentBlendDstAlpha = blendDstAlpha; - } + customDefines - currentBlending = blending; - currentPremultipledAlpha = null; - } - - function setMaterial(material, frontFaceCW) { - material.side === DoubleSide ? disable(gl.CULL_FACE) : enable(gl.CULL_FACE); - let flipSided = material.side === BackSide; - if (frontFaceCW) flipSided = !flipSided; - setFlipSided(flipSided); - material.blending === NormalBlending && material.transparent === false ? setBlending(NoBlending) : setBlending(material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha); - depthBuffer.setFunc(material.depthFunc); - depthBuffer.setTest(material.depthTest); - depthBuffer.setMask(material.depthWrite); - colorBuffer.setMask(material.colorWrite); - const stencilWrite = material.stencilWrite; - stencilBuffer.setTest(stencilWrite); + ].filter( filterEmptyLine ).join( '\n' ); + + if ( prefixVertex.length > 0 ) { + + prefixVertex += '\n'; - 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); - } // + prefixFragment = [ + customExtensions, + customDefines - function setFlipSided(flipSided) { - if (currentFlipSided !== flipSided) { - if (flipSided) { - gl.frontFace(gl.CW); - } else { - gl.frontFace(gl.CCW); - } + ].filter( filterEmptyLine ).join( '\n' ); - currentFlipSided = flipSided; - } - } + if ( prefixFragment.length > 0 ) { - function setCullFace(cullFace) { - if (cullFace !== CullFaceNone) { - enable(gl.CULL_FACE); + prefixFragment += '\n'; - if (cullFace !== currentCullFace) { - if (cullFace === CullFaceBack) { - gl.cullFace(gl.BACK); - } else if (cullFace === CullFaceFront) { - gl.cullFace(gl.FRONT); - } else { - gl.cullFace(gl.FRONT_AND_BACK); - } - } - } else { - disable(gl.CULL_FACE); } - currentCullFace = cullFace; - } + } else { - function setLineWidth(width) { - if (width !== currentLineWidth) { - if (lineWidthAvailable) gl.lineWidth(width); - currentLineWidth = width; - } - } + prefixVertex = [ - function setPolygonOffset(polygonOffset, factor, units) { - if (polygonOffset) { - enable(gl.POLYGON_OFFSET_FILL); + generatePrecision( parameters ), - if (currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units) { - gl.polygonOffset(factor, units); - currentPolygonOffsetFactor = factor; - currentPolygonOffsetUnits = units; - } - } else { - disable(gl.POLYGON_OFFSET_FILL); - } - } + '#define SHADER_NAME ' + parameters.shaderName, - function setScissorTest(scissorTest) { - if (scissorTest) { - enable(gl.SCISSOR_TEST); - } else { - disable(gl.SCISSOR_TEST); - } - } // texture + customDefines, + parameters.instancing ? '#define USE_INSTANCING' : '', + parameters.instancingColor ? '#define USE_INSTANCING_COLOR' : '', - function activeTexture(webglSlot) { - if (webglSlot === undefined) webglSlot = gl.TEXTURE0 + maxTextures - 1; + parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', - if (currentTextureSlot !== webglSlot) { - gl.activeTexture(webglSlot); - currentTextureSlot = webglSlot; - } - } + ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', + ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', - function bindTexture(webglType, webglTexture) { - if (currentTextureSlot === null) { - activeTexture(); - } + 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' : '', - let boundTexture = currentBoundTextures[currentTextureSlot]; + parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', + parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', + parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', - if (boundTexture === undefined) { - boundTexture = { - type: undefined, - texture: undefined - }; - currentBoundTextures[currentTextureSlot] = boundTexture; - } + parameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '', + parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '', - if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) { - gl.bindTexture(webglType, webglTexture || emptyTextures[webglType]); - boundTexture.type = webglType; - boundTexture.texture = webglTexture; - } - } + parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', - function unbindTexture() { - const boundTexture = currentBoundTextures[currentTextureSlot]; + parameters.specularMap ? '#define USE_SPECULARMAP' : '', + parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', + parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', - if (boundTexture !== undefined && boundTexture.type !== undefined) { - gl.bindTexture(boundTexture.type, null); - boundTexture.type = undefined; - boundTexture.texture = undefined; - } - } + parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', + parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', + parameters.alphaMap ? '#define USE_ALPHAMAP' : '', - function compressedTexImage2D() { - try { - gl.compressedTexImage2D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } + parameters.transmission ? '#define USE_TRANSMISSION' : '', + parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', + parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', - function texSubImage2D() { - try { - gl.texSubImage2D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } + parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', + parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', - function texSubImage3D() { - try { - gl.texSubImage3D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } + 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' : '', - function compressedTexSubImage2D() { - try { - gl.compressedTexSubImage2D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } + parameters.flatShading ? '#define FLAT_SHADED' : '', - function texStorage2D() { - try { - gl.texStorage2D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } + parameters.skinning ? '#define USE_SKINNING' : '', - function texStorage3D() { - try { - gl.texStorage3D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } + 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' : '', - function texImage2D() { - try { - gl.texImage2D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } + parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', + parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', - function texImage3D() { - try { - gl.texImage3D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } // + parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', + parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', + ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '', - function scissor(scissor) { - if (currentScissor.equals(scissor) === false) { - gl.scissor(scissor.x, scissor.y, scissor.z, scissor.w); - currentScissor.copy(scissor); - } - } + 'uniform mat4 modelMatrix;', + 'uniform mat4 modelViewMatrix;', + 'uniform mat4 projectionMatrix;', + 'uniform mat4 viewMatrix;', + 'uniform mat3 normalMatrix;', + 'uniform vec3 cameraPosition;', + 'uniform bool isOrthographic;', - function viewport(viewport) { - if (currentViewport.equals(viewport) === false) { - gl.viewport(viewport.x, viewport.y, viewport.z, viewport.w); - currentViewport.copy(viewport); - } - } // + '#ifdef USE_INSTANCING', + ' attribute mat4 instanceMatrix;', - function reset() { - // reset state - gl.disable(gl.BLEND); - gl.disable(gl.CULL_FACE); - gl.disable(gl.DEPTH_TEST); - gl.disable(gl.POLYGON_OFFSET_FILL); - gl.disable(gl.SCISSOR_TEST); - gl.disable(gl.STENCIL_TEST); - gl.disable(gl.SAMPLE_ALPHA_TO_COVERAGE); - gl.blendEquation(gl.FUNC_ADD); - gl.blendFunc(gl.ONE, gl.ZERO); - gl.blendFuncSeparate(gl.ONE, gl.ZERO, gl.ONE, gl.ZERO); - gl.colorMask(true, true, true, true); - gl.clearColor(0, 0, 0, 0); - gl.depthMask(true); - gl.depthFunc(gl.LESS); - gl.clearDepth(1); - gl.stencilMask(0xffffffff); - gl.stencilFunc(gl.ALWAYS, 0, 0xffffffff); - gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); - gl.clearStencil(0); - gl.cullFace(gl.BACK); - gl.frontFace(gl.CCW); - 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 + '#endif', - enabledCapabilities = {}; - currentTextureSlot = null; - currentBoundTextures = {}; - currentBoundFramebuffers = {}; - currentDrawbuffers = new WeakMap(); - defaultDrawbuffers = []; - currentProgram = null; - currentBlendingEnabled = false; - currentBlending = null; - currentBlendEquation = null; - currentBlendSrc = null; - currentBlendDst = null; - currentBlendEquationAlpha = null; - currentBlendSrcAlpha = null; - currentBlendDstAlpha = null; - currentPremultipledAlpha = false; - currentFlipSided = null; - currentCullFace = null; - currentLineWidth = null; - currentPolygonOffsetFactor = null; - currentPolygonOffsetUnits = null; - currentScissor.set(0, 0, gl.canvas.width, gl.canvas.height); - currentViewport.set(0, 0, gl.canvas.width, gl.canvas.height); - colorBuffer.reset(); - depthBuffer.reset(); - stencilBuffer.reset(); - } + '#ifdef USE_INSTANCING_COLOR', - return { - buffers: { - color: colorBuffer, - depth: depthBuffer, - stencil: stencilBuffer - }, - enable: enable, - disable: disable, - bindFramebuffer: bindFramebuffer, - drawBuffers: drawBuffers, - useProgram: useProgram, - setBlending: setBlending, - setMaterial: setMaterial, - setFlipSided: setFlipSided, - setCullFace: setCullFace, - setLineWidth: setLineWidth, - setPolygonOffset: setPolygonOffset, - setScissorTest: setScissorTest, - activeTexture: activeTexture, - bindTexture: bindTexture, - unbindTexture: unbindTexture, - compressedTexImage2D: compressedTexImage2D, - texImage2D: texImage2D, - texImage3D: texImage3D, - texStorage2D: texStorage2D, - texStorage3D: texStorage3D, - texSubImage2D: texSubImage2D, - texSubImage3D: texSubImage3D, - compressedTexSubImage2D: compressedTexSubImage2D, - scissor: scissor, - viewport: viewport, - reset: reset - }; -} + ' attribute vec3 instanceColor;', -function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info) { - const isWebGL2 = capabilities.isWebGL2; - const maxTextures = capabilities.maxTextures; - const maxCubemapSize = capabilities.maxCubemapSize; - 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); + '#endif', - const _videoTextures = new WeakMap(); + 'attribute vec3 position;', + 'attribute vec3 normal;', + 'attribute vec2 uv;', - let _canvas; + '#ifdef USE_TANGENT', - 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). + ' attribute vec4 tangent;', + '#endif', - let useOffscreenCanvas = false; + '#if defined( USE_COLOR_ALPHA )', - try { - useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' // eslint-disable-next-line compat/compat - && new OffscreenCanvas(1, 1).getContext('2d') !== null; - } catch (err) {// Ignore any errors - } + ' attribute vec4 color;', - function createCanvas(width, height) { - // Use OffscreenCanvas when available. Specially needed in web workers - return useOffscreenCanvas ? // eslint-disable-next-line compat/compat - new OffscreenCanvas(width, height) : createElementNS('canvas'); - } + '#elif defined( USE_COLOR )', - function resizeImage(image, needsPowerOfTwo, needsNewCanvas, maxSize) { - let scale = 1; // handle case if texture exceeds max size + ' attribute vec3 color;', - if (image.width > maxSize || image.height > maxSize) { - scale = maxSize / Math.max(image.width, image.height); - } // only perform resize if necessary + '#endif', + '#if ( defined( USE_MORPHTARGETS ) && ! defined( MORPHTARGETS_TEXTURE ) )', - 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 + ' attribute vec3 morphTarget0;', + ' attribute vec3 morphTarget1;', + ' attribute vec3 morphTarget2;', + ' attribute vec3 morphTarget3;', - const canvas = needsNewCanvas ? createCanvas(width, height) : _canvas; - canvas.width = width; - canvas.height = height; - const context = canvas.getContext('2d'); - context.drawImage(image, 0, 0, width, height); - console.warn('THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').'); - return canvas; - } else { - if ('data' in image) { - console.warn('THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').'); - } + ' #ifdef USE_MORPHNORMALS', - return image; - } - } + ' attribute vec3 morphNormal0;', + ' attribute vec3 morphNormal1;', + ' attribute vec3 morphNormal2;', + ' attribute vec3 morphNormal3;', - return image; - } + ' #else', - function isPowerOfTwo$1(image) { - return isPowerOfTwo(image.width) && isPowerOfTwo(image.height); - } + ' attribute vec3 morphTarget4;', + ' attribute vec3 morphTarget5;', + ' attribute vec3 morphTarget6;', + ' attribute vec3 morphTarget7;', - function textureNeedsPowerOfTwo(texture) { - if (isWebGL2) return false; - return texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping || texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; - } + ' #endif', - function textureNeedsGenerateMipmaps(texture, supportsMips) { - return texture.generateMipmaps && supportsMips && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; - } + '#endif', - function generateMipmap(target) { - _gl.generateMipmap(target); - } + '#ifdef USE_SKINNING', - function getInternalFormat(internalFormatName, glFormat, glType, encoding, isVideoTexture = false) { - if (isWebGL2 === false) return glFormat; + ' attribute vec4 skinIndex;', + ' attribute vec4 skinWeight;', - if (internalFormatName !== null) { - if (_gl[internalFormatName] !== undefined) return _gl[internalFormatName]; - console.warn('THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\''); - } + '#endif', - let internalFormat = glFormat; + '\n' - 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; - } + ].filter( filterEmptyLine ).join( '\n' ); - 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; - } + prefixFragment = [ - 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_SHORT_4_4_4_4) internalFormat = _gl.RGBA4; - if (glType === _gl.UNSIGNED_SHORT_5_5_5_1) internalFormat = _gl.RGB5_A1; - } + customExtensions, - 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'); - } + generatePrecision( parameters ), - return internalFormat; - } + '#define SHADER_NAME ' + parameters.shaderName, - 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 + customDefines, + ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', + ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', - function filterFallback(f) { - if (f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter) { - return _gl.NEAREST; - } + 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' : '', - return _gl.LINEAR; - } // + 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' : '', - function onTextureDispose(event) { - const texture = event.target; - texture.removeEventListener('dispose', onTextureDispose); - deallocateTexture(texture); + 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' : '', - if (texture.isVideoTexture) { - _videoTextures.delete(texture); - } - } + parameters.alphaMap ? '#define USE_ALPHAMAP' : '', + parameters.alphaTest ? '#define USE_ALPHATEST' : '', - function onRenderTargetDispose(event) { - const renderTarget = event.target; - renderTarget.removeEventListener('dispose', onRenderTargetDispose); - deallocateRenderTarget(renderTarget); - } // + 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' : '', - function deallocateTexture(texture) { - const textureProperties = properties.get(texture); - if (textureProperties.__webglInit === undefined) return; // check if it's necessary to remove the WebGLTexture object + parameters.decodeVideoTexture ? '#define DECODE_VIDEO_TEXTURE' : '', - const source = texture.source; + 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' : '', - const webglTextures = _sources.get(source); + parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', - if (webglTextures) { - const webglTexture = webglTextures[textureProperties.__cacheKey]; - webglTexture.usedTimes--; // the WebGLTexture object is not used anymore, remove it + parameters.flatShading ? '#define FLAT_SHADED' : '', - if (webglTexture.usedTimes === 0) { - deleteTexture(texture); - } // remove the weak map entry if no WebGLTexture uses the source anymore + parameters.doubleSided ? '#define DOUBLE_SIDED' : '', + parameters.flipSided ? '#define FLIP_SIDED' : '', + parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', + parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', - if (Object.keys(webglTextures).length === 0) { - _sources.delete(source); - } - } + 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' ); - properties.remove(texture); } - function deleteTexture(texture) { - const textureProperties = properties.get(texture); + vertexShader = resolveIncludes( vertexShader ); + vertexShader = replaceLightNums( vertexShader, parameters ); + vertexShader = replaceClippingPlaneNums( vertexShader, parameters ); - _gl.deleteTexture(textureProperties.__webglTexture); + fragmentShader = resolveIncludes( fragmentShader ); + fragmentShader = replaceLightNums( fragmentShader, parameters ); + fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters ); - const source = texture.source; + 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 ); + // 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. - const webglTextures = _sources.get(source); + if ( parameters.index0AttributeName !== undefined ) { + + gl.bindAttribLocation( program, 0, parameters.index0AttributeName ); + + } else if ( parameters.morphTargets === true ) { + + // programs with morphTargets displace position out of attribute 0 + gl.bindAttribLocation( program, 0, 'position' ); - delete webglTextures[textureProperties.__cacheKey]; - info.memory.textures--; } - function deallocateRenderTarget(renderTarget) { - const texture = renderTarget.texture; - const renderTargetProperties = properties.get(renderTarget); - const textureProperties = properties.get(texture); + gl.linkProgram( program ); - if (textureProperties.__webglTexture !== undefined) { - _gl.deleteTexture(textureProperties.__webglTexture); + // check for link errors + if ( renderer.debug.checkShaderErrors ) { - info.memory.textures--; - } + const programLog = gl.getProgramInfoLog( program ).trim(); + const vertexLog = gl.getShaderInfoLog( glVertexShader ).trim(); + const fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim(); - if (renderTarget.depthTexture) { - renderTarget.depthTexture.dispose(); - } + let runnable = true; + let haveDiagnostics = true; - if (renderTarget.isWebGLCubeRenderTarget) { - for (let i = 0; i < 6; i++) { - _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i]); + if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) { - if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer[i]); - } - } else { - _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer); + runnable = false; - if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer); - if (renderTargetProperties.__webglMultisampledFramebuffer) _gl.deleteFramebuffer(renderTargetProperties.__webglMultisampledFramebuffer); + const vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' ); + const fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' ); - if (renderTargetProperties.__webglColorRenderbuffer) { - for (let i = 0; i < renderTargetProperties.__webglColorRenderbuffer.length; i++) { - if (renderTargetProperties.__webglColorRenderbuffer[i]) _gl.deleteRenderbuffer(renderTargetProperties.__webglColorRenderbuffer[i]); - } - } + console.error( + 'THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' + + 'VALIDATE_STATUS ' + gl.getProgramParameter( program, gl.VALIDATE_STATUS ) + '\n\n' + + 'Program Info Log: ' + programLog + '\n' + + vertexErrors + '\n' + + fragmentErrors + ); - if (renderTargetProperties.__webglDepthRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthRenderbuffer); - } + } else if ( programLog !== '' ) { - if (renderTarget.isWebGLMultipleRenderTargets) { - for (let i = 0, il = texture.length; i < il; i++) { - const attachmentProperties = properties.get(texture[i]); + console.warn( 'THREE.WebGLProgram: Program Info Log:', programLog ); - if (attachmentProperties.__webglTexture) { - _gl.deleteTexture(attachmentProperties.__webglTexture); + } else if ( vertexLog === '' || fragmentLog === '' ) { - info.memory.textures--; - } + haveDiagnostics = false; - properties.remove(texture[i]); - } } - properties.remove(texture); - properties.remove(renderTarget); - } // + if ( haveDiagnostics ) { + this.diagnostics = { - let textureUnits = 0; + runnable: runnable, - function resetTextureUnits() { - textureUnits = 0; - } + programLog: programLog, - function allocateTextureUnit() { - const textureUnit = textureUnits; + vertexShader: { - if (textureUnit >= maxTextures) { - console.warn('THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures); - } + log: vertexLog, + prefix: prefixVertex - textureUnits += 1; - return textureUnit; - } + }, - function getTextureCacheKey(texture) { - const array = []; - array.push(texture.wrapS); - array.push(texture.wrapT); - array.push(texture.magFilter); - array.push(texture.minFilter); - array.push(texture.anisotropy); - array.push(texture.internalFormat); - array.push(texture.format); - array.push(texture.type); - array.push(texture.generateMipmaps); - array.push(texture.premultiplyAlpha); - array.push(texture.flipY); - array.push(texture.unpackAlignment); - array.push(texture.encoding); - return array.join(); - } // + fragmentShader: { + log: fragmentLog, + prefix: prefixFragment - 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) { - console.warn('THREE.WebGLRenderer: Texture marked for update but image is incomplete'); - } else { - uploadTexture(textureProperties, texture, slot); - return; - } } - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_2D, textureProperties.__webglTexture); } - function setTexture2DArray(texture, slot) { - const textureProperties = properties.get(texture); + // Clean up - if (texture.version > 0 && textureProperties.__version !== texture.version) { - uploadTexture(textureProperties, texture, slot); - return; - } + // Crashes in iOS9 and iOS10. #18402 + // gl.detachShader( program, glVertexShader ); + // gl.detachShader( program, glFragmentShader ); - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture); - } + gl.deleteShader( glVertexShader ); + gl.deleteShader( glFragmentShader ); - function setTexture3D(texture, slot) { - const textureProperties = properties.get(texture); + // set up caching for uniform locations - if (texture.version > 0 && textureProperties.__version !== texture.version) { - uploadTexture(textureProperties, texture, slot); - return; - } + let cachedUniforms; - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_3D, textureProperties.__webglTexture); - } + this.getUniforms = function () { - function setTextureCube(texture, slot) { - const textureProperties = properties.get(texture); + if ( cachedUniforms === undefined ) { + + cachedUniforms = new WebGLUniforms( gl, program ); - 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); - } + return cachedUniforms; - const wrappingToGL = { - [RepeatWrapping]: _gl.REPEAT, - [ClampToEdgeWrapping]: _gl.CLAMP_TO_EDGE, - [MirroredRepeatWrapping]: _gl.MIRRORED_REPEAT - }; - const filterToGL = { - [NearestFilter]: _gl.NEAREST, - [NearestMipmapNearestFilter]: _gl.NEAREST_MIPMAP_NEAREST, - [NearestMipmapLinearFilter]: _gl.NEAREST_MIPMAP_LINEAR, - [LinearFilter]: _gl.LINEAR, - [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]); + // set up caching for attribute locations - _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, wrappingToGL[texture.wrapT]); + let cachedAttributes; - if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) { - _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, wrappingToGL[texture.wrapR]); - } + this.getAttributes = function () { - _gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterToGL[texture.magFilter]); + if ( cachedAttributes === undefined ) { - _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterToGL[texture.minFilter]); - } else { - _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE); + cachedAttributes = fetchAttributeLocations( gl, program ); - _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); - } + return cachedAttributes; - 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)); + // free resource - _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterFallback(texture.minFilter)); + this.destroy = function () { - 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.'); - } - } + bindingStates.releaseStatesOfProgram( this ); - 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 + gl.deleteProgram( program ); + this.program = undefined; - 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; - } - } - } + this.name = parameters.shaderName; + this.id = programIdCount ++; + this.cacheKey = cacheKey; + this.usedTimes = 1; + this.program = program; + this.vertexShader = glVertexShader; + this.fragmentShader = glFragmentShader; - function initTexture(textureProperties, texture) { - let forceUpload = false; + return this; - if (textureProperties.__webglInit === undefined) { - textureProperties.__webglInit = true; - texture.addEventListener('dispose', onTextureDispose); - } // create Source <-> WebGLTextures mapping if necessary +} +let _id = 0; - const source = texture.source; +class WebGLShaderCache { - let webglTextures = _sources.get(source); + constructor() { - if (webglTextures === undefined) { - webglTextures = {}; + this.shaderCache = new Map(); + this.materialCache = new Map(); - _sources.set(source, webglTextures); - } // check if there is already a WebGLTexture object for the given texture parameters + } + update( material ) { - const textureCacheKey = getTextureCacheKey(texture); + const vertexShader = material.vertexShader; + const fragmentShader = material.fragmentShader; - 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 - // even if the image contents are identical + const vertexShaderStage = this._getShaderStage( vertexShader ); + const fragmentShaderStage = this._getShaderStage( fragmentShader ); - forceUpload = true; - } + const materialShaders = this._getShaderCacheForMaterial( material ); - webglTextures[textureCacheKey].usedTimes++; // 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. + if ( materialShaders.has( vertexShaderStage ) === false ) { - const webglTexture = webglTextures[textureProperties.__cacheKey]; + materialShaders.add( vertexShaderStage ); + vertexShaderStage.usedTimes ++; - if (webglTexture !== undefined) { - webglTextures[textureProperties.__cacheKey].usedTimes--; + } - if (webglTexture.usedTimes === 0) { - deleteTexture(texture); - } - } // store references to cache key and WebGLTexture object + if ( materialShaders.has( fragmentShaderStage ) === false ) { + materialShaders.add( fragmentShaderStage ); + fragmentShaderStage.usedTimes ++; - textureProperties.__cacheKey = textureCacheKey; - textureProperties.__webglTexture = webglTextures[textureCacheKey].texture; } - return forceUpload; + return this; + } - function uploadTexture(textureProperties, texture, slot) { - let textureType = _gl.TEXTURE_2D; - if (texture.isDataArrayTexture) 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); + remove( material ) { - if (source.version !== source.__currentVersion || forceUpload === true) { - _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + const materialShaders = this.materialCache.get( material ); - _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha); + for ( const shaderStage of materialShaders ) { - _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment); + shaderStage.usedTimes --; - _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE); + if ( shaderStage.usedTimes === 0 ) this.shaderCache.delete( shaderStage.code ); - 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); - let glType = utils.convert(texture.type), - 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 levels = getMipLevels(texture, image, supportsMips); + } - if (texture.isDepthTexture) { - // populate depth texture with dummy data - glInternalFormat = _gl.DEPTH_COMPONENT; + this.materialCache.delete( material ); - if (isWebGL2) { - if (texture.type === FloatType) { - glInternalFormat = _gl.DEPTH_COMPONENT32F; - } else if (texture.type === UnsignedIntType) { - glInternalFormat = _gl.DEPTH_COMPONENT24; - } else if (texture.type === UnsignedInt248Type) { - glInternalFormat = _gl.DEPTH24_STENCIL8; - } else { - glInternalFormat = _gl.DEPTH_COMPONENT16; // WebGL2 requires sized internalformat for glTexImage2D - } - } else { - if (texture.type === FloatType) { - console.error('WebGLRenderer: Floating point depth texture requires WebGL2.'); - } - } // validation checks for WebGL 1 + return this; + } - if (texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT) { - // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are - // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT - // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) - if (texture.type !== UnsignedShortType && texture.type !== UnsignedIntType) { - console.warn('THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.'); - texture.type = UnsignedIntType; - glType = utils.convert(texture.type); - } - } + getVertexShaderID( material ) { - 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 - // DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL. - // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) + return this._getShaderStage( material.vertexShader ).id; - if (texture.type !== UnsignedInt248Type) { - console.warn('THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.'); - texture.type = UnsignedInt248Type; - glType = utils.convert(texture.type); - } - } // + } + getFragmentShaderID( material ) { - if (allocateMemory) { - if (useTexStorage) { - state.texStorage2D(_gl.TEXTURE_2D, 1, glInternalFormat, image.width, image.height); - } else { - state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null); - } - } - } else if (texture.isDataTexture) { - // use manually created mipmaps if available - // if there are no manual mipmaps - // set 0 level mipmap and then use GL to generate other mipmap levels - if (mipmaps.length > 0 && supportsMips) { - if (useTexStorage && allocateMemory) { - state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); - } + return this._getShaderStage( material.fragmentShader ).id; - 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); - } - } + dispose() { - texture.generateMipmaps = false; - } else { - if (useTexStorage) { - if (allocateMemory) { - state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); - } + this.shaderCache.clear(); + this.materialCache.clear(); - 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]; + _getShaderCacheForMaterial( material ) { - 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 { - 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); - } - } - } - } else if (texture.isDataArrayTexture) { - if (useTexStorage) { - if (allocateMemory) { - state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth); - } + const cache = this.materialCache; + let set = cache.get( material ); - 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); - } - } else if (texture.isData3DTexture) { - if (useTexStorage) { - if (allocateMemory) { - state.texStorage3D(_gl.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth); - } + if ( set === undefined ) { - 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); - } - } else if (texture.isFramebufferTexture) { - if (allocateMemory) { - if (useTexStorage) { - state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); - } else { - let width = image.width, - height = image.height; + set = new Set(); + cache.set( material, set ); - for (let i = 0; i < levels; i++) { - state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, width, height, 0, glFormat, glType, null); - width >>= 1; - height >>= 1; - } - } - } - } 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]; + return set; - 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); - } + _getShaderStage( code ) { - state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image); - } else { - state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image); - } - } - } + const cache = this.shaderCache; + let stage = cache.get( code ); - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { - generateMipmap(textureType); - } + if ( stage === undefined ) { + + stage = new WebGLShaderStage( code ); + cache.set( code, stage ); - source.__currentVersion = source.version; - if (texture.onUpdate) texture.onUpdate(texture); } - textureProperties.__version = texture.version; + return stage; + } - 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) { - _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); +class WebGLShaderStage { - _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha); + constructor( code ) { - _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment); + this.id = _id ++; - _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE); + this.code = code; + this.usedTimes = 0; - 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]); - } +function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping ) { - 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); - const useTexStorage = isWebGL2 && texture.isVideoTexture !== true; - const allocateMemory = source.__currentVersion === undefined || forceUpload === true; - let levels = getMipLevels(texture, image, supportsMips); - setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture, supportsMips); - let mipmaps; + const _programLayers = new Layers(); + const _customShaders = new WebGLShaderCache(); + const programs = []; - if (isCompressed) { - if (useTexStorage && allocateMemory) { - state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height); - } + const isWebGL2 = capabilities.isWebGL2; + const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; + const vertexTextures = capabilities.vertexTextures; + let precision = capabilities.precision; + + const shaderIDs = { + MeshDepthMaterial: 'depth', + MeshDistanceMaterial: 'distanceRGBA', + MeshNormalMaterial: 'normal', + MeshBasicMaterial: 'basic', + MeshLambertMaterial: 'lambert', + MeshPhongMaterial: 'phong', + MeshToonMaterial: 'toon', + MeshStandardMaterial: 'physical', + MeshPhysicalMaterial: 'physical', + MeshMatcapMaterial: 'matcap', + LineBasicMaterial: 'basic', + LineDashedMaterial: 'dashed', + PointsMaterial: 'points', + ShadowMaterial: 'shadow', + SpriteMaterial: 'sprite' + }; - for (let i = 0; i < 6; i++) { - mipmaps = cubeImage[i].mipmaps; + function getParameters( material, lights, shadows, scene, object ) { - for (let j = 0; j < mipmaps.length; j++) { - const mipmap = mipmaps[j]; + const fog = scene.fog; + const geometry = object.geometry; + const environment = material.isMeshStandardMaterial ? scene.environment : null; - if (texture.format !== RGBAFormat) { - if (glFormat !== null) { - if (useTexStorage) { - state.compressedTexSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); - } else { - state.compressedTexImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); - } - } else { - console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()'); - } - } else { - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); - } else { - state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); - } - } - } - } - } else { - mipmaps = texture.mipmaps; + const envMap = ( material.isMeshStandardMaterial ? cubeuvmaps : cubemaps ).get( material.envMap || environment ); + const envMapCubeUVHeight = ( !! envMap ) && ( envMap.mapping === CubeUVReflectionMapping ) ? envMap.image.height : null; - 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); - } + const shaderID = shaderIDs[ material.type ]; - for (let i = 0; i < 6; i++) { - if (isDataTexture) { - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[i].width, cubeImage[i].height, glFormat, glType, cubeImage[i].data); - } else { - state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[i].width, cubeImage[i].height, 0, glFormat, glType, cubeImage[i].data); - } + // heuristics to create shader parameters according to lights in the scene + // (not to blow over maxLights budget) - for (let j = 0; j < mipmaps.length; j++) { - const mipmap = mipmaps[j]; - const mipmapImage = mipmap.image[i].image; + if ( material.precision !== null ) { - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data); - } else { - state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data); - } - } - } else { - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i]); - } else { - state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]); - } + precision = capabilities.getMaxPrecision( material.precision ); - for (let j = 0; j < mipmaps.length; j++) { - const mipmap = mipmaps[j]; + if ( precision !== material.precision ) { - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]); - } else { - state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]); - } - } - } - } - } + console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' ); - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { - // We assume images for cube map have the same size. - generateMipmap(_gl.TEXTURE_CUBE_MAP); } - source.__currentVersion = 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 + // + const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; + const morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0; - 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); + let morphTextureStride = 0; - 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); - } else { - state.texImage2D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null); - } - } + if ( geometry.morphAttributes.position !== undefined ) morphTextureStride = 1; + if ( geometry.morphAttributes.normal !== undefined ) morphTextureStride = 2; + if ( geometry.morphAttributes.color !== undefined ) morphTextureStride = 3; - state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); + // - if (useMultisampledRTT(renderTarget)) { - multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0, getRenderTargetSamples(renderTarget)); - } else { - _gl.framebufferTexture2D(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0); - } + let vertexShader, fragmentShader; + let customVertexShaderID, customFragmentShaderID; - state.bindFramebuffer(_gl.FRAMEBUFFER, null); - } // Setup storage for internal depth/stencil buffers and bind to correct framebuffer + if ( shaderID ) { + const shader = ShaderLib[ shaderID ]; - function setupRenderBufferStorage(renderbuffer, renderTarget, isMultisample) { - _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer); + vertexShader = shader.vertexShader; + fragmentShader = shader.fragmentShader; - if (renderTarget.depthBuffer && !renderTarget.stencilBuffer) { - let glInternalFormat = _gl.DEPTH_COMPONENT16; + } else { - if (isMultisample || useMultisampledRTT(renderTarget)) { - const depthTexture = renderTarget.depthTexture; + vertexShader = material.vertexShader; + fragmentShader = material.fragmentShader; - if (depthTexture && depthTexture.isDepthTexture) { - if (depthTexture.type === FloatType) { - glInternalFormat = _gl.DEPTH_COMPONENT32F; - } else if (depthTexture.type === UnsignedIntType) { - glInternalFormat = _gl.DEPTH_COMPONENT24; - } - } + _customShaders.update( material ); - const samples = getRenderTargetSamples(renderTarget); + customVertexShaderID = _customShaders.getVertexShaderID( material ); + customFragmentShaderID = _customShaders.getFragmentShaderID( material ); - if (useMultisampledRTT(renderTarget)) { - multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); - } else { - _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); - } - } 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); + const currentRenderTarget = renderer.getRenderTarget(); - if (isMultisample && useMultisampledRTT(renderTarget) === false) { - _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height); - } else if (useMultisampledRTT(renderTarget)) { - multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height); - } else { - _gl.renderbufferStorage(_gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height); - } + const useAlphaTest = material.alphaTest > 0; + const useClearcoat = material.clearcoat > 0; + const useIridescence = material.iridescence > 0; - _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)) { - multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); - } else { - _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height); - } - } - } + const parameters = { - _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); - } // Setup resources for a Depth Texture for a FBO (needs an extension) + isWebGL2: isWebGL2, + shaderID: shaderID, + shaderName: material.type, - 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); + vertexShader: vertexShader, + fragmentShader: fragmentShader, + defines: material.defines, - 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 + customVertexShaderID: customVertexShaderID, + customFragmentShaderID: customFragmentShaderID, + isRawShaderMaterial: material.isRawShaderMaterial === true, + glslVersion: material.glslVersion, - 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; - } + precision: precision, - setTexture2D(renderTarget.depthTexture, 0); + instancing: object.isInstancedMesh === true, + instancingColor: object.isInstancedMesh === true && object.instanceColor !== null, - const webglDepthTexture = properties.get(renderTarget.depthTexture).__webglTexture; + supportsVertexTextures: vertexTextures, + outputEncoding: ( currentRenderTarget === null ) ? renderer.outputEncoding : ( currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.encoding : LinearEncoding ), + map: !! material.map, + matcap: !! material.matcap, + envMap: !! envMap, + envMapMode: envMap && envMap.mapping, + envMapCubeUVHeight: envMapCubeUVHeight, + lightMap: !! material.lightMap, + aoMap: !! material.aoMap, + emissiveMap: !! material.emissiveMap, + bumpMap: !! material.bumpMap, + normalMap: !! material.normalMap, + objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap, + tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap, - const samples = getRenderTargetSamples(renderTarget); + decodeVideoTexture: !! material.map && ( material.map.isVideoTexture === true ) && ( material.map.encoding === sRGBEncoding ), - if (renderTarget.depthTexture.format === DepthFormat) { - if (useMultisampledRTT(renderTarget)) { - multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples); - } else { - _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0); - } - } else if (renderTarget.depthTexture.format === DepthStencilFormat) { - if (useMultisampledRTT(renderTarget)) { - multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples); - } else { - _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0); - } - } else { - throw new Error('Unknown depthTexture format'); - } - } // Setup GL resources for a non-texture depth buffer + clearcoat: useClearcoat, + clearcoatMap: useClearcoat && !! material.clearcoatMap, + clearcoatRoughnessMap: useClearcoat && !! material.clearcoatRoughnessMap, + clearcoatNormalMap: useClearcoat && !! material.clearcoatNormalMap, + iridescence: useIridescence, + iridescenceMap: useIridescence && !! material.iridescenceMap, + iridescenceThicknessMap: useIridescence && !! material.iridescenceThicknessMap, - function setupDepthRenderbuffer(renderTarget) { - const renderTargetProperties = properties.get(renderTarget); - const isCube = renderTarget.isWebGLCubeRenderTarget === true; + displacementMap: !! material.displacementMap, + roughnessMap: !! material.roughnessMap, + metalnessMap: !! material.metalnessMap, + specularMap: !! material.specularMap, + specularIntensityMap: !! material.specularIntensityMap, + specularColorMap: !! material.specularColorMap, - 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 = []; + opaque: material.transparent === false && material.blending === NormalBlending, - for (let i = 0; i < 6; i++) { - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[i]); - renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer(); - setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer[i], renderTarget, false); - } - } else { - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); - renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); - setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false); - } - } + alphaMap: !! material.alphaMap, + alphaTest: useAlphaTest, - state.bindFramebuffer(_gl.FRAMEBUFFER, null); - } // rebind framebuffer with external textures + gradientMap: !! material.gradientMap, + sheen: material.sheen > 0, + sheenColorMap: !! material.sheenColorMap, + sheenRoughnessMap: !! material.sheenRoughnessMap, - function rebindTextures(renderTarget, colorTexture, depthTexture) { - const renderTargetProperties = properties.get(renderTarget); + transmission: material.transmission > 0, + transmissionMap: !! material.transmissionMap, + thicknessMap: !! material.thicknessMap, - if (colorTexture !== undefined) { - setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, renderTarget.texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D); - } + combine: material.combine, - if (depthTexture !== undefined) { - setupDepthRenderbuffer(renderTarget); - } - } // Set up GL resources for the render target + vertexTangents: ( !! material.normalMap && !! geometry.attributes.tangent ), + vertexColors: material.vertexColors, + vertexAlphas: material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4, + vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatMap || !! material.clearcoatRoughnessMap || !! material.clearcoatNormalMap || !! material.iridescenceMap || !! material.iridescenceThicknessMap || !! material.displacementMap || !! material.transmissionMap || !! material.thicknessMap || !! material.specularIntensityMap || !! material.specularColorMap || !! material.sheenColorMap || !! material.sheenRoughnessMap, + uvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap || !! material.iridescenceMap || !! material.iridescenceThicknessMap || material.transmission > 0 || !! material.transmissionMap || !! material.thicknessMap || !! material.specularIntensityMap || !! material.specularColorMap || material.sheen > 0 || !! material.sheenColorMap || !! material.sheenRoughnessMap ) && !! material.displacementMap, + fog: !! fog, + useFog: material.fog === true, + fogExp2: ( fog && fog.isFogExp2 ), - function setupRenderTarget(renderTarget) { - const texture = renderTarget.texture; - const renderTargetProperties = properties.get(renderTarget); - const textureProperties = properties.get(texture); - renderTarget.addEventListener('dispose', onRenderTargetDispose); + flatShading: !! material.flatShading, - if (renderTarget.isWebGLMultipleRenderTargets !== true) { - if (textureProperties.__webglTexture === undefined) { - textureProperties.__webglTexture = _gl.createTexture(); - } + sizeAttenuation: material.sizeAttenuation, + logarithmicDepthBuffer: logarithmicDepthBuffer, - textureProperties.__version = texture.version; - info.memory.textures++; - } + skinning: object.isSkinnedMesh === true, - const isCube = renderTarget.isWebGLCubeRenderTarget === true; - const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true; - const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; // Setup framebuffer + morphTargets: geometry.morphAttributes.position !== undefined, + morphNormals: geometry.morphAttributes.normal !== undefined, + morphColors: geometry.morphAttributes.color !== undefined, + morphTargetsCount: morphTargetsCount, + morphTextureStride: morphTextureStride, - if (isCube) { - renderTargetProperties.__webglFramebuffer = []; + numDirLights: lights.directional.length, + numPointLights: lights.point.length, + numSpotLights: lights.spot.length, + numSpotLightMaps: lights.spotLightMap.length, + numRectAreaLights: lights.rectArea.length, + numHemiLights: lights.hemi.length, - for (let i = 0; i < 6; i++) { - renderTargetProperties.__webglFramebuffer[i] = _gl.createFramebuffer(); - } - } else { - renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); + numDirLightShadows: lights.directionalShadowMap.length, + numPointLightShadows: lights.pointShadowMap.length, + numSpotLightShadows: lights.spotShadowMap.length, + numSpotLightShadowsWithMaps: lights.numSpotLightShadowsWithMaps, - if (isMultipleRenderTargets) { - if (capabilities.drawBuffers) { - const textures = renderTarget.texture; + numClippingPlanes: clipping.numPlanes, + numClipIntersection: clipping.numIntersection, - for (let i = 0, il = textures.length; i < il; i++) { - const attachmentProperties = properties.get(textures[i]); + dithering: material.dithering, - if (attachmentProperties.__webglTexture === undefined) { - attachmentProperties.__webglTexture = _gl.createTexture(); - info.memory.textures++; - } - } - } else { - console.warn('THREE.WebGLRenderer: WebGLMultipleRenderTargets can only be used with WebGL2 or WEBGL_draw_buffers extension.'); - } - } + shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0, + shadowMapType: renderer.shadowMap.type, - 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); + toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping, + physicallyCorrectLights: renderer.physicallyCorrectLights, - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - renderTargetProperties.__webglColorRenderbuffer[i] = _gl.createRenderbuffer(); + premultipliedAlpha: material.premultipliedAlpha, - _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); + doubleSided: material.side === DoubleSide, + flipSided: material.side === BackSide, - 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); + useDepthPacking: !! material.depthPacking, + depthPacking: material.depthPacking || 0, - _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); + index0AttributeName: material.index0AttributeName, - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); - } + extensionDerivatives: material.extensions && material.extensions.derivatives, + extensionFragDepth: material.extensions && material.extensions.fragDepth, + extensionDrawBuffers: material.extensions && material.extensions.drawBuffers, + extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD, - _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); + rendererExtensionFragDepth: isWebGL2 || extensions.has( 'EXT_frag_depth' ), + rendererExtensionDrawBuffers: isWebGL2 || extensions.has( 'WEBGL_draw_buffers' ), + rendererExtensionShaderTextureLod: isWebGL2 || extensions.has( 'EXT_shader_texture_lod' ), - if (renderTarget.depthBuffer) { - renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer(); - setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true); - } + customProgramCacheKey: material.customProgramCacheKey() - state.bindFramebuffer(_gl.FRAMEBUFFER, null); - } - } // Setup color buffer + }; + return parameters; - 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); - } + function getProgramCacheKey( parameters ) { - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { - generateMipmap(_gl.TEXTURE_CUBE_MAP); - } - - state.unbindTexture(); - } else if (isMultipleRenderTargets) { - const textures = renderTarget.texture; + const array = []; - 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 ( parameters.shaderID ) { - if (textureNeedsGenerateMipmaps(attachment, supportsMips)) { - generateMipmap(_gl.TEXTURE_2D); - } - } + array.push( parameters.shaderID ); - 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; - } else { - console.error('THREE.WebGLTextures: THREE.Data3DTexture and THREE.DataArrayTexture only supported with WebGL2.'); - } - } + array.push( parameters.customVertexShaderID ); + array.push( parameters.customFragmentShaderID ); - state.bindTexture(glTextureType, textureProperties.__webglTexture); - setTextureParameters(glTextureType, texture, supportsMips); - setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, texture, _gl.COLOR_ATTACHMENT0, glTextureType); + } - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { - generateMipmap(glTextureType); - } + if ( parameters.defines !== undefined ) { - state.unbindTexture(); - } // Setup depth and stencil buffers + for ( const name in parameters.defines ) { + array.push( name ); + array.push( parameters.defines[ name ] ); + + } - if (renderTarget.depthBuffer) { - setupDepthRenderbuffer(renderTarget); } - } - function updateRenderTargetMipmap(renderTarget) { - const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; - const textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [renderTarget.texture]; + if ( parameters.isRawShaderMaterial === false ) { - for (let i = 0, il = textures.length; i < il; i++) { - const texture = textures[i]; + getProgramCacheKeyParameters( array, parameters ); + getProgramCacheKeyBooleans( array, parameters ); + array.push( renderer.outputEncoding ); - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { - const target = renderTarget.isWebGLCubeRenderTarget ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D; + } - const webglTexture = properties.get(texture).__webglTexture; + array.push( parameters.customProgramCacheKey ); - state.bindTexture(target, webglTexture); - generateMipmap(target); - state.unbindTexture(); - } - } - } + return array.join(); - function updateMultisampleRenderTarget(renderTarget) { - if (isWebGL2 && renderTarget.samples > 0 && useMultisampledRTT(renderTarget) === false) { - const textures = renderTarget.isWebGLMultipleRenderTargets ? renderTarget.texture : [renderTarget.texture]; - const width = renderTarget.width; - const height = renderTarget.height; - let mask = _gl.COLOR_BUFFER_BIT; - 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 + } - if (isMultipleRenderTargets) { - for (let i = 0; i < textures.length; i++) { - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); + function getProgramCacheKeyParameters( array, parameters ) { - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, null); + array.push( parameters.precision ); + array.push( parameters.outputEncoding ); + array.push( parameters.envMapMode ); + array.push( parameters.envMapCubeUVHeight ); + array.push( parameters.combine ); + array.push( parameters.vertexUvs ); + array.push( parameters.fogExp2 ); + array.push( parameters.sizeAttenuation ); + array.push( parameters.morphTargetsCount ); + array.push( parameters.morphAttributeCount ); + 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 ); - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); + } - _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, null, 0); - } - } + function getProgramCacheKeyBooleans( array, parameters ) { - state.bindFramebuffer(_gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); - state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); + _programLayers.disableAll(); - for (let i = 0; i < textures.length; i++) { - invalidationArray.push(_gl.COLOR_ATTACHMENT0 + i); + if ( parameters.isWebGL2 ) + _programLayers.enable( 0 ); + if ( parameters.supportsVertexTextures ) + _programLayers.enable( 1 ); + if ( parameters.instancing ) + _programLayers.enable( 2 ); + if ( parameters.instancingColor ) + _programLayers.enable( 3 ); + if ( parameters.map ) + _programLayers.enable( 4 ); + if ( parameters.matcap ) + _programLayers.enable( 5 ); + if ( parameters.envMap ) + _programLayers.enable( 6 ); + if ( parameters.lightMap ) + _programLayers.enable( 7 ); + if ( parameters.aoMap ) + _programLayers.enable( 8 ); + if ( parameters.emissiveMap ) + _programLayers.enable( 9 ); + if ( parameters.bumpMap ) + _programLayers.enable( 10 ); + if ( parameters.normalMap ) + _programLayers.enable( 11 ); + if ( parameters.objectSpaceNormalMap ) + _programLayers.enable( 12 ); + if ( parameters.tangentSpaceNormalMap ) + _programLayers.enable( 13 ); + if ( parameters.clearcoat ) + _programLayers.enable( 14 ); + if ( parameters.clearcoatMap ) + _programLayers.enable( 15 ); + if ( parameters.clearcoatRoughnessMap ) + _programLayers.enable( 16 ); + if ( parameters.clearcoatNormalMap ) + _programLayers.enable( 17 ); + if ( parameters.iridescence ) + _programLayers.enable( 18 ); + if ( parameters.iridescenceMap ) + _programLayers.enable( 19 ); + if ( parameters.iridescenceThicknessMap ) + _programLayers.enable( 20 ); + if ( parameters.displacementMap ) + _programLayers.enable( 21 ); + if ( parameters.specularMap ) + _programLayers.enable( 22 ); + if ( parameters.roughnessMap ) + _programLayers.enable( 23 ); + if ( parameters.metalnessMap ) + _programLayers.enable( 24 ); + if ( parameters.gradientMap ) + _programLayers.enable( 25 ); + if ( parameters.alphaMap ) + _programLayers.enable( 26 ); + if ( parameters.alphaTest ) + _programLayers.enable( 27 ); + if ( parameters.vertexColors ) + _programLayers.enable( 28 ); + if ( parameters.vertexAlphas ) + _programLayers.enable( 29 ); + if ( parameters.vertexUvs ) + _programLayers.enable( 30 ); + if ( parameters.vertexTangents ) + _programLayers.enable( 31 ); + if ( parameters.uvsVertexOnly ) + _programLayers.enable( 32 ); + + array.push( _programLayers.mask ); + _programLayers.disableAll(); - if (renderTarget.depthBuffer) { - invalidationArray.push(depthStyle); - } + 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; - const ignoreDepthValues = renderTargetProperties.__ignoreDepthValues !== undefined ? renderTargetProperties.__ignoreDepthValues : false; + if ( shaderID ) { - if (ignoreDepthValues === false) { - if (renderTarget.depthBuffer) mask |= _gl.DEPTH_BUFFER_BIT; - if (renderTarget.stencilBuffer) mask |= _gl.STENCIL_BUFFER_BIT; - } + const shader = ShaderLib[ shaderID ]; + uniforms = UniformsUtils.clone( shader.uniforms ); - if (isMultipleRenderTargets) { - _gl.framebufferRenderbuffer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); - } + } else { - if (ignoreDepthValues === true) { - _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, [depthStyle]); + uniforms = material.uniforms; - _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, [depthStyle]); - } + } - if (isMultipleRenderTargets) { - const webglTexture = properties.get(textures[i]).__webglTexture; + return uniforms; - _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); + function acquireProgram( parameters, cacheKey ) { - if (supportsInvalidateFramebuffer) { - _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, invalidationArray); - } - } + let program; - 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 + // Check if code has been already compiled + for ( let p = 0, pl = programs.length; p < pl; p ++ ) { - if (isMultipleRenderTargets) { - for (let i = 0; i < textures.length; i++) { - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); + const preexistingProgram = programs[ p ]; - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); + if ( preexistingProgram.cacheKey === cacheKey ) { - const webglTexture = properties.get(textures[i]).__webglTexture; + program = preexistingProgram; + ++ program.usedTimes; - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); + break; - _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 + if ( program === undefined ) { - if (_videoTextures.get(texture) !== frame) { - _videoTextures.set(texture, frame); + program = new WebGLProgram( renderer, cacheKey, parameters, bindingStates ); + programs.push( program ); - 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 + return program; - 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.'); - } - } - } else { - console.error('THREE.WebGLTextures: Unsupported texture encoding:', encoding); - } - } + } - return image; - } // + function releaseProgram( program ) { + if ( -- program.usedTimes === 0 ) { - this.allocateTextureUnit = allocateTextureUnit; - this.resetTextureUnits = resetTextureUnits; - this.setTexture2D = setTexture2D; - this.setTexture2DArray = setTexture2DArray; - this.setTexture3D = setTexture3D; - this.setTextureCube = setTextureCube; - this.rebindTextures = rebindTextures; - this.setupRenderTarget = setupRenderTarget; - this.updateRenderTargetMipmap = updateRenderTargetMipmap; - this.updateMultisampleRenderTarget = updateMultisampleRenderTarget; - this.setupDepthRenderbuffer = setupDepthRenderbuffer; - this.setupFrameBufferTexture = setupFrameBufferTexture; - this.useMultisampledRTT = useMultisampledRTT; -} + // Remove from unordered set + const i = programs.indexOf( program ); + programs[ i ] = programs[ programs.length - 1 ]; + programs.pop(); -function WebGLUtils(gl, extensions, capabilities) { - const isWebGL2 = capabilities.isWebGL2; + // Free WebGL resources + program.destroy(); - function convert(p, encoding = null) { - let extension; - if (p === UnsignedByteType) return gl.UNSIGNED_BYTE; - if (p === UnsignedShort4444Type) return gl.UNSIGNED_SHORT_4_4_4_4; - if (p === UnsignedShort5551Type) return gl.UNSIGNED_SHORT_5_5_5_1; - if (p === ByteType) return gl.BYTE; - if (p === ShortType) return gl.SHORT; - if (p === UnsignedShortType) return gl.UNSIGNED_SHORT; - 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; + } - 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 + function releaseShaderCache( material ) { + _customShaders.remove( material ); - if (p === _SRGBAFormat) { - extension = extensions.get('EXT_sRGB'); + } - if (extension !== null) { - return extension.SRGB_ALPHA_EXT; - } else { - return null; - } - } // WebGL2 formats. + function dispose() { + _customShaders.dispose(); - 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 === 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'); + return { + getParameters: getParameters, + getProgramCacheKey: getProgramCacheKey, + getUniforms: getUniforms, + acquireProgram: acquireProgram, + releaseProgram: releaseProgram, + releaseShaderCache: releaseShaderCache, + // Exposed for resource monitoring & error feedback via renderer.info: + programs: programs, + dispose: dispose + }; - 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; - if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; - if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; - } else { - return null; - } - } 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; - if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; - if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; - } else { - return null; - } - } - } // PVRTC +function WebGLProperties() { + let properties = new WeakMap(); - 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'); + function get( object ) { - if (extension !== null) { - if (p === RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; - if (p === RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; - if (p === RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; - if (p === RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; - } else { - return null; - } - } // ETC1 + let map = properties.get( object ); + if ( map === undefined ) { - if (p === RGB_ETC1_Format) { - extension = extensions.get('WEBGL_compressed_texture_etc1'); + map = {}; + properties.set( object, map ); - if (extension !== null) { - return extension.COMPRESSED_RGB_ETC1_WEBGL; - } else { - return null; - } - } // ETC2 + } + return map; - 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 - - - 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; - if (p === RGBA_ASTC_5x5_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR; - if (p === RGBA_ASTC_6x5_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR; - if (p === RGBA_ASTC_6x6_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR; - if (p === RGBA_ASTC_8x5_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR; - if (p === RGBA_ASTC_8x6_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR; - if (p === RGBA_ASTC_8x8_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR; - if (p === RGBA_ASTC_10x5_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR; - if (p === RGBA_ASTC_10x6_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR; - if (p === RGBA_ASTC_10x8_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR; - if (p === RGBA_ASTC_10x10_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR; - if (p === RGBA_ASTC_12x10_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR; - if (p === RGBA_ASTC_12x12_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR; - } else { - return null; - } - } // BPTC + function remove( object ) { + properties.delete( object ); - 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; - } - } // + function update( object, key, value ) { + properties.get( object )[ key ] = value; - 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) + function dispose() { + properties = new WeakMap(); - return gl[p] !== undefined ? gl[p] : null; } return { - convert: convert + get: get, + remove: remove, + update: update, + dispose: dispose }; + } -class ArrayCamera extends PerspectiveCamera { - constructor(array = []) { - super(); - this.isArrayCamera = true; - this.cameras = array; - } +function painterSortStable( a, b ) { -} + if ( a.groupOrder !== b.groupOrder ) { -class Group extends Object3D { - constructor() { - super(); - this.isGroup = true; - this.type = 'Group'; - } + return a.groupOrder - b.groupOrder; -} + } else if ( a.renderOrder !== b.renderOrder ) { -const _moveEvent = { - type: 'move' -}; + return a.renderOrder - b.renderOrder; -class WebXRController { - constructor() { - this._targetRay = null; - this._grip = null; - this._hand = null; - } + } else if ( a.material.id !== b.material.id ) { - getHandSpace() { - if (this._hand === null) { - this._hand = new Group(); - this._hand.matrixAutoUpdate = false; - this._hand.visible = false; - this._hand.joints = {}; - this._hand.inputState = { - pinching: false - }; - } + return a.material.id - b.material.id; - return this._hand; - } + } else if ( a.z !== b.z ) { - getTargetRaySpace() { - if (this._targetRay === null) { - this._targetRay = new Group(); - this._targetRay.matrixAutoUpdate = false; - this._targetRay.visible = false; - this._targetRay.hasLinearVelocity = false; - this._targetRay.linearVelocity = new Vector3(); - this._targetRay.hasAngularVelocity = false; - this._targetRay.angularVelocity = new Vector3(); - } + return a.z - b.z; - return this._targetRay; - } + } else { - getGripSpace() { - if (this._grip === null) { - this._grip = new Group(); - this._grip.matrixAutoUpdate = false; - this._grip.visible = false; - this._grip.hasLinearVelocity = false; - this._grip.linearVelocity = new Vector3(); - this._grip.hasAngularVelocity = false; - this._grip.angularVelocity = new Vector3(); - } + return a.id - b.id; - return this._grip; } - dispatchEvent(event) { - if (this._targetRay !== null) { - this._targetRay.dispatchEvent(event); - } +} - if (this._grip !== null) { - this._grip.dispatchEvent(event); - } +function reversePainterSortStable( a, b ) { - if (this._hand !== null) { - this._hand.dispatchEvent(event); - } + if ( a.groupOrder !== b.groupOrder ) { - return this; - } + return a.groupOrder - b.groupOrder; - disconnect(inputSource) { - this.dispatchEvent({ - type: 'disconnected', - data: inputSource - }); + } else if ( a.renderOrder !== b.renderOrder ) { - if (this._targetRay !== null) { - this._targetRay.visible = false; - } + return a.renderOrder - b.renderOrder; - if (this._grip !== null) { - this._grip.visible = false; - } + } else if ( a.z !== b.z ) { - if (this._hand !== null) { - this._hand.visible = false; - } + return b.z - a.z; - return this; - } + } else { - update(inputSource, frame, referenceSpace) { - let inputPose = null; - let gripPose = null; - let handPose = null; - const targetRay = this._targetRay; - const grip = this._grip; - const hand = this._hand; + return a.id - b.id; - if (inputSource && frame.session.visibilityState !== 'visible-blurred') { - if (targetRay !== null) { - inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace); + } - 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); - } - } +function WebGLRenderList() { - if (hand && inputSource.hand) { - handPose = true; + const renderItems = []; + let renderItemsIndex = 0; - for (const inputjoint of inputSource.hand.values()) { - // Update the joints groups with the XRJoint poses - const jointPose = frame.getJointPose(inputjoint, referenceSpace); + const opaque = []; + const transmissive = []; + const transparent = []; - 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; // ?? + function init() { - hand.add(joint); - } + renderItemsIndex = 0; - const joint = hand.joints[inputjoint.jointName]; + opaque.length = 0; + transmissive.length = 0; + transparent.length = 0; - 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 + function getNextRenderItem( object, geometry, material, groupOrder, z, group ) { + let renderItem = renderItems[ renderItemsIndex ]; - 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 ( renderItem === undefined ) { - if (hand.inputState.pinching && distance > distanceToPinch + threshold) { - hand.inputState.pinching = false; - this.dispatchEvent({ - type: 'pinchend', - handedness: inputSource.handedness, - target: this - }); - } else if (!hand.inputState.pinching && distance <= distanceToPinch - threshold) { - hand.inputState.pinching = true; - this.dispatchEvent({ - type: 'pinchstart', - handedness: inputSource.handedness, - target: this - }); - } - } else { - if (grip !== null && inputSource.gripSpace) { - gripPose = frame.getPose(inputSource.gripSpace, referenceSpace); + renderItem = { + id: object.id, + object: object, + geometry: geometry, + material: material, + groupOrder: groupOrder, + renderOrder: object.renderOrder, + z: z, + group: group + }; - if (gripPose !== null) { - grip.matrix.fromArray(gripPose.transform.matrix); - grip.matrix.decompose(grip.position, grip.rotation, grip.scale); + renderItems[ renderItemsIndex ] = renderItem; - if (gripPose.linearVelocity) { - grip.hasLinearVelocity = true; - grip.linearVelocity.copy(gripPose.linearVelocity); - } else { - grip.hasLinearVelocity = false; - } + } else { - if (gripPose.angularVelocity) { - grip.hasAngularVelocity = true; - grip.angularVelocity.copy(gripPose.angularVelocity); - } else { - grip.hasAngularVelocity = false; - } - } - } - } - } + renderItem.id = object.id; + renderItem.object = object; + renderItem.geometry = geometry; + renderItem.material = material; + renderItem.groupOrder = groupOrder; + renderItem.renderOrder = object.renderOrder; + renderItem.z = z; + renderItem.group = group; - if (targetRay !== null) { - targetRay.visible = inputPose !== null; } - if (grip !== null) { - grip.visible = gripPose !== null; - } + renderItemsIndex ++; - if (hand !== null) { - hand.visible = handPose !== null; - } + return renderItem; - return this; } -} + function push( object, geometry, material, groupOrder, z, group ) { -class DepthTexture extends Texture { - constructor(width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format) { - format = format !== undefined ? format : DepthFormat; + const renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group ); + + if ( material.transmission > 0.0 ) { + + transmissive.push( renderItem ); + + } else if ( material.transparent === true ) { + + transparent.push( renderItem ); + + } else { + + opaque.push( renderItem ); - 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); - this.isDepthTexture = true; - this.image = { - width: width, - height: height - }; - this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; - this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; - this.flipY = false; - this.generateMipmaps = false; } -} + function unshift( object, geometry, material, groupOrder, z, group ) { -class WebXRManager extends EventDispatcher { - constructor(renderer, gl) { - super(); - const scope = this; - let session = null; - let framebufferScaleFactor = 1.0; - let referenceSpace = null; - let referenceSpaceType = 'local-floor'; - let customReferenceSpace = null; - let pose = null; - let glBinding = null; - let glProjLayer = null; - let glBaseLayer = null; - let xrFrame = null; - const attributes = gl.getContextAttributes(); - let initialRenderTarget = null; - let newRenderTarget = null; - const controllers = []; - const inputSourcesMap = new Map(); // + const renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group ); - const cameraL = new PerspectiveCamera(); - cameraL.layers.enable(1); - cameraL.viewport = new Vector4(); - const cameraR = new PerspectiveCamera(); - cameraR.layers.enable(2); - cameraR.viewport = new Vector4(); - const cameras = [cameraL, cameraR]; - const cameraVR = new ArrayCamera(); - cameraVR.layers.enable(1); - cameraVR.layers.enable(2); - let _currentDepthNear = null; - let _currentDepthFar = null; // + if ( material.transmission > 0.0 ) { - this.cameraAutoUpdate = true; - this.enabled = false; - this.isPresenting = false; + transmissive.unshift( renderItem ); - this.getController = function (index) { - let controller = controllers[index]; + } else if ( material.transparent === true ) { - if (controller === undefined) { - controller = new WebXRController(); - controllers[index] = controller; - } + transparent.unshift( renderItem ); - return controller.getTargetRaySpace(); - }; + } else { - this.getControllerGrip = function (index) { - let controller = controllers[index]; + opaque.unshift( renderItem ); - if (controller === undefined) { - controller = new WebXRController(); - controllers[index] = controller; - } + } - return controller.getGripSpace(); - }; + } - this.getHand = function (index) { - let controller = controllers[index]; + function sort( customOpaqueSort, customTransparentSort ) { - if (controller === undefined) { - controller = new WebXRController(); - controllers[index] = controller; - } + if ( opaque.length > 1 ) opaque.sort( customOpaqueSort || painterSortStable ); + if ( transmissive.length > 1 ) transmissive.sort( customTransparentSort || reversePainterSortStable ); + if ( transparent.length > 1 ) transparent.sort( customTransparentSort || reversePainterSortStable ); - return controller.getHandSpace(); - }; // + } + function finish() { - function onSessionEvent(event) { - const controller = inputSourcesMap.get(event.inputSource); + // Clear references from inactive renderItems in the list - if (controller !== undefined) { - controller.dispatchEvent({ - type: event.type, - data: event.inputSource - }); - } - } + for ( let i = renderItemsIndex, il = renderItems.length; i < il; i ++ ) { - function onSessionEnd() { - session.removeEventListener('select', onSessionEvent); - session.removeEventListener('selectstart', onSessionEvent); - session.removeEventListener('selectend', onSessionEvent); - session.removeEventListener('squeeze', onSessionEvent); - session.removeEventListener('squeezestart', onSessionEvent); - session.removeEventListener('squeezeend', onSessionEvent); - session.removeEventListener('end', onSessionEnd); - session.removeEventListener('inputsourceschange', onInputSourcesChange); - inputSourcesMap.forEach(function (controller, inputSource) { - if (controller !== undefined) { - controller.disconnect(inputSource); - } - }); - inputSourcesMap.clear(); - _currentDepthNear = null; - _currentDepthFar = null; // restore framebuffer/rendering state + const renderItem = renderItems[ i ]; - renderer.setRenderTarget(initialRenderTarget); - glBaseLayer = null; - glProjLayer = null; - glBinding = null; - session = null; - newRenderTarget = null; // + if ( renderItem.id === null ) break; + + renderItem.id = null; + renderItem.object = null; + renderItem.geometry = null; + renderItem.material = null; + renderItem.group = null; - animation.stop(); - scope.isPresenting = false; - scope.dispatchEvent({ - type: 'sessionend' - }); } - this.setFramebufferScaleFactor = function (value) { - framebufferScaleFactor = value; + } - if (scope.isPresenting === true) { - console.warn('THREE.WebXRManager: Cannot change framebuffer scale while presenting.'); - } - }; + return { - this.setReferenceSpaceType = function (value) { - referenceSpaceType = value; + opaque: opaque, + transmissive: transmissive, + transparent: transparent, - if (scope.isPresenting === true) { - console.warn('THREE.WebXRManager: Cannot change reference space type while presenting.'); - } - }; + init: init, + push: push, + unshift: unshift, + finish: finish, - this.getReferenceSpace = function () { - return customReferenceSpace || referenceSpace; - }; + sort: sort + }; - this.setReferenceSpace = function (space) { - customReferenceSpace = space; - }; +} - this.getBaseLayer = function () { - return glProjLayer !== null ? glProjLayer : glBaseLayer; - }; +function WebGLRenderLists() { - this.getBinding = function () { - return glBinding; - }; + let lists = new WeakMap(); - this.getFrame = function () { - return xrFrame; - }; + function get( scene, renderCallDepth ) { - this.getSession = function () { - return session; - }; + const listArray = lists.get( scene ); + let list; - this.setSession = async function (value) { - session = value; + if ( listArray === undefined ) { - if (session !== null) { - initialRenderTarget = renderer.getRenderTarget(); - session.addEventListener('select', onSessionEvent); - session.addEventListener('selectstart', onSessionEvent); - session.addEventListener('selectend', onSessionEvent); - session.addEventListener('squeeze', onSessionEvent); - session.addEventListener('squeezestart', onSessionEvent); - session.addEventListener('squeezeend', onSessionEvent); - session.addEventListener('end', onSessionEnd); - session.addEventListener('inputsourceschange', onInputSourcesChange); - - if (attributes.xrCompatible !== true) { - await gl.makeXRCompatible(); - } + list = new WebGLRenderList(); + lists.set( scene, [ list ] ); - if (session.renderState.layers === undefined || renderer.capabilities.isWebGL2 === false) { - const layerInit = { - antialias: session.renderState.layers === undefined ? attributes.antialias : true, - alpha: attributes.alpha, - depth: attributes.depth, - stencil: attributes.stencil, - framebufferScaleFactor: framebufferScaleFactor - }; - glBaseLayer = new XRWebGLLayer(session, gl, layerInit); - session.updateRenderState({ - baseLayer: glBaseLayer - }); - newRenderTarget = new WebGLRenderTarget(glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, { - format: RGBAFormat, - type: UnsignedByteType, - encoding: renderer.outputEncoding - }); - } else { - let depthFormat = null; - let depthType = null; - let glDepthFormat = null; + } else { - if (attributes.depth) { - glDepthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24; - depthFormat = attributes.stencil ? DepthStencilFormat : DepthFormat; - depthType = attributes.stencil ? UnsignedInt248Type : UnsignedIntType; - } + if ( renderCallDepth >= listArray.length ) { - const projectionlayerInit = { - colorFormat: renderer.outputEncoding === sRGBEncoding ? gl.SRGB8_ALPHA8 : gl.RGBA8, - depthFormat: glDepthFormat, - scaleFactor: framebufferScaleFactor - }; - glBinding = new XRWebGLBinding(session, gl); - glProjLayer = glBinding.createProjectionLayer(projectionlayerInit); - session.updateRenderState({ - layers: [glProjLayer] - }); - newRenderTarget = new WebGLRenderTarget(glProjLayer.textureWidth, glProjLayer.textureHeight, { - format: RGBAFormat, - type: UnsignedByteType, - depthTexture: new DepthTexture(glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat), - stencilBuffer: attributes.stencil, - encoding: renderer.outputEncoding, - samples: attributes.antialias ? 4 : 0 - }); - const renderTargetProperties = renderer.properties.get(newRenderTarget); - renderTargetProperties.__ignoreDepthValues = glProjLayer.ignoreDepthValues; - } + list = new WebGLRenderList(); + listArray.push( list ); - newRenderTarget.isXRRenderTarget = true; // TODO Remove this when possible, see #23278 - // Set foveation to maximum. + } else { + + list = listArray[ renderCallDepth ]; - this.setFoveation(1.0); - customReferenceSpace = null; - referenceSpace = await session.requestReferenceSpace(referenceSpaceType); - animation.setContext(session); - animation.start(); - scope.isPresenting = true; - scope.dispatchEvent({ - type: 'sessionstart' - }); } - }; - function onInputSourcesChange(event) { - const inputSources = session.inputSources; // Assign controllers to available inputSources + } - for (let i = 0; i < inputSources.length; i++) { - const index = inputSources[i].handedness === 'right' ? 1 : 0; - inputSourcesMap.set(inputSources[i], controllers[index]); - } // Notify disconnected + return list; + } - for (let i = 0; i < event.removed.length; i++) { - const inputSource = event.removed[i]; - const controller = inputSourcesMap.get(inputSource); + function dispose() { - if (controller) { - controller.dispatchEvent({ - type: 'disconnected', - data: inputSource - }); - inputSourcesMap.delete(inputSource); - } - } // Notify connected + lists = new WeakMap(); + } - for (let i = 0; i < event.added.length; i++) { - const inputSource = event.added[i]; - const controller = inputSourcesMap.get(inputSource); + return { + get: get, + dispose: dispose + }; - if (controller) { - controller.dispatchEvent({ - type: 'connected', - data: inputSource - }); - } - } - } // +} +function UniformsCache() { - 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 - */ + const lights = {}; - 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 - // most likely identical top and bottom frustum extents. - // Use the left camera for these values. + return { - const near = projL[14] / (projL[10] - 1); - const far = projL[14] / (projL[10] + 1); - const topFov = (projL[9] + 1) / projL[5]; - const bottomFov = (projL[9] - 1) / projL[5]; - 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`. + get: function ( light ) { - const zOffset = ipd / (-leftFov + rightFov); - const xOffset = zOffset * -leftFov; // TODO: Better way to apply this offset? + if ( lights[ light.id ] !== undefined ) { - 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 - // 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. + return lights[ light.id ]; - const near2 = near + zOffset; - const far2 = far + zOffset; - const left2 = left - xOffset; - const right2 = right + (ipd - xOffset); - const top2 = topFov * far / far2 * near2; - 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 - }); - _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); // 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); - 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 - + let uniforms; - if (cameras.length === 2) { - setProjectionFromUnion(cameraVR, cameraL, cameraR); - } else { - // assume single camera setup (AR) - cameraVR.projectionMatrix.copy(cameraL.projectionMatrix); - } - }; + switch ( light.type ) { - this.getCamera = function () { - return cameraVR; - }; + case 'DirectionalLight': + uniforms = { + direction: new Vector3(), + color: new Color() + }; + break; - this.getFoveation = function () { - if (glProjLayer !== null) { - return glProjLayer.fixedFoveation; - } + case 'SpotLight': + uniforms = { + position: new Vector3(), + direction: new Vector3(), + color: new Color(), + distance: 0, + coneCos: 0, + penumbraCos: 0, + decay: 0 + }; + break; - if (glBaseLayer !== null) { - return glBaseLayer.fixedFoveation; - } + case 'PointLight': + uniforms = { + position: new Vector3(), + color: new Color(), + distance: 0, + decay: 0 + }; + break; - return undefined; - }; + case 'HemisphereLight': + uniforms = { + direction: new Vector3(), + skyColor: new Color(), + groundColor: new Color() + }; + break; - this.setFoveation = function (foveation) { - // 0 = no foveation = full resolution - // 1 = maximum foveation = the edges render at lower resolution - if (glProjLayer !== null) { - glProjLayer.fixedFoveation = foveation; - } + case 'RectAreaLight': + uniforms = { + color: new Color(), + position: new Vector3(), + halfWidth: new Vector3(), + halfHeight: new Vector3() + }; + break; - if (glBaseLayer !== null && glBaseLayer.fixedFoveation !== undefined) { - glBaseLayer.fixedFoveation = foveation; } - }; // 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; // check if it's necessary to rebuild cameraVR's camera list + lights[ light.id ] = uniforms; - if (views.length !== cameraVR.cameras.length) { - cameraVR.cameras.length = 0; - cameraVRNeedsUpdate = true; - } + return uniforms; - 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. + }; - if (i === 0) { - renderer.setRenderTargetTextures(newRenderTarget, glSubImage.colorTexture, glProjLayer.ignoreDepthValues ? undefined : glSubImage.depthStencilTexture); - renderer.setRenderTarget(newRenderTarget); - } - } +} +<<<<<<< HEAD let camera = cameras[i]; if (camera === undefined) { @@ -18869,1454 +20405,834 @@ class WebXRManager extends EventDispatcher { camera.matrix.fromArray(view.transform.matrix); camera.projectionMatrix.fromArray(view.projectionMatrix); camera.viewport.set(viewport.x, viewport.y, viewport.width, viewport.height); +======= +function ShadowUniformsCache() { +>>>>>>> mrdoob-dev - if (i === 0) { - cameraVR.matrix.copy(camera.matrix); - } + const lights = {}; - if (cameraVRNeedsUpdate === true) { - cameraVR.cameras.push(camera); - } - } - } // + return { + get: function ( light ) { - const inputSources = session.inputSources; + if ( lights[ light.id ] !== undefined ) { - for (let i = 0; i < controllers.length; i++) { - const inputSource = inputSources[i]; - const controller = inputSourcesMap.get(inputSource); + return lights[ light.id ]; - if (controller !== undefined) { - controller.update(inputSource, frame, customReferenceSpace || referenceSpace); - } } - if (onAnimationFrameCallback) onAnimationFrameCallback(time, frame); - xrFrame = null; - } - - const animation = new WebGLAnimation(); - animation.setAnimationLoop(onAnimationFrame); + let uniforms; - this.setAnimationLoop = function (callback) { - onAnimationFrameCallback = callback; - }; + switch ( light.type ) { - this.dispose = function () {}; - } + case 'DirectionalLight': + uniforms = { + shadowBias: 0, + shadowNormalBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2() + }; + break; -} + case 'SpotLight': + uniforms = { + shadowBias: 0, + shadowNormalBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2() + }; + break; -function WebGLMaterials(renderer, properties) { - function refreshFogUniforms(uniforms, fog) { - uniforms.fogColor.value.copy(fog.color); + case 'PointLight': + uniforms = { + shadowBias: 0, + shadowNormalBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2(), + shadowCameraNear: 1, + shadowCameraFar: 1000 + }; + break; - if (fog.isFog) { - uniforms.fogNear.value = fog.near; - uniforms.fogFar.value = fog.far; - } else if (fog.isFogExp2) { - uniforms.fogDensity.value = fog.density; - } - } + // TODO (abelnation): set RectAreaLight shadow uniforms - function refreshMaterialUniforms(uniforms, material, pixelRatio, height, transmissionRenderTarget) { - if (material.isMeshBasicMaterial) { - refreshUniformsCommon(uniforms, material); - } else if (material.isMeshLambertMaterial) { - refreshUniformsCommon(uniforms, material); - } else if (material.isMeshToonMaterial) { - refreshUniformsCommon(uniforms, material); - refreshUniformsToon(uniforms, material); - } else if (material.isMeshPhongMaterial) { - refreshUniformsCommon(uniforms, material); - refreshUniformsPhong(uniforms, material); - } else if (material.isMeshStandardMaterial) { - refreshUniformsCommon(uniforms, material); - refreshUniformsStandard(uniforms, material); - - if (material.isMeshPhysicalMaterial) { - refreshUniformsPhysical(uniforms, material, transmissionRenderTarget); - } - } else if (material.isMeshMatcapMaterial) { - refreshUniformsCommon(uniforms, material); - refreshUniformsMatcap(uniforms, material); - } else if (material.isMeshDepthMaterial) { - refreshUniformsCommon(uniforms, material); - } else if (material.isMeshDistanceMaterial) { - refreshUniformsCommon(uniforms, material); - refreshUniformsDistance(uniforms, material); - } else if (material.isMeshNormalMaterial) { - refreshUniformsCommon(uniforms, material); - } else if (material.isLineBasicMaterial) { - refreshUniformsLine(uniforms, material); - - if (material.isLineDashedMaterial) { - refreshUniformsDash(uniforms, material); - } - } else if (material.isPointsMaterial) { - refreshUniformsPoints(uniforms, material, pixelRatio, height); - } else if (material.isSpriteMaterial) { - refreshUniformsSprites(uniforms, material); - } else if (material.isShadowMaterial) { - uniforms.color.value.copy(material.color); - uniforms.opacity.value = material.opacity; - } else if (material.isShaderMaterial) { - material.uniformsNeedUpdate = false; // #15581 - } - } + } - function refreshUniformsCommon(uniforms, material) { - uniforms.opacity.value = material.opacity; + lights[ light.id ] = uniforms; - if (material.color) { - uniforms.diffuse.value.copy(material.color); - } + return uniforms; - 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; - } +let nextVersion = 0; - if (material.normalMap) { - uniforms.normalMap.value = material.normalMap; - uniforms.normalScale.value.copy(material.normalScale); - if (material.side === BackSide) uniforms.normalScale.value.negate(); - } +function shadowCastingAndTexturingLightsFirst( lightA, lightB ) { - if (material.specularMap) { - uniforms.specularMap.value = material.specularMap; - } + return ( lightB.castShadow ? 2 : 0 ) - ( lightA.castShadow ? 2 : 0 ) + ( lightB.map ? 1 : 0 ) - ( lightA.map ? 1 : 0 ); - if (material.alphaTest > 0) { - uniforms.alphaTest.value = material.alphaTest; - } +} - const envMap = properties.get(material).envMap; +function WebGLLights( extensions, capabilities ) { - if (envMap) { - uniforms.envMap.value = envMap; - uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1; - uniforms.reflectivity.value = material.reflectivity; - uniforms.ior.value = material.ior; - uniforms.refractionRatio.value = material.refractionRatio; - } + const cache = new UniformsCache(); - if (material.lightMap) { - uniforms.lightMap.value = material.lightMap; // artist-friendly light intensity scaling factor + const shadowCache = ShadowUniformsCache(); - const scaleFactor = renderer.physicallyCorrectLights !== true ? Math.PI : 1; - uniforms.lightMapIntensity.value = material.lightMapIntensity * scaleFactor; - } + const state = { - if (material.aoMap) { - uniforms.aoMap.value = material.aoMap; - uniforms.aoMapIntensity.value = material.aoMapIntensity; - } // uv repeat and offset setting priorities - // 1. color map - // 2. specular map - // 3. displacementMap map - // 4. normal map - // 5. bump map - // 6. roughnessMap map - // 7. metalnessMap map - // 8. alphaMap map - // 9. emissiveMap map - // 10. clearcoat map - // 11. clearcoat normal map - // 12. clearcoat roughnessMap map - // 13. iridescence map - // 14. iridescence thickness map - // 15. specular intensity map - // 16. specular tint map - // 17. transmission map - // 18. thickness map + version: 0, + hash: { + directionalLength: - 1, + pointLength: - 1, + spotLength: - 1, + rectAreaLength: - 1, + hemiLength: - 1, + + numDirectionalShadows: - 1, + numPointShadows: - 1, + numSpotShadows: - 1, + numSpotMaps: - 1 + }, - let uvScaleMap; + 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 - if (material.map) { - uvScaleMap = material.map; - } else if (material.specularMap) { - uvScaleMap = material.specularMap; - } else if (material.displacementMap) { - uvScaleMap = material.displacementMap; - } else if (material.normalMap) { - uvScaleMap = material.normalMap; - } else if (material.bumpMap) { - uvScaleMap = material.bumpMap; - } else if (material.roughnessMap) { - uvScaleMap = material.roughnessMap; - } else if (material.metalnessMap) { - uvScaleMap = material.metalnessMap; - } else if (material.alphaMap) { - uvScaleMap = material.alphaMap; - } else if (material.emissiveMap) { - uvScaleMap = material.emissiveMap; - } else if (material.clearcoatMap) { - uvScaleMap = material.clearcoatMap; - } else if (material.clearcoatNormalMap) { - uvScaleMap = material.clearcoatNormalMap; - } else if (material.clearcoatRoughnessMap) { - uvScaleMap = material.clearcoatRoughnessMap; - } else if (material.iridescenceMap) { - uvScaleMap = material.iridescenceMap; - } else if (material.iridescenceThicknessMap) { - uvScaleMap = material.iridescenceThicknessMap; - } else if (material.specularIntensityMap) { - uvScaleMap = material.specularIntensityMap; - } else if (material.specularColorMap) { - uvScaleMap = material.specularColorMap; - } else if (material.transmissionMap) { - uvScaleMap = material.transmissionMap; - } else if (material.thicknessMap) { - uvScaleMap = material.thicknessMap; - } else if (material.sheenColorMap) { - uvScaleMap = material.sheenColorMap; - } else if (material.sheenRoughnessMap) { - uvScaleMap = material.sheenRoughnessMap; - } + }; - if (uvScaleMap !== undefined) { - // backwards compatibility - if (uvScaleMap.isWebGLRenderTarget) { - uvScaleMap = uvScaleMap.texture; - } + for ( let i = 0; i < 9; i ++ ) state.probe.push( new Vector3() ); - if (uvScaleMap.matrixAutoUpdate === true) { - uvScaleMap.updateMatrix(); - } + const vector3 = new Vector3(); + const matrix4 = new Matrix4(); + const matrix42 = new Matrix4(); - uniforms.uvTransform.value.copy(uvScaleMap.matrix); - } // uv repeat and offset setting priorities for uv2 - // 1. ao map - // 2. light map + function setup( lights, physicallyCorrectLights ) { + let r = 0, g = 0, b = 0; - let uv2ScaleMap; + for ( let i = 0; i < 9; i ++ ) state.probe[ i ].set( 0, 0, 0 ); - if (material.aoMap) { - uv2ScaleMap = material.aoMap; - } else if (material.lightMap) { - uv2ScaleMap = material.lightMap; - } + let directionalLength = 0; + let pointLength = 0; + let spotLength = 0; + let rectAreaLength = 0; + let hemiLength = 0; - if (uv2ScaleMap !== undefined) { - // backwards compatibility - if (uv2ScaleMap.isWebGLRenderTarget) { - uv2ScaleMap = uv2ScaleMap.texture; - } + let numDirectionalShadows = 0; + let numPointShadows = 0; + let numSpotShadows = 0; + let numSpotMaps = 0; + let numSpotShadowsWithMaps = 0; - if (uv2ScaleMap.matrixAutoUpdate === true) { - uv2ScaleMap.updateMatrix(); - } + // ordering : [shadow casting + map texturing, map texturing, shadow casting, none ] + lights.sort( shadowCastingAndTexturingLightsFirst ); - uniforms.uv2Transform.value.copy(uv2ScaleMap.matrix); - } - } + // artist-friendly light intensity scaling factor + const scaleFactor = ( physicallyCorrectLights !== true ) ? Math.PI : 1; - function refreshUniformsLine(uniforms, material) { - uniforms.diffuse.value.copy(material.color); - uniforms.opacity.value = material.opacity; - } + for ( let i = 0, l = lights.length; i < l; i ++ ) { - function refreshUniformsDash(uniforms, material) { - uniforms.dashSize.value = material.dashSize; - uniforms.totalSize.value = material.dashSize + material.gapSize; - uniforms.scale.value = material.scale; - } + const light = lights[ i ]; - 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; + const color = light.color; + const intensity = light.intensity; + const distance = light.distance; - if (material.map) { - uniforms.map.value = material.map; - } + const shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null; - if (material.alphaMap) { - uniforms.alphaMap.value = material.alphaMap; - } + if ( light.isAmbientLight ) { - if (material.alphaTest > 0) { - uniforms.alphaTest.value = material.alphaTest; - } // uv repeat and offset setting priorities - // 1. color map - // 2. alpha map + r += color.r * intensity * scaleFactor; + g += color.g * intensity * scaleFactor; + b += color.b * intensity * scaleFactor; + } else if ( light.isLightProbe ) { - let uvScaleMap; + for ( let j = 0; j < 9; j ++ ) { - if (material.map) { - uvScaleMap = material.map; - } else if (material.alphaMap) { - uvScaleMap = material.alphaMap; - } + state.probe[ j ].addScaledVector( light.sh.coefficients[ j ], intensity ); - if (uvScaleMap !== undefined) { - if (uvScaleMap.matrixAutoUpdate === true) { - uvScaleMap.updateMatrix(); - } + } - uniforms.uvTransform.value.copy(uvScaleMap.matrix); - } - } + } else if ( light.isDirectionalLight ) { - function refreshUniformsSprites(uniforms, material) { - uniforms.diffuse.value.copy(material.color); - uniforms.opacity.value = material.opacity; - uniforms.rotation.value = material.rotation; + const uniforms = cache.get( light ); - if (material.map) { - uniforms.map.value = material.map; - } + uniforms.color.copy( light.color ).multiplyScalar( light.intensity * scaleFactor ); - if (material.alphaMap) { - uniforms.alphaMap.value = material.alphaMap; - } + if ( light.castShadow ) { - if (material.alphaTest > 0) { - uniforms.alphaTest.value = material.alphaTest; - } // uv repeat and offset setting priorities - // 1. color map - // 2. alpha map + const shadow = light.shadow; + const shadowUniforms = shadowCache.get( light ); - let uvScaleMap; + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowNormalBias = shadow.normalBias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; - if (material.map) { - uvScaleMap = material.map; - } else if (material.alphaMap) { - uvScaleMap = material.alphaMap; - } + state.directionalShadow[ directionalLength ] = shadowUniforms; + state.directionalShadowMap[ directionalLength ] = shadowMap; + state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; - if (uvScaleMap !== undefined) { - if (uvScaleMap.matrixAutoUpdate === true) { - uvScaleMap.updateMatrix(); - } + numDirectionalShadows ++; - 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 ) - } + state.directional[ directionalLength ] = uniforms; - function refreshUniformsToon(uniforms, material) { - if (material.gradientMap) { - uniforms.gradientMap.value = material.gradientMap; - } - } + directionalLength ++; - function refreshUniformsStandard(uniforms, material) { - uniforms.roughness.value = material.roughness; - uniforms.metalness.value = material.metalness; + } else if ( light.isSpotLight ) { - if (material.roughnessMap) { - uniforms.roughnessMap.value = material.roughnessMap; - } + const uniforms = cache.get( light ); - if (material.metalnessMap) { - uniforms.metalnessMap.value = material.metalnessMap; - } + uniforms.position.setFromMatrixPosition( light.matrixWorld ); - const envMap = properties.get(material).envMap; + uniforms.color.copy( color ).multiplyScalar( intensity * scaleFactor ); + uniforms.distance = distance; - if (envMap) { - //uniforms.envMap.value = material.envMap; // part of uniforms common - uniforms.envMapIntensity.value = material.envMapIntensity; - } - } + uniforms.coneCos = Math.cos( light.angle ); + uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) ); + uniforms.decay = light.decay; - function refreshUniformsPhysical(uniforms, material, transmissionRenderTarget) { - uniforms.ior.value = material.ior; // also part of uniforms common + state.spot[ spotLength ] = uniforms; - if (material.sheen > 0) { - uniforms.sheenColor.value.copy(material.sheenColor).multiplyScalar(material.sheen); - uniforms.sheenRoughness.value = material.sheenRoughness; + const shadow = light.shadow; - if (material.sheenColorMap) { - uniforms.sheenColorMap.value = material.sheenColorMap; - } + if ( light.map ) { - if (material.sheenRoughnessMap) { - uniforms.sheenRoughnessMap.value = material.sheenRoughnessMap; - } - } + state.spotLightMap[ numSpotMaps ] = light.map; + numSpotMaps ++; - if (material.clearcoat > 0) { - uniforms.clearcoat.value = material.clearcoat; - uniforms.clearcoatRoughness.value = material.clearcoatRoughness; + // make sure the lightMatrix is up to date + // TODO : do it if required only + shadow.updateMatrices( light ); - if (material.clearcoatMap) { - uniforms.clearcoatMap.value = material.clearcoatMap; - } + if ( light.castShadow ) numSpotShadowsWithMaps ++; - if (material.clearcoatRoughnessMap) { - uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap; - } + } - if (material.clearcoatNormalMap) { - uniforms.clearcoatNormalScale.value.copy(material.clearcoatNormalScale); - uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; + state.spotLightMatrix[ spotLength ] = shadow.matrix; - if (material.side === BackSide) { - uniforms.clearcoatNormalScale.value.negate(); - } - } - } + if ( light.castShadow ) { - 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]; + const shadowUniforms = shadowCache.get( light ); - if (material.iridescenceMap) { - uniforms.iridescenceMap.value = material.iridescenceMap; - } + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowNormalBias = shadow.normalBias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; - if (material.iridescenceThicknessMap) { - uniforms.iridescenceThicknessMap.value = material.iridescenceThicknessMap; - } - } + state.spotShadow[ spotLength ] = shadowUniforms; + state.spotShadowMap[ spotLength ] = shadowMap; - if (material.transmission > 0) { - uniforms.transmission.value = material.transmission; - uniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture; - uniforms.transmissionSamplerSize.value.set(transmissionRenderTarget.width, transmissionRenderTarget.height); + numSpotShadows ++; - if (material.transmissionMap) { - uniforms.transmissionMap.value = material.transmissionMap; - } + } - uniforms.thickness.value = material.thickness; + spotLength ++; - if (material.thicknessMap) { - uniforms.thicknessMap.value = material.thicknessMap; - } + } else if ( light.isRectAreaLight ) { - uniforms.attenuationDistance.value = material.attenuationDistance; - uniforms.attenuationColor.value.copy(material.attenuationColor); - } + const uniforms = cache.get( light ); - uniforms.specularIntensity.value = material.specularIntensity; - uniforms.specularColor.value.copy(material.specularColor); + uniforms.color.copy( color ).multiplyScalar( intensity ); - if (material.specularIntensityMap) { - uniforms.specularIntensityMap.value = material.specularIntensityMap; - } + uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 ); + uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 ); - if (material.specularColorMap) { - uniforms.specularColorMap.value = material.specularColorMap; - } - } + state.rectArea[ rectAreaLength ] = uniforms; - function refreshUniformsMatcap(uniforms, material) { - if (material.matcap) { - uniforms.matcap.value = material.matcap; - } - } + rectAreaLength ++; - function refreshUniformsDistance(uniforms, material) { - uniforms.referencePosition.value.copy(material.referencePosition); - uniforms.nearDistance.value = material.nearDistance; - uniforms.farDistance.value = material.farDistance; - } + } else if ( light.isPointLight ) { - return { - refreshFogUniforms: refreshFogUniforms, - refreshMaterialUniforms: refreshMaterialUniforms - }; -} + const uniforms = cache.get( light ); -function createCanvasElement() { - const canvas = createElementNS('canvas'); - canvas.style.display = 'block'; - return canvas; -} + uniforms.color.copy( light.color ).multiplyScalar( light.intensity * scaleFactor ); + uniforms.distance = light.distance; + uniforms.decay = light.decay; -function WebGLRenderer(parameters = {}) { - this.isWebGLRenderer = true; + if ( light.castShadow ) { - 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; + const shadow = light.shadow; - let _alpha; + const shadowUniforms = shadowCache.get( light ); - if (_context !== null) { - _alpha = _context.getContextAttributes().alpha; - } else { - _alpha = parameters.alpha !== undefined ? parameters.alpha : false; - } + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowNormalBias = shadow.normalBias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; + shadowUniforms.shadowCameraNear = shadow.camera.near; + shadowUniforms.shadowCameraFar = shadow.camera.far; - let currentRenderList = null; - 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. + state.pointShadow[ pointLength ] = shadowUniforms; + state.pointShadowMap[ pointLength ] = shadowMap; + state.pointShadowMatrix[ pointLength ] = light.shadow.matrix; - const renderListStack = []; - const renderStateStack = []; // public properties + numPointShadows ++; - this.domElement = _canvas; // Debug configuration container + } - this.debug = { - /** - * Enables error checking and reporting when shader programs are being compiled - * @type {boolean} - */ - checkShaderErrors: true - }; // clearing + state.point[ pointLength ] = uniforms; - this.autoClear = true; - this.autoClearColor = true; - this.autoClearDepth = true; - this.autoClearStencil = true; // scene graph + pointLength ++; - this.sortObjects = true; // user-defined clipping + } else if ( light.isHemisphereLight ) { - this.clippingPlanes = []; - this.localClippingEnabled = false; // physically based shading + const uniforms = cache.get( light ); - this.outputEncoding = LinearEncoding; // physical lights + uniforms.skyColor.copy( light.color ).multiplyScalar( intensity * scaleFactor ); + uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity * scaleFactor ); - this.physicallyCorrectLights = false; // tone mapping + state.hemi[ hemiLength ] = uniforms; - this.toneMapping = NoToneMapping; - this.toneMappingExposure = 1.0; // + hemiLength ++; - 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; - let _isContextLost = false; // internal state cache + } - let _currentActiveCubeFace = 0; - let _currentActiveMipmapLevel = 0; - let _currentRenderTarget = null; + if ( rectAreaLength > 0 ) { - let _currentMaterialId = -1; + if ( capabilities.isWebGL2 ) { - let _currentCamera = null; + // WebGL 2 - const _currentViewport = new Vector4(); + state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; + state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; - const _currentScissor = new Vector4(); + } else { - let _currentScissorTest = null; // + // WebGL 1 - let _width = _canvas.width; - let _height = _canvas.height; - let _pixelRatio = 1; - let _opaqueSort = null; - let _transparentSort = null; + if ( extensions.has( 'OES_texture_float_linear' ) === true ) { - const _viewport = new Vector4(0, 0, _width, _height); + state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; + state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; - const _scissor = new Vector4(0, 0, _width, _height); + } else if ( extensions.has( 'OES_texture_half_float_linear' ) === true ) { - let _scissorTest = false; // frustum + state.rectAreaLTC1 = UniformsLib.LTC_HALF_1; + state.rectAreaLTC2 = UniformsLib.LTC_HALF_2; - const _frustum = new Frustum(); // clipping + } else { + console.error( 'THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.' ); - let _clippingEnabled = false; - let _localClippingEnabled = false; // transmission + } - let _transmissionRenderTarget = null; // camera matrices cache + } - const _projScreenMatrix = new Matrix4(); + } - const _vector2 = new Vector2(); + state.ambient[ 0 ] = r; + state.ambient[ 1 ] = g; + state.ambient[ 2 ] = b; - const _vector3 = new Vector3(); + const hash = state.hash; - const _emptyScene = { - background: null, - fog: null, - environment: null, - overrideMaterial: null, - isScene: true - }; + 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 ) { - function getTargetPixelRatio() { - return _currentRenderTarget === null ? _pixelRatio : 1; - } // initialize + state.directional.length = directionalLength; + state.spot.length = spotLength; + state.rectArea.length = rectAreaLength; + state.point.length = pointLength; + state.hemi.length = hemiLength; + state.directionalShadow.length = numDirectionalShadows; + state.directionalShadowMap.length = numDirectionalShadows; + state.pointShadow.length = numPointShadows; + state.pointShadowMap.length = numPointShadows; + state.spotShadow.length = numSpotShadows; + state.spotShadowMap.length = numSpotShadows; + state.directionalShadowMatrix.length = numDirectionalShadows; + state.pointShadowMatrix.length = numPointShadows; + state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps; + state.spotLightMap.length = numSpotMaps; + state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps; - let _gl = _context; + hash.directionalLength = directionalLength; + hash.pointLength = pointLength; + hash.spotLength = spotLength; + hash.rectAreaLength = rectAreaLength; + hash.hemiLength = hemiLength; - function getContext(contextNames, contextAttributes) { - for (let i = 0; i < contextNames.length; i++) { - const contextName = contextNames[i]; + hash.numDirectionalShadows = numDirectionalShadows; + hash.numPointShadows = numPointShadows; + hash.numSpotShadows = numSpotShadows; + hash.numSpotMaps = numSpotMaps; - const context = _canvas.getContext(contextName, contextAttributes); + state.version = nextVersion ++; - if (context !== null) return context; } - return null; } - try { - const contextAttributes = { - alpha: true, - depth: _depth, - stencil: _stencil, - antialias: _antialias, - premultipliedAlpha: _premultipliedAlpha, - preserveDrawingBuffer: _preserveDrawingBuffer, - powerPreference: _powerPreference, - failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat - }; // OffscreenCanvas does not have setAttribute, see #22811 + function setupView( lights, camera ) { - if ('setAttribute' in _canvas) _canvas.setAttribute('data-engine', `three.js r${REVISION}`); // event listeners must be registered before WebGL context is created, see #12753 + let directionalLength = 0; + let pointLength = 0; + let spotLength = 0; + let rectAreaLength = 0; + let hemiLength = 0; - _canvas.addEventListener('webglcontextlost', onContextLost, false); + const viewMatrix = camera.matrixWorldInverse; - _canvas.addEventListener('webglcontextrestored', onContextRestore, false); + for ( let i = 0, l = lights.length; i < l; i ++ ) { - _canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false); + const light = lights[ i ]; - if (_gl === null) { - const contextNames = ['webgl2', 'webgl', 'experimental-webgl']; + if ( light.isDirectionalLight ) { - if (_this.isWebGL1Renderer === true) { - contextNames.shift(); - } + const uniforms = state.directional[ directionalLength ]; - _gl = getContext(contextNames, contextAttributes); + uniforms.direction.setFromMatrixPosition( light.matrixWorld ); + vector3.setFromMatrixPosition( light.target.matrixWorld ); + uniforms.direction.sub( vector3 ); + uniforms.direction.transformDirection( viewMatrix ); - if (_gl === null) { - if (getContext(contextNames)) { - throw new Error('Error creating WebGL context with your selected attributes.'); - } else { - throw new Error('Error creating WebGL context.'); - } - } - } // Some experimental-webgl implementations do not have getShaderPrecisionFormat + directionalLength ++; + } else if ( light.isSpotLight ) { - if (_gl.getShaderPrecisionFormat === undefined) { - _gl.getShaderPrecisionFormat = function () { - return { - 'rangeMin': 1, - 'rangeMax': 1, - 'precision': 1 - }; - }; - } - } catch (error) { - console.error('THREE.WebGLRenderer: ' + error.message); - throw error; - } + const uniforms = state.spot[ spotLength ]; - 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; + uniforms.position.setFromMatrixPosition( light.matrixWorld ); + uniforms.position.applyMatrix4( viewMatrix ); - function initGLContext() { - extensions = new WebGLExtensions(_gl); - capabilities = new WebGLCapabilities(_gl, extensions, parameters); - extensions.init(capabilities); - utils = new WebGLUtils(_gl, extensions, capabilities); - state = new WebGLState(_gl, extensions, capabilities); - info = new WebGLInfo(_gl); - properties = new WebGLProperties(); - textures = new WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info); - cubemaps = new WebGLCubeMaps(_this); - cubeuvmaps = new WebGLCubeUVMaps(_this); - attributes = new WebGLAttributes(_gl, capabilities); - bindingStates = new WebGLBindingStates(_gl, extensions, attributes, capabilities); - geometries = new WebGLGeometries(_gl, attributes, info, bindingStates); - objects = new WebGLObjects(_gl, geometries, attributes, info); - morphtargets = new WebGLMorphtargets(_gl, capabilities, textures); - clipping = new WebGLClipping(properties); - programCache = new WebGLPrograms(_this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping); - materials = new WebGLMaterials(_this, properties); - renderLists = new WebGLRenderLists(); - renderStates = new WebGLRenderStates(extensions, capabilities); - background = new WebGLBackground(_this, cubemaps, state, objects, _alpha, _premultipliedAlpha); - shadowMap = new WebGLShadowMap(_this, objects, capabilities); - bufferRenderer = new WebGLBufferRenderer(_gl, extensions, info, capabilities); - indexedBufferRenderer = new WebGLIndexedBufferRenderer(_gl, extensions, info, capabilities); - info.programs = programCache.programs; - _this.capabilities = capabilities; - _this.extensions = extensions; - _this.properties = properties; - _this.renderLists = renderLists; - _this.shadowMap = shadowMap; - _this.state = state; - _this.info = info; - } + uniforms.direction.setFromMatrixPosition( light.matrixWorld ); + vector3.setFromMatrixPosition( light.target.matrixWorld ); + uniforms.direction.sub( vector3 ); + uniforms.direction.transformDirection( viewMatrix ); - initGLContext(); // xr + spotLength ++; - const xr = new WebXRManager(_this, _gl); - this.xr = xr; // API + } else if ( light.isRectAreaLight ) { - this.getContext = function () { - return _gl; - }; + const uniforms = state.rectArea[ rectAreaLength ]; - this.getContextAttributes = function () { - return _gl.getContextAttributes(); - }; + uniforms.position.setFromMatrixPosition( light.matrixWorld ); + uniforms.position.applyMatrix4( viewMatrix ); - this.forceContextLoss = function () { - const extension = extensions.get('WEBGL_lose_context'); - if (extension) extension.loseContext(); - }; + // extract local rotation of light to derive width/height half vectors + matrix42.identity(); + matrix4.copy( light.matrixWorld ); + matrix4.premultiply( viewMatrix ); + matrix42.extractRotation( matrix4 ); - this.forceContextRestore = function () { - const extension = extensions.get('WEBGL_lose_context'); - if (extension) extension.restoreContext(); - }; + uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 ); + uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 ); - this.getPixelRatio = function () { - return _pixelRatio; - }; + uniforms.halfWidth.applyMatrix4( matrix42 ); + uniforms.halfHeight.applyMatrix4( matrix42 ); - this.setPixelRatio = function (value) { - if (value === undefined) return; - _pixelRatio = value; - this.setSize(_width, _height, false); - }; + rectAreaLength ++; - this.getSize = function (target) { - return target.set(_width, _height); - }; + } else if ( light.isPointLight ) { - this.setSize = function (width, height, updateStyle) { - if (xr.isPresenting) { - console.warn('THREE.WebGLRenderer: Can\'t change size while VR device is presenting.'); - return; - } + const uniforms = state.point[ pointLength ]; - _width = width; - _height = height; - _canvas.width = Math.floor(width * _pixelRatio); - _canvas.height = Math.floor(height * _pixelRatio); + uniforms.position.setFromMatrixPosition( light.matrixWorld ); + uniforms.position.applyMatrix4( viewMatrix ); - if (updateStyle !== false) { - _canvas.style.width = width + 'px'; - _canvas.style.height = height + 'px'; - } + pointLength ++; - this.setViewport(0, 0, width, height); - }; + } else if ( light.isHemisphereLight ) { - this.getDrawingBufferSize = function (target) { - return target.set(_width * _pixelRatio, _height * _pixelRatio).floor(); - }; + const uniforms = state.hemi[ hemiLength ]; - this.setDrawingBufferSize = function (width, height, pixelRatio) { - _width = width; - _height = height; - _pixelRatio = pixelRatio; - _canvas.width = Math.floor(width * pixelRatio); - _canvas.height = Math.floor(height * pixelRatio); - this.setViewport(0, 0, width, height); - }; + uniforms.direction.setFromMatrixPosition( light.matrixWorld ); + uniforms.direction.transformDirection( viewMatrix ); - this.getCurrentViewport = function (target) { - return target.copy(_currentViewport); - }; + hemiLength ++; - 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); + return { + setup: setup, + setupView: setupView, + state: state }; - 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()); - }; +function WebGLRenderState( extensions, capabilities ) { - this.getScissorTest = function () { - return _scissorTest; - }; + const lights = new WebGLLights( extensions, capabilities ); - this.setScissorTest = function (boolean) { - state.setScissorTest(_scissorTest = boolean); - }; + const lightsArray = []; + const shadowsArray = []; - this.setOpaqueSort = function (method) { - _opaqueSort = method; - }; + function init() { - this.setTransparentSort = function (method) { - _transparentSort = method; - }; // Clearing + lightsArray.length = 0; + shadowsArray.length = 0; + } - this.getClearColor = function (target) { - return target.copy(background.getClearColor()); - }; + function pushLight( light ) { - this.setClearColor = function () { - background.setClearColor.apply(background, arguments); - }; + lightsArray.push( light ); - this.getClearAlpha = function () { - return background.getClearAlpha(); - }; + } - this.setClearAlpha = function () { - background.setClearAlpha.apply(background, arguments); - }; + function pushShadow( shadowLight ) { - 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; + shadowsArray.push( shadowLight ); - _gl.clear(bits); - }; + } - this.clearColor = function () { - this.clear(true, false, false); - }; + function setupLights( physicallyCorrectLights ) { - this.clearDepth = function () { - this.clear(false, true, false); - }; + lights.setup( lightsArray, physicallyCorrectLights ); - this.clearStencil = function () { - this.clear(false, false, true); - }; // + } + function setupLightsView( camera ) { - this.dispose = function () { - _canvas.removeEventListener('webglcontextlost', onContextLost, false); + lights.setupView( lightsArray, camera ); - _canvas.removeEventListener('webglcontextrestored', onContextRestore, false); + } - _canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false); + const state = { + lightsArray: lightsArray, + shadowsArray: shadowsArray, - renderLists.dispose(); - renderStates.dispose(); - properties.dispose(); - cubemaps.dispose(); - cubeuvmaps.dispose(); - objects.dispose(); - bindingStates.dispose(); - programCache.dispose(); - xr.dispose(); - xr.removeEventListener('sessionstart', onXRSessionStart); - xr.removeEventListener('sessionend', onXRSessionEnd); + lights: lights + }; - if (_transmissionRenderTarget) { - _transmissionRenderTarget.dispose(); + return { + init: init, + state: state, + setupLights: setupLights, + setupLightsView: setupLightsView, - _transmissionRenderTarget = null; - } + pushLight: pushLight, + pushShadow: pushShadow + }; - animation.stop(); - }; // Events +} +function WebGLRenderStates( extensions, capabilities ) { - function onContextLost(event) { - event.preventDefault(); - console.log('THREE.WebGLRenderer: Context Lost.'); - _isContextLost = true; - } + let renderStates = new WeakMap(); - function - /* event */ - onContextRestore() { - console.log('THREE.WebGLRenderer: Context Restored.'); - _isContextLost = false; - const infoAutoReset = info.autoReset; - const shadowMapEnabled = shadowMap.enabled; - const shadowMapAutoUpdate = shadowMap.autoUpdate; - const shadowMapNeedsUpdate = shadowMap.needsUpdate; - const shadowMapType = shadowMap.type; - initGLContext(); - info.autoReset = infoAutoReset; - shadowMap.enabled = shadowMapEnabled; - shadowMap.autoUpdate = shadowMapAutoUpdate; - shadowMap.needsUpdate = shadowMapNeedsUpdate; - shadowMap.type = shadowMapType; - } + function get( scene, renderCallDepth = 0 ) { - function onContextCreationError(event) { - console.error('THREE.WebGLRenderer: A WebGL context could not be created. Reason: ', event.statusMessage); - } + const renderStateArray = renderStates.get( scene ); + let renderState; - function onMaterialDispose(event) { - const material = event.target; - material.removeEventListener('dispose', onMaterialDispose); - deallocateMaterial(material); - } // Buffer deallocation + if ( renderStateArray === undefined ) { + renderState = new WebGLRenderState( extensions, capabilities ); + renderStates.set( scene, [ renderState ] ); - function deallocateMaterial(material) { - releaseMaterialProgramReferences(material); - properties.remove(material); - } + } else { - function releaseMaterialProgramReferences(material) { - const programs = properties.get(material).programs; + if ( renderCallDepth >= renderStateArray.length ) { - if (programs !== undefined) { - programs.forEach(function (program) { - programCache.releaseProgram(program); - }); + renderState = new WebGLRenderState( extensions, capabilities ); + renderStateArray.push( renderState ); - if (material.isShaderMaterial) { - programCache.releaseShaderCache(material); - } - } - } // Buffer rendering + } else { + renderState = renderStateArray[ renderCallDepth ]; - 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; // + return renderState; - if (index === null) { - if (position === undefined || position.count === 0) return; - } else if (index.count === 0) { - return; - } // + } + function dispose() { - let rangeFactor = 1; + renderStates = new WeakMap(); - if (material.wireframe === true) { - index = geometries.getWireframeAttribute(geometry); - rangeFactor = 2; - } + } - bindingStates.setup(object, material, program, geometry, index); - let attribute; - let renderer = bufferRenderer; + return { + get: get, + dispose: dispose + }; - if (index !== null) { - attribute = attributes.get(index); - renderer = indexedBufferRenderer; - renderer.setIndex(attribute); - } // +} +class MeshDepthMaterial extends Material { - 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) { - state.setLineWidth(material.wireframeLinewidth * getTargetPixelRatio()); - renderer.setMode(_gl.LINES); - } else { - renderer.setMode(_gl.TRIANGLES); - } - } else if (object.isLine) { - let lineWidth = material.linewidth; - if (lineWidth === undefined) lineWidth = 1; // Not using Line*Material + constructor( parameters ) { - state.setLineWidth(lineWidth * getTargetPixelRatio()); + super(); - if (object.isLineSegments) { - renderer.setMode(_gl.LINES); - } else if (object.isLineLoop) { - renderer.setMode(_gl.LINE_LOOP); - } else { - renderer.setMode(_gl.LINE_STRIP); - } - } else if (object.isPoints) { - renderer.setMode(_gl.POINTS); - } else if (object.isSprite) { - renderer.setMode(_gl.TRIANGLES); - } + this.isMeshDepthMaterial = true; - if (object.isInstancedMesh) { - renderer.renderInstances(drawStart, drawCount, object.count); - } else if (geometry.isInstancedBufferGeometry) { - const instanceCount = Math.min(geometry.instanceCount, geometry._maxInstanceCount); - renderer.renderInstances(drawStart, drawCount, instanceCount); - } else { - renderer.render(drawStart, drawCount); - } - }; // Compile + this.type = 'MeshDepthMaterial'; + this.depthPacking = BasicDepthPacking; - this.compile = function (scene, camera) { - currentRenderState = renderStates.get(scene); - currentRenderState.init(); - renderStateStack.push(currentRenderState); - scene.traverseVisible(function (object) { - if (object.isLight && object.layers.test(camera.layers)) { - currentRenderState.pushLight(object); + this.map = null; - if (object.castShadow) { - currentRenderState.pushShadow(object); - } - } - }); - currentRenderState.setupLights(_this.physicallyCorrectLights); - scene.traverse(function (object) { - const material = object.material; + this.alphaMap = null; - if (material) { - if (Array.isArray(material)) { - for (let i = 0; i < material.length; i++) { - const material2 = material[i]; - getProgram(material2, scene, object); - } - } else { - getProgram(material, scene, object); - } - } - }); - renderStateStack.pop(); - currentRenderState = null; - }; // Animation Loop + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + this.wireframe = false; + this.wireframeLinewidth = 1; - let onAnimationFrameCallback = null; + this.setValues( parameters ); - function onAnimationFrame(time) { - if (onAnimationFrameCallback) onAnimationFrameCallback(time); } - function onXRSessionStart() { - animation.stop(); - } + copy( source ) { - function onXRSessionEnd() { - animation.start(); - } + super.copy( source ); - const animation = new WebGLAnimation(); - animation.setAnimationLoop(onAnimationFrame); - if (typeof self !== 'undefined') animation.setContext(self); + this.depthPacking = source.depthPacking; - this.setAnimationLoop = function (callback) { - onAnimationFrameCallback = callback; - xr.setAnimationLoop(callback); - callback === null ? animation.stop() : animation.start(); - }; + this.map = source.map; - xr.addEventListener('sessionstart', onXRSessionStart); - xr.addEventListener('sessionend', onXRSessionEnd); // Rendering + this.alphaMap = source.alphaMap; - 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; - } + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; - if (_isContextLost === true) return; // update scene graph + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; - if (scene.autoUpdate === true) scene.updateMatrixWorld(); // update camera matrices and frustum + return this; - if (camera.parent === null) camera.updateMatrixWorld(); + } - if (xr.enabled === true && xr.isPresenting === true) { - if (xr.cameraAutoUpdate === true) xr.updateCamera(camera); - camera = xr.getCamera(); // use XR camera for rendering - } // +} +class MeshDistanceMaterial extends Material { - if (scene.isScene === true) scene.onBeforeRender(_this, scene, camera, _currentRenderTarget); - currentRenderState = renderStates.get(scene, renderStateStack.length); - currentRenderState.init(); - renderStateStack.push(currentRenderState); + constructor( parameters ) { - _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); + super(); - _frustum.setFromProjectionMatrix(_projScreenMatrix); + this.isMeshDistanceMaterial = true; - _localClippingEnabled = this.localClippingEnabled; - _clippingEnabled = clipping.init(this.clippingPlanes, _localClippingEnabled, camera); - currentRenderList = renderLists.get(scene, renderListStack.length); - currentRenderList.init(); - renderListStack.push(currentRenderList); - projectObject(scene, camera, 0, _this.sortObjects); - currentRenderList.finish(); + this.type = 'MeshDistanceMaterial'; - if (_this.sortObjects === true) { - currentRenderList.sort(_opaqueSort, _transparentSort); - } // + this.referencePosition = new Vector3(); + this.nearDistance = 1; + this.farDistance = 1000; + this.map = null; - if (_clippingEnabled === true) clipping.beginShadows(); - const shadowsArray = currentRenderState.state.shadowsArray; - shadowMap.render(shadowsArray, scene, camera); - if (_clippingEnabled === true) clipping.endShadows(); // + this.alphaMap = null; - if (this.info.autoReset === true) this.info.reset(); // + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; - background.render(currentRenderList, scene); // render scene + this.setValues( parameters ); - currentRenderState.setupLights(_this.physicallyCorrectLights); + } - if (camera.isArrayCamera) { - const cameras = camera.cameras; + copy( source ) { - 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); - } // + super.copy( source ); + this.referencePosition.copy( source.referencePosition ); + this.nearDistance = source.nearDistance; + this.farDistance = source.farDistance; - 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 + this.map = source.map; - textures.updateRenderTargetMipmap(_currentRenderTarget); - } // + this.alphaMap = source.alphaMap; + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; - if (scene.isScene === true) scene.onAfterRender(_this, scene, camera); // _gl.finish(); + return this; - bindingStates.resetDefaultState(); - _currentMaterialId = -1; - _currentCamera = null; - renderStateStack.pop(); + } - if (renderStateStack.length > 0) { - currentRenderState = renderStateStack[renderStateStack.length - 1]; - } else { - currentRenderState = null; - } +} - renderListStack.pop(); +const vertex = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; - if (renderListStack.length > 0) { - currentRenderList = renderListStack[renderListStack.length - 1]; - } else { - currentRenderList = null; - } - }; +const fragment = "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}"; - function projectObject(object, camera, groupOrder, sortObjects) { - if (object.visible === false) return; - const visible = object.layers.test(camera.layers); +function WebGLShadowMap( _renderer, _objects, _capabilities ) { - if (visible) { - if (object.isGroup) { - groupOrder = object.renderOrder; - } else if (object.isLOD) { - if (object.autoUpdate === true) object.update(camera); - } else if (object.isLight) { - currentRenderState.pushLight(object); - - if (object.castShadow) { - currentRenderState.pushShadow(object); - } - } else if (object.isSprite) { - if (!object.frustumCulled || _frustum.intersectsSprite(object)) { - if (sortObjects) { - _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); - } + let _frustum = new Frustum(); - const geometry = objects.update(object); - const material = object.material; + const _shadowMapSize = new Vector2(), + _viewportSize = new Vector2(), - if (material.visible) { - currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null); - } - } - } else if (object.isMesh || object.isLine || object.isPoints) { - if (object.isSkinnedMesh) { - // update skeleton only once in a frame - if (object.skeleton.frame !== info.render.frame) { - object.skeleton.update(); - object.skeleton.frame = info.render.frame; - } - } + _viewport = new Vector4(), - if (!object.frustumCulled || _frustum.intersectsObject(object)) { - if (sortObjects) { - _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); - } + _depthMaterial = new MeshDepthMaterial( { depthPacking: RGBADepthPacking } ), + _distanceMaterial = new MeshDistanceMaterial(), - const geometry = objects.update(object); - const material = object.material; + _materialCache = {}, - if (Array.isArray(material)) { - const groups = geometry.groups; + _maxTextureSize = _capabilities.maxTextureSize; - for (let i = 0, l = groups.length; i < l; i++) { - const group = groups[i]; - const groupMaterial = material[group.materialIndex]; + const shadowSide = { [ FrontSide ]: BackSide, [ BackSide ]: FrontSide, [ DoubleSide ]: DoubleSide }; - if (groupMaterial && groupMaterial.visible) { - currentRenderList.push(object, geometry, groupMaterial, groupOrder, _vector3.z, group); - } - } - } else if (material.visible) { - currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null); - } - } - } - } + const shadowMaterialVertical = new ShaderMaterial( { + defines: { + VSM_SAMPLES: 8 + }, + uniforms: { + shadow_pass: { value: null }, + resolution: { value: new Vector2() }, + radius: { value: 4.0 } + }, - const children = object.children; + vertexShader: vertex, + fragmentShader: fragment - 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; - const transparentObjects = currentRenderList.transparent; - currentRenderState.setupLightsView(camera); - if (transmissiveObjects.length > 0) renderTransmissionPass(opaqueObjects, scene, camera); - 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 + const shadowMaterialHorizontal = shadowMaterialVertical.clone(); + shadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1; - state.buffers.depth.setTest(true); - state.buffers.depth.setMask(true); - state.buffers.color.setMask(true); - state.setPolygonOffset(false); - } + const fullScreenTri = new BufferGeometry(); + fullScreenTri.setAttribute( + 'position', + new BufferAttribute( + new Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ), + 3 + ) + ); - function renderTransmissionPass(opaqueObjects, scene, camera) { - const isWebGL2 = capabilities.isWebGL2; + const fullScreenMesh = new Mesh( fullScreenTri, shadowMaterialVertical ); - if (_transmissionRenderTarget === null) { - _transmissionRenderTarget = new WebGLRenderTarget(1, 1, { - generateMipmaps: true, - type: extensions.has('EXT_color_buffer_half_float') ? HalfFloatType : UnsignedByteType, - minFilter: LinearMipmapLinearFilter, - samples: isWebGL2 && _antialias === true ? 4 : 0 - }); - } + const scope = this; - _this.getDrawingBufferSize(_vector2); + this.enabled = false; - if (isWebGL2) { - _transmissionRenderTarget.setSize(_vector2.x, _vector2.y); - } else { - _transmissionRenderTarget.setSize(floorPowerOfTwo(_vector2.x), floorPowerOfTwo(_vector2.y)); - } // + this.autoUpdate = true; + this.needsUpdate = false; + this.type = PCFShadowMap; - const currentRenderTarget = _this.getRenderTarget(); + this.render = function ( lights, scene, camera ) { - _this.setRenderTarget(_transmissionRenderTarget); + if ( scope.enabled === false ) return; + if ( scope.autoUpdate === false && scope.needsUpdate === false ) return; - _this.clear(); // 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. + if ( lights.length === 0 ) return; + const currentRenderTarget = _renderer.getRenderTarget(); + const activeCubeFace = _renderer.getActiveCubeFace(); + const activeMipmapLevel = _renderer.getActiveMipmapLevel(); - const currentToneMapping = _this.toneMapping; - _this.toneMapping = NoToneMapping; - renderObjects(opaqueObjects, scene, camera); - _this.toneMapping = currentToneMapping; - textures.updateMultisampleRenderTarget(_transmissionRenderTarget); - textures.updateRenderTargetMipmap(_transmissionRenderTarget); + const _state = _renderer.state; - _this.setRenderTarget(currentRenderTarget); - } + // 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 ); - function renderObjects(renderList, scene, camera) { - const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null; + // render depth map - 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; + 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 (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 ( shadow.autoUpdate === false && shadow.needsUpdate === false ) continue; - if (material.transparent === true && material.side === DoubleSide) { - material.side = BackSide; - material.needsUpdate = true; + _shadowMapSize.copy( shadow.mapSize ); - _this.renderBufferDirect(camera, scene, geometry, material, object, group); + const shadowFrameExtents = shadow.getFrameExtents(); - material.side = FrontSide; - material.needsUpdate = true; + _shadowMapSize.multiply( shadowFrameExtents ); - _this.renderBufferDirect(camera, scene, geometry, material, object, group); + _viewportSize.copy( shadow.mapSize ); - material.side = DoubleSide; - } else { - _this.renderBufferDirect(camera, scene, geometry, material, object, group); - } + if ( _shadowMapSize.x > _maxTextureSize || _shadowMapSize.y > _maxTextureSize ) { - object.onAfterRender(_this, scene, camera, geometry, material, group); - } + if ( _shadowMapSize.x > _maxTextureSize ) { - function getProgram(material, scene, object) { - if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... + _viewportSize.x = Math.floor( _maxTextureSize / shadowFrameExtents.x ); + _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x; + shadow.mapSize.x = _viewportSize.x; - const materialProperties = properties.get(material); - const lights = currentRenderState.state.lights; - const shadowsArray = currentRenderState.state.shadowsArray; - 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 + } - materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null; - materialProperties.fog = scene.fog; - materialProperties.envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || materialProperties.environment); + if ( _shadowMapSize.y > _maxTextureSize ) { - if (programs === undefined) { - // new material - material.addEventListener('dispose', onMaterialDispose); - programs = new Map(); - materialProperties.programs = programs; - } + _viewportSize.y = Math.floor( _maxTextureSize / shadowFrameExtents.y ); + _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; + shadow.mapSize.y = _viewportSize.y; - 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; } - } else { - parameters.uniforms = programCache.getUniforms(material); - material.onBuild(object, parameters, _this); - material.onBeforeCompile(parameters, _this); - program = programCache.acquireProgram(parameters, programCacheKey); - programs.set(programCacheKey, program); - materialProperties.uniforms = parameters.uniforms; - } - const uniforms = materialProperties.uniforms; + if ( shadow.map === null ) { - if (!material.isShaderMaterial && !material.isRawShaderMaterial || material.clipping === true) { - uniforms.clippingPlanes = clipping.uniform; - } + const pars = ( this.type !== VSMShadowMap ) ? { minFilter: NearestFilter, magFilter: NearestFilter } : {}; - updateCommonMaterialProperties(material, parameters); // store the light setup it was created for + shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); + shadow.map.texture.name = light.name + '.shadowMap'; - materialProperties.needsLights = materialNeedsLights(material); - materialProperties.lightsStateVersion = lightsStateVersion; + shadow.camera.updateProjectionMatrix(); - if (materialProperties.needsLights) { - // wire up the material to this renderer's lighting state - uniforms.ambientLightColor.value = lights.state.ambient; - uniforms.lightProbe.value = lights.state.probe; - uniforms.directionalLights.value = lights.state.directional; - uniforms.directionalLightShadows.value = lights.state.directionalShadow; - uniforms.spotLights.value = lights.state.spot; - uniforms.spotLightShadows.value = lights.state.spotShadow; - uniforms.rectAreaLights.value = lights.state.rectArea; - uniforms.ltc_1.value = lights.state.rectAreaLTC1; - uniforms.ltc_2.value = lights.state.rectAreaLTC2; - uniforms.pointLights.value = lights.state.point; - uniforms.pointLightShadows.value = lights.state.pointShadow; - uniforms.hemisphereLights.value = lights.state.hemi; - uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; - uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix; - uniforms.spotShadowMap.value = lights.state.spotShadowMap; - uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix; - uniforms.pointShadowMap.value = lights.state.pointShadowMap; - uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; // TODO (abelnation): add area lights shadow info to uniforms - } + } - const progUniforms = program.getUniforms(); - const uniformsList = WebGLUniforms.seqWithValue(progUniforms.seq, uniforms); - materialProperties.currentProgram = program; - materialProperties.uniformsList = uniformsList; - return program; - } + _renderer.setRenderTarget( shadow.map ); + _renderer.clear(); +<<<<<<< HEAD function updateCommonMaterialProperties(material, parameters) { const materialProperties = properties.get(material); materialProperties.outputEncoding = parameters.outputEncoding; @@ -20333,10 +21249,13 @@ function WebGLRenderer(parameters = {}) { materialProperties.toneMapping = parameters.toneMapping; materialProperties.extraProgramCacheKey = parameters.extraProgramCacheKey; } +======= + const viewportCount = shadow.getViewportCount(); +>>>>>>> mrdoob-dev - function setProgram(camera, scene, geometry, material, object) { - if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... + for ( let vp = 0; vp < viewportCount; vp ++ ) { +<<<<<<< HEAD textures.resetTextureUnits(); const fog = scene.fog; const environment = material.isMeshStandardMaterial ? scene.environment : null; @@ -20353,20 +21272,32 @@ function WebGLRenderer(parameters = {}) { const materialProperties = properties.get(material); const lights = currentRenderState.state.lights; const extraProgramCacheKey = _this.extraProgramCacheKey; +======= + const viewport = shadow.getViewport( vp ); +>>>>>>> mrdoob-dev - 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 - // object instead of the material, once it becomes feasible - // (#8465, #8379) + _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 ); - clipping.setState(material, camera, useCache); } - } // + // do blur pass for VSM - let needsProgramChange = false; + if ( shadow.isPointLightShadow !== true && this.type === VSMShadowMap ) { +<<<<<<< HEAD if (material.version === materialProperties.__version) { if (materialProperties.needsLights && materialProperties.lightsStateVersion !== lights.state.version) { needsProgramChange = true; @@ -20407,14729 +21338,29212 @@ function WebGLRenderer(parameters = {}) { needsProgramChange = true; materialProperties.__version = material.version; } // +======= + VSMPass( shadow, camera ); +>>>>>>> mrdoob-dev + } - let program = materialProperties.currentProgram; + shadow.needsUpdate = false; - 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; + 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 (state.useProgram(program.program)) { - refreshProgram = true; - refreshMaterial = true; - refreshLights = true; } - if (material.id !== _currentMaterialId) { - _currentMaterialId = material.id; - refreshMaterial = true; + if ( shadow.mapPass === null ) { + + shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y ); + } - if (refreshProgram || _currentCamera !== camera) { - p_uniforms.setValue(_gl, 'projectionMatrix', camera.projectionMatrix); + // vertical pass - if (capabilities.logarithmicDepthBuffer) { - p_uniforms.setValue(_gl, 'logDepthBufFC', 2.0 / (Math.log(camera.far + 1.0) / Math.LN2)); - } + 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 ); - if (_currentCamera !== camera) { - _currentCamera = camera; // lighting uniforms depend on the camera so enforce an update - // now, in case this material supports lights - or later, when - // the next material that does gets activated: + // horizontal pass - refreshMaterial = true; // set to true on material change + 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 ); - refreshLights = true; // remains set until update done - } // load material specific uniforms - // (shader material also gets them for the sake of genericity) + } + function getDepthMaterial( object, material, light, shadowCameraNear, shadowCameraFar, type ) { - if (material.isShaderMaterial || material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshStandardMaterial || material.envMap) { - const uCamPos = p_uniforms.map.cameraPosition; + let result = null; - if (uCamPos !== undefined) { - uCamPos.setValue(_gl, _vector3.setFromMatrixPosition(camera.matrixWorld)); - } - } + const customMaterial = ( light.isPointLight === true ) ? object.customDistanceMaterial : object.customDepthMaterial; - if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial) { - p_uniforms.setValue(_gl, 'isOrthographic', camera.isOrthographicCamera === true); - } + if ( customMaterial !== undefined ) { - 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 - // 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 + result = customMaterial; + } else { - if (object.isSkinnedMesh) { - p_uniforms.setOptional(_gl, object, 'bindMatrix'); - p_uniforms.setOptional(_gl, object, 'bindMatrixInverse'); - const skeleton = object.skeleton; + result = ( light.isPointLight === true ) ? _distanceMaterial : _depthMaterial; - if (skeleton) { - if (capabilities.floatVertexTextures) { - if (skeleton.boneTexture === null) skeleton.computeBoneTexture(); - p_uniforms.setValue(_gl, 'boneTexture', skeleton.boneTexture, textures); - p_uniforms.setValue(_gl, 'boneTextureSize', skeleton.boneTextureSize); - } else { - console.warn('THREE.WebGLRenderer: SkinnedMesh can only be used with WebGL 2. With WebGL 1 OES_texture_float and vertex textures support is required.'); - } - } - } + 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 ) ) { - const morphAttributes = geometry.morphAttributes; + // in this case we need a unique material instance reflecting the + // appropriate state - if (morphAttributes.position !== undefined || morphAttributes.normal !== undefined || morphAttributes.color !== undefined && capabilities.isWebGL2 === true) { - morphtargets.update(object, geometry, material, program); - } + const keyA = result.uuid, keyB = material.uuid; - if (refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow) { - materialProperties.receiveShadow = object.receiveShadow; - p_uniforms.setValue(_gl, 'receiveShadow', object.receiveShadow); - } + let materialsForVariant = _materialCache[ keyA ]; - if (refreshMaterial) { - p_uniforms.setValue(_gl, 'toneMappingExposure', _this.toneMappingExposure); + if ( materialsForVariant === undefined ) { - 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 + materialsForVariant = {}; + _materialCache[ keyA ] = materialsForVariant; + + } + + let cachedMaterial = materialsForVariant[ keyB ]; + + if ( cachedMaterial === undefined ) { + + cachedMaterial = result.clone(); + materialsForVariant[ keyB ] = cachedMaterial; + + } + result = cachedMaterial; - 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; - } + result.visible = material.visible; + result.wireframe = material.wireframe; - if (material.isSpriteMaterial) { - p_uniforms.setValue(_gl, 'center', object.center); - } // common matrices + if ( type === VSMShadowMap ) { + result.side = ( material.shadowSide !== null ) ? material.shadowSide : material.side; - p_uniforms.setValue(_gl, 'modelViewMatrix', object.modelViewMatrix); - p_uniforms.setValue(_gl, 'normalMatrix', object.normalMatrix); - p_uniforms.setValue(_gl, 'modelMatrix', object.matrixWorld); - return program; - } // If uniforms are marked as clean, they don't need to be loaded to the GPU. + } else { + result.side = ( material.shadowSide !== null ) ? material.shadowSide : shadowSide[ material.side ]; - function markUniformsLightsNeedsUpdate(uniforms, value) { - uniforms.ambientLightColor.needsUpdate = value; - uniforms.lightProbe.needsUpdate = value; - uniforms.directionalLights.needsUpdate = value; - uniforms.directionalLightShadows.needsUpdate = value; - uniforms.pointLights.needsUpdate = value; - uniforms.pointLightShadows.needsUpdate = value; - uniforms.spotLights.needsUpdate = value; - uniforms.spotLightShadows.needsUpdate = value; - uniforms.rectAreaLights.needsUpdate = value; - uniforms.hemisphereLights.needsUpdate = value; - } + } - function materialNeedsLights(material) { - return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isShadowMaterial || material.isShaderMaterial && material.lights === true; - } + result.alphaMap = material.alphaMap; + result.alphaTest = material.alphaTest; + result.map = material.map; - this.getActiveCubeFace = function () { - return _currentActiveCubeFace; - }; + result.clipShadows = material.clipShadows; + result.clippingPlanes = material.clippingPlanes; + result.clipIntersection = material.clipIntersection; - this.getActiveMipmapLevel = function () { - return _currentActiveMipmapLevel; - }; + result.displacementMap = material.displacementMap; + result.displacementScale = material.displacementScale; + result.displacementBias = material.displacementBias; - this.getRenderTarget = function () { - return _currentRenderTarget; - }; + result.wireframeLinewidth = material.wireframeLinewidth; + result.linewidth = material.linewidth; - 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 ( light.isPointLight === true && result.isMeshDistanceMaterial === true ) { - if (renderTargetProperties.__hasExternalTextures) { - renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined; + result.referencePosition.setFromMatrixPosition( light.matrixWorld ); + result.nearDistance = shadowCameraNear; + result.farDistance = shadowCameraFar; - 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. - if (extensions.has('WEBGL_multisampled_render_to_texture') === true) { - console.warn('THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided'); - renderTargetProperties.__useRenderToTexture = false; - } - } } - }; - this.setRenderTargetFramebuffer = function (renderTarget, defaultFramebuffer) { - const renderTargetProperties = properties.get(renderTarget); - renderTargetProperties.__webglFramebuffer = defaultFramebuffer; - renderTargetProperties.__useDefaultFramebuffer = defaultFramebuffer === undefined; - }; + return result; - this.setRenderTarget = function (renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { - _currentRenderTarget = renderTarget; - _currentActiveCubeFace = activeCubeFace; - _currentActiveMipmapLevel = activeMipmapLevel; - let useDefaultFramebuffer = true; + } - if (renderTarget) { - const renderTargetProperties = properties.get(renderTarget); + function renderObject( object, camera, shadowCamera, light, type ) { - if (renderTargetProperties.__useDefaultFramebuffer !== undefined) { - // We need to make sure to rebind the framebuffer. - state.bindFramebuffer(_gl.FRAMEBUFFER, null); - useDefaultFramebuffer = false; - } else if (renderTargetProperties.__webglFramebuffer === undefined) { - textures.setupRenderTarget(renderTarget); - } else if (renderTargetProperties.__hasExternalTextures) { - // 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); - } - } + if ( object.visible === false ) return; - let framebuffer = null; - let isCube = false; - let isRenderTarget3D = false; + const visible = object.layers.test( camera.layers ); - if (renderTarget) { - const texture = renderTarget.texture; + if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) { - if (texture.isData3DTexture || texture.isDataArrayTexture) { - isRenderTarget3D = true; - } + if ( ( object.castShadow || ( object.receiveShadow && type === VSMShadowMap ) ) && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) { - const __webglFramebuffer = properties.get(renderTarget).__webglFramebuffer; + object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld ); - if (renderTarget.isWebGLCubeRenderTarget) { - framebuffer = __webglFramebuffer[activeCubeFace]; - isCube = true; - } else if (capabilities.isWebGL2 && renderTarget.samples > 0 && textures.useMultisampledRTT(renderTarget) === false) { - framebuffer = properties.get(renderTarget).__webglMultisampledFramebuffer; - } else { - framebuffer = __webglFramebuffer; - } + const geometry = _objects.update( object ); + const material = object.material; - _currentViewport.copy(renderTarget.viewport); + if ( Array.isArray( material ) ) { - _currentScissor.copy(renderTarget.scissor); + const groups = geometry.groups; - _currentScissorTest = renderTarget.scissorTest; - } else { - _currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor(); + for ( let k = 0, kl = groups.length; k < kl; k ++ ) { - _currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor(); + const group = groups[ k ]; + const groupMaterial = material[ group.materialIndex ]; - _currentScissorTest = _scissorTest; - } + if ( groupMaterial && groupMaterial.visible ) { - const framebufferBound = state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); + const depthMaterial = getDepthMaterial( object, groupMaterial, light, shadowCamera.near, shadowCamera.far, type ); - if (framebufferBound && capabilities.drawBuffers && useDefaultFramebuffer) { - state.drawBuffers(renderTarget, framebuffer); - } + _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group ); - 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; + } else if ( material.visible ) { - _gl.framebufferTextureLayer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureProperties.__webglTexture, activeMipmapLevel || 0, layer); - } + const depthMaterial = getDepthMaterial( object, material, light, shadowCamera.near, shadowCamera.far, type ); - _currentMaterialId = -1; // reset current material to ensure correct uniform bindings - }; + _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null ); - this.readRenderTargetPixels = function (renderTarget, x, y, width, height, buffer, activeCubeFaceIndex) { - if (!(renderTarget && renderTarget.isWebGLRenderTarget)) { - console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.'); - return; - } + } - 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')); + const children = object.children; - 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) + for ( let i = 0, l = children.length; i < l; i ++ ) { + renderObject( children[ i ], camera, shadowCamera, light, type ); - 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(); - }; +function WebGLState( gl, extensions, capabilities ) { - 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 + const isWebGL2 = capabilities.isWebGL2; - _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); + function ColorBuffer() { - _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); + let locked = false; - _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); + const color = new Vector4(); + let currentColorMask = null; + const currentColorClear = new Vector4( 0, 0, 0, 0 ); - if (srcTexture.isDataTexture) { - _gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data); - } else { - if (srcTexture.isCompressedTexture) { - _gl.compressedTexSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, srcTexture.mipmaps[0].width, srcTexture.mipmaps[0].height, glFormat, srcTexture.mipmaps[0].data); - } else { - _gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image); - } - } // Generate mipmaps only when copying level 0 + return { + setMask: function ( colorMask ) { - if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(_gl.TEXTURE_2D); - state.unbindTexture(); - }; + if ( currentColorMask !== colorMask && ! locked ) { - this.copyTextureToTexture3D = function (sourceBox, position, srcTexture, dstTexture, level = 0) { - if (_this.isWebGL1Renderer) { - console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: can only be used with WebGL2.'); - return; - } + gl.colorMask( colorMask, colorMask, colorMask, colorMask ); + currentColorMask = colorMask; - 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; - } else if (dstTexture.isDataArrayTexture) { - textures.setTexture2DArray(dstTexture, 0); - glTarget = _gl.TEXTURE_2D_ARRAY; - } else { - console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.'); - return; - } + }, - _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); + setLocked: function ( lock ) { - _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); + locked = lock; - _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); + }, - const unpackRowLen = _gl.getParameter(_gl.UNPACK_ROW_LENGTH); + setClear: function ( r, g, b, a, premultipliedAlpha ) { - const unpackImageHeight = _gl.getParameter(_gl.UNPACK_IMAGE_HEIGHT); + if ( premultipliedAlpha === true ) { - const unpackSkipPixels = _gl.getParameter(_gl.UNPACK_SKIP_PIXELS); + r *= a; g *= a; b *= a; - const unpackSkipRows = _gl.getParameter(_gl.UNPACK_SKIP_ROWS); + } - const unpackSkipImages = _gl.getParameter(_gl.UNPACK_SKIP_IMAGES); + color.set( r, g, b, a ); - const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[0] : srcTexture.image; + if ( currentColorClear.equals( color ) === false ) { - _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, image.width); + gl.clearColor( r, g, b, a ); + currentColorClear.copy( color ); - _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); + reset: function () { - _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, sourceBox.min.z); + locked = false; - 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) { - console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture.'); + currentColorMask = null; + currentColorClear.set( - 1, 0, 0, 0 ); // set to invalid state - _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); + function DepthBuffer() { - _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, unpackSkipRows); + let locked = false; - _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, unpackSkipImages); // Generate mipmaps only when copying level 0 + let currentDepthMask = null; + let currentDepthFunc = null; + let currentDepthClear = null; + return { - if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(glTarget); - state.unbindTexture(); - }; + setTest: function ( depthTest ) { - this.initTexture = function (texture) { - textures.setTexture2D(texture, 0); - state.unbindTexture(); - }; + if ( depthTest ) { - this.resetState = function () { - _currentActiveCubeFace = 0; - _currentActiveMipmapLevel = 0; - _currentRenderTarget = null; - state.reset(); - bindingStates.reset(); - }; + enable( gl.DEPTH_TEST ); - if (typeof __THREE_DEVTOOLS__ !== 'undefined') { - __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', { - detail: this - })); - } -} + } else { -class WebGL1Renderer extends WebGLRenderer {} + disable( gl.DEPTH_TEST ); -WebGL1Renderer.prototype.isWebGL1Renderer = true; + } -class FogExp2 { - constructor(color, density = 0.00025) { - this.isFogExp2 = true; - this.name = ''; - this.color = new Color(color); - this.density = density; - } + }, - clone() { - return new FogExp2(this.color, this.density); - } + setMask: function ( depthMask ) { - toJSON() { - return { - type: 'FogExp2', - color: this.color.getHex(), - density: this.density - }; - } + if ( currentDepthMask !== depthMask && ! locked ) { -} + gl.depthMask( depthMask ); + currentDepthMask = depthMask; -class Fog { - constructor(color, near = 1, far = 1000) { - this.isFog = true; - this.name = ''; - this.color = new Color(color); - this.near = near; - this.far = far; - } + } - clone() { - return new Fog(this.color, this.near, this.far); - } + }, - toJSON() { - return { - type: 'Fog', - color: this.color.getHex(), - near: this.near, - far: this.far - }; - } + setFunc: function ( depthFunc ) { -} + if ( currentDepthFunc !== depthFunc ) { -class Scene extends Object3D { - constructor() { - super(); - this.isScene = true; - this.type = 'Scene'; - this.background = null; - this.environment = null; - this.fog = null; - this.overrideMaterial = null; - this.autoUpdate = true; // checked by the renderer + switch ( depthFunc ) { - if (typeof __THREE_DEVTOOLS__ !== 'undefined') { - __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', { - detail: this - })); - } - } + case NeverDepth: - 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(); - if (source.overrideMaterial !== null) this.overrideMaterial = source.overrideMaterial.clone(); - this.autoUpdate = source.autoUpdate; - this.matrixAutoUpdate = source.matrixAutoUpdate; - return this; - } + gl.depthFunc( gl.NEVER ); + break; - toJSON(meta) { - const data = super.toJSON(meta); - if (this.fog !== null) data.object.fog = this.fog.toJSON(); - return data; - } + case AlwaysDepth: -} + gl.depthFunc( gl.ALWAYS ); + break; -class InterleavedBuffer { - constructor(array, stride) { - this.isInterleavedBuffer = true; - this.array = array; - this.stride = stride; - this.count = array !== undefined ? array.length / stride : 0; - this.usage = StaticDrawUsage; - this.updateRange = { - offset: 0, - count: -1 - }; - this.version = 0; - this.uuid = generateUUID(); - } + case LessDepth: - onUploadCallback() {} + gl.depthFunc( gl.LESS ); + break; - set needsUpdate(value) { - if (value === true) this.version++; - } + case LessEqualDepth: - setUsage(value) { - this.usage = value; - return this; - } + gl.depthFunc( gl.LEQUAL ); + break; - copy(source) { - this.array = new source.array.constructor(source.array); - this.count = source.count; - this.stride = source.stride; - this.usage = source.usage; - return this; - } + case EqualDepth: - copyAt(index1, attribute, index2) { - index1 *= this.stride; - index2 *= attribute.stride; + gl.depthFunc( gl.EQUAL ); + break; - for (let i = 0, l = this.stride; i < l; i++) { - this.array[index1 + i] = attribute.array[index2 + i]; - } + case GreaterEqualDepth: - return this; - } + gl.depthFunc( gl.GEQUAL ); + break; - set(value, offset = 0) { - this.array.set(value, offset); - return this; - } + case GreaterDepth: - clone(data) { - if (data.arrayBuffers === undefined) { - data.arrayBuffers = {}; - } + gl.depthFunc( gl.GREATER ); + break; - if (this.array.buffer._uuid === undefined) { - this.array.buffer._uuid = generateUUID(); - } + case NotEqualDepth: - if (data.arrayBuffers[this.array.buffer._uuid] === undefined) { - data.arrayBuffers[this.array.buffer._uuid] = this.array.slice(0).buffer; - } + gl.depthFunc( gl.NOTEQUAL ); + break; - 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; - } + default: - onUpload(callback) { - this.onUploadCallback = callback; - return this; - } + gl.depthFunc( gl.LEQUAL ); - toJSON(data) { - if (data.arrayBuffers === undefined) { - data.arrayBuffers = {}; - } // generate UUID for array buffer if necessary + } + currentDepthFunc = depthFunc; - 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.prototype.slice.call(new Uint32Array(this.array.buffer)); - } // + }, + setLocked: function ( lock ) { - return { - uuid: this.uuid, - buffer: this.array.buffer._uuid, - type: this.array.constructor.name, - stride: this.stride - }; - } + locked = lock; -} + }, -const _vector$6 = /*@__PURE__*/new Vector3(); + setClear: function ( depth ) { -class InterleavedBufferAttribute { - constructor(interleavedBuffer, itemSize, offset, normalized = false) { - this.isInterleavedBufferAttribute = true; - this.name = ''; - this.data = interleavedBuffer; - this.itemSize = itemSize; - this.offset = offset; - this.normalized = normalized === true; - } + if ( currentDepthClear !== depth ) { - get count() { - return this.data.count; - } + gl.clearDepth( depth ); + currentDepthClear = depth; - 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); + reset: function () { - _vector$6.applyMatrix4(m); + locked = false; - this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); - } + currentDepthMask = null; + currentDepthFunc = null; + currentDepthClear = null; + + } + + }; - return this; } - applyNormalMatrix(m) { - for (let i = 0, l = this.count; i < l; i++) { - _vector$6.fromBufferAttribute(this, i); + function StencilBuffer() { - _vector$6.applyNormalMatrix(m); + let locked = false; - this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); - } + let currentStencilMask = null; + let currentStencilFunc = null; + let currentStencilRef = null; + let currentStencilFuncMask = null; + let currentStencilFail = null; + let currentStencilZFail = null; + let currentStencilZPass = null; + let currentStencilClear = null; - return this; - } + return { - transformDirection(m) { - for (let i = 0, l = this.count; i < l; i++) { - _vector$6.fromBufferAttribute(this, i); + setTest: function ( stencilTest ) { - _vector$6.transformDirection(m); + if ( ! locked ) { - this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); - } + if ( stencilTest ) { - return this; - } + enable( gl.STENCIL_TEST ); - setX(index, x) { - this.data.array[index * this.data.stride + this.offset] = x; - return this; - } + } else { - setY(index, y) { - this.data.array[index * this.data.stride + this.offset + 1] = y; - return this; - } + disable( gl.STENCIL_TEST ); - setZ(index, z) { - this.data.array[index * this.data.stride + this.offset + 2] = z; - return this; - } + } - setW(index, w) { - 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]; - } + }, - getY(index) { - return this.data.array[index * this.data.stride + this.offset + 1]; - } + setMask: function ( stencilMask ) { - getZ(index) { - return this.data.array[index * this.data.stride + this.offset + 2]; - } + if ( currentStencilMask !== stencilMask && ! locked ) { - getW(index) { - return this.data.array[index * this.data.stride + this.offset + 3]; - } + gl.stencilMask( stencilMask ); + currentStencilMask = stencilMask; - setXY(index, x, y) { - index = index * this.data.stride + this.offset; - this.data.array[index + 0] = x; - this.data.array[index + 1] = y; - return this; - } + } - setXYZ(index, x, y, z) { - index = index * this.data.stride + this.offset; - this.data.array[index + 0] = x; - this.data.array[index + 1] = y; - this.data.array[index + 2] = z; - return this; - } + }, - setXYZW(index, x, y, z, w) { - index = index * this.data.stride + this.offset; - this.data.array[index + 0] = x; - this.data.array[index + 1] = y; - this.data.array[index + 2] = z; - this.data.array[index + 3] = w; - return this; - } + setFunc: function ( stencilFunc, stencilRef, stencilMask ) { - clone(data) { - if (data === undefined) { - console.log('THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave buffer data.'); - const array = []; + if ( currentStencilFunc !== stencilFunc || + currentStencilRef !== stencilRef || + currentStencilFuncMask !== stencilMask ) { - for (let i = 0; i < this.count; i++) { - const index = i * this.data.stride + this.offset; + gl.stencilFunc( stencilFunc, stencilRef, stencilMask ); + + currentStencilFunc = stencilFunc; + currentStencilRef = stencilRef; + currentStencilFuncMask = stencilMask; - 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); - } + setOp: function ( stencilFail, stencilZFail, stencilZPass ) { - return new InterleavedBufferAttribute(data.interleavedBuffers[this.data.uuid], this.itemSize, this.offset, this.normalized); - } - } + if ( currentStencilFail !== stencilFail || + currentStencilZFail !== stencilZFail || + currentStencilZPass !== stencilZPass ) { - toJSON(data) { - if (data === undefined) { - console.log('THREE.InterleavedBufferAttribute.toJSON(): Serializing an interlaved buffer attribute will deinterleave buffer data.'); - const array = []; + gl.stencilOp( stencilFail, stencilZFail, stencilZPass ); - for (let i = 0; i < this.count; i++) { - const index = i * this.data.stride + this.offset; + currentStencilFail = stencilFail; + currentStencilZFail = stencilZFail; + currentStencilZPass = stencilZPass; - 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 + }, - return { - itemSize: this.itemSize, - type: this.array.constructor.name, - array: array, - normalized: this.normalized - }; - } else { - // save as true interlaved attribtue - if (data.interleavedBuffers === undefined) { - data.interleavedBuffers = {}; - } + setLocked: function ( lock ) { - if (data.interleavedBuffers[this.data.uuid] === undefined) { - data.interleavedBuffers[this.data.uuid] = this.data.toJSON(data); - } + locked = lock; - return { - isInterleavedBufferAttribute: true, - itemSize: this.itemSize, - data: this.data.uuid, - offset: this.offset, - normalized: this.normalized - }; - } - } + }, -} + setClear: function ( stencil ) { -class SpriteMaterial extends Material { - constructor(parameters) { - super(); - this.isSpriteMaterial = true; - this.type = 'SpriteMaterial'; - this.color = new Color(0xffffff); - this.map = null; - this.alphaMap = null; - this.rotation = 0; - this.sizeAttenuation = true; - this.transparent = true; - this.fog = true; - this.setValues(parameters); - } + if ( currentStencilClear !== stencil ) { - copy(source) { - super.copy(source); - this.color.copy(source.color); - this.map = source.map; - this.alphaMap = source.alphaMap; - this.rotation = source.rotation; - this.sizeAttenuation = source.sizeAttenuation; - this.fog = source.fog; - return this; - } + gl.clearStencil( stencil ); + currentStencilClear = stencil; -} + } -let _geometry; + }, -const _intersectPoint = /*@__PURE__*/new Vector3(); + reset: function () { -const _worldScale = /*@__PURE__*/new Vector3(); + locked = false; -const _mvPosition = /*@__PURE__*/new Vector3(); + currentStencilMask = null; + currentStencilFunc = null; + currentStencilRef = null; + currentStencilFuncMask = null; + currentStencilFail = null; + currentStencilZFail = null; + currentStencilZPass = null; + currentStencilClear = null; -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 colorBuffer = new ColorBuffer(); + const depthBuffer = new DepthBuffer(); + const stencilBuffer = new StencilBuffer(); -const _vC = /*@__PURE__*/new Vector3(); + const uboBindings = new WeakMap(); + const uboProgramMap = new WeakMap(); -const _uvA = /*@__PURE__*/new Vector2(); + let enabledCapabilities = {}; -const _uvB = /*@__PURE__*/new Vector2(); + let currentBoundFramebuffers = {}; + let currentDrawbuffers = new WeakMap(); + let defaultDrawbuffers = []; -const _uvC = /*@__PURE__*/new Vector2(); + let currentProgram = null; -class Sprite extends Object3D { - constructor(material) { - super(); - this.isSprite = true; - this.type = 'Sprite'; + let currentBlendingEnabled = false; + let currentBlending = null; + let currentBlendEquation = null; + let currentBlendSrc = null; + let currentBlendDst = null; + let currentBlendEquationAlpha = null; + let currentBlendSrcAlpha = null; + let currentBlendDstAlpha = null; + let currentPremultipledAlpha = false; - 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); + let currentFlipSided = null; + let currentCullFace = null; - _geometry.setIndex([0, 1, 2, 0, 2, 3]); + let currentLineWidth = null; - _geometry.setAttribute('position', new InterleavedBufferAttribute(interleavedBuffer, 3, 0, false)); + let currentPolygonOffsetFactor = null; + let currentPolygonOffsetUnits = null; - _geometry.setAttribute('uv', new InterleavedBufferAttribute(interleavedBuffer, 2, 3, false)); - } + const maxTextures = gl.getParameter( gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS ); + + 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 ); + + } else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) { + + version = parseFloat( /^OpenGL ES (\d)/.exec( glVersion )[ 1 ] ); + lineWidthAvailable = ( version >= 2.0 ); - 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.'); - } + let currentTextureSlot = null; + let currentBoundTextures = {}; - _worldScale.setFromMatrixScale(this.matrixWorld); + const scissorParam = gl.getParameter( gl.SCISSOR_BOX ); + const viewportParam = gl.getParameter( gl.VIEWPORT ); - _viewWorldMatrix.copy(raycaster.camera.matrixWorld); + const currentScissor = new Vector4().fromArray( scissorParam ); + const currentViewport = new Vector4().fromArray( viewportParam ); - this.modelViewMatrix.multiplyMatrices(raycaster.camera.matrixWorldInverse, this.matrixWorld); + function createTexture( type, target, count ) { - _mvPosition.setFromMatrixPosition(this.modelViewMatrix); + const data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4. + const texture = gl.createTexture(); - if (raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false) { - _worldScale.multiplyScalar(-_mvPosition.z); - } + gl.bindTexture( type, texture ); + gl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST ); + gl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST ); - const rotation = this.material.rotation; - let sin, cos; + for ( let i = 0; i < count; i ++ ) { + + gl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data ); - 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); + return texture; - _uvA.set(0, 0); + } - _uvB.set(1, 0); + 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 ); - _uvC.set(1, 1); // check first triangle + // init + colorBuffer.setClear( 0, 0, 0, 1 ); + depthBuffer.setClear( 1 ); + stencilBuffer.setClear( 0 ); - let intersect = raycaster.ray.intersectTriangle(_vA, _vB, _vC, false, _intersectPoint); + enable( gl.DEPTH_TEST ); + depthBuffer.setFunc( LessEqualDepth ); - if (intersect === null) { - // check second triangle - transformVertex(_vB.set(-0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos); + setFlipSided( false ); + setCullFace( CullFaceBack ); + enable( gl.CULL_FACE ); - _uvB.set(0, 1); + setBlending( NoBlending ); - intersect = raycaster.ray.intersectTriangle(_vA, _vC, _vB, false, _intersectPoint); + // + + function enable( id ) { + + if ( enabledCapabilities[ id ] !== true ) { + + gl.enable( id ); + enabledCapabilities[ id ] = true; - if (intersect === null) { - return; - } } - const distance = raycaster.ray.origin.distanceTo(_intersectPoint); - if (distance < raycaster.near || distance > raycaster.far) return; - intersects.push({ - distance: distance, - point: _intersectPoint.clone(), - uv: Triangle.getUV(_intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2()), - face: null, - 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 disable( id ) { -} + if ( enabledCapabilities[ id ] !== false ) { -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 + gl.disable( id ); + enabledCapabilities[ id ] = false; + } - 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 + function bindFramebuffer( target, framebuffer ) { - vertexPosition.applyMatrix4(_viewWorldMatrix); -} + if ( currentBoundFramebuffers[ target ] !== framebuffer ) { -const _v1$2 = /*@__PURE__*/new Vector3(); + gl.bindFramebuffer( target, framebuffer ); -const _v2$1 = /*@__PURE__*/new Vector3(); + currentBoundFramebuffers[ target ] = framebuffer; -class LOD extends Object3D { - constructor() { - super(); - this._currentLevel = 0; - this.type = 'LOD'; - Object.defineProperties(this, { - levels: { - enumerable: true, - value: [] - }, - isLOD: { - value: true - } - }); - this.autoUpdate = true; - } + if ( isWebGL2 ) { - copy(source) { - super.copy(source, false); - const levels = source.levels; + // gl.DRAW_FRAMEBUFFER is equivalent to gl.FRAMEBUFFER - for (let i = 0, l = levels.length; i < l; i++) { - const level = levels[i]; - this.addLevel(level.object.clone(), level.distance); - } + if ( target === gl.DRAW_FRAMEBUFFER ) { - this.autoUpdate = source.autoUpdate; - return this; - } + currentBoundFramebuffers[ gl.FRAMEBUFFER ] = framebuffer; - addLevel(object, distance = 0) { - distance = Math.abs(distance); - const levels = this.levels; - let l; + } + + if ( target === gl.FRAMEBUFFER ) { + + currentBoundFramebuffers[ gl.DRAW_FRAMEBUFFER ] = framebuffer; + + } - for (l = 0; l < levels.length; l++) { - if (distance < levels[l].distance) { - break; } + + return true; + } - levels.splice(l, 0, { - distance: distance, - object: object - }); - this.add(object); - return this; - } + return false; - getCurrentLevel() { - return this._currentLevel; } - getObjectForDistance(distance) { - const levels = this.levels; + function drawBuffers( renderTarget, framebuffer ) { - if (levels.length > 0) { - let i, l; + let drawBuffers = defaultDrawbuffers; + + let needsUpdate = false; + + if ( renderTarget ) { + + drawBuffers = currentDrawbuffers.get( framebuffer ); + + if ( drawBuffers === undefined ) { + + drawBuffers = []; + currentDrawbuffers.set( framebuffer, drawBuffers ); - for (i = 1, l = levels.length; i < l; i++) { - if (distance < levels[i].distance) { - break; - } } - return levels[i - 1].object; - } + if ( renderTarget.isWebGLMultipleRenderTargets ) { - return null; - } + const textures = renderTarget.texture; - raycast(raycaster, intersects) { - const levels = this.levels; + if ( drawBuffers.length !== textures.length || drawBuffers[ 0 ] !== gl.COLOR_ATTACHMENT0 ) { - if (levels.length > 0) { - _v1$2.setFromMatrixPosition(this.matrixWorld); + for ( let i = 0, il = textures.length; i < il; i ++ ) { - const distance = raycaster.ray.origin.distanceTo(_v1$2); - this.getObjectForDistance(distance).raycast(raycaster, intersects); - } - } + drawBuffers[ i ] = gl.COLOR_ATTACHMENT0 + i; - update(camera) { - const levels = this.levels; + } - if (levels.length > 1) { - _v1$2.setFromMatrixPosition(camera.matrixWorld); + drawBuffers.length = textures.length; - _v2$1.setFromMatrixPosition(this.matrixWorld); + needsUpdate = true; - const distance = _v1$2.distanceTo(_v2$1) / camera.zoom; - levels[0].object.visible = true; - let i, l; + } + + } else { + + if ( drawBuffers[ 0 ] !== gl.COLOR_ATTACHMENT0 ) { + + drawBuffers[ 0 ] = gl.COLOR_ATTACHMENT0; + + needsUpdate = true; - for (i = 1, l = levels.length; i < l; i++) { - if (distance >= levels[i].distance) { - levels[i - 1].object.visible = false; - levels[i].object.visible = true; - } else { - break; } + } - this._currentLevel = i - 1; + } else { + + if ( drawBuffers[ 0 ] !== gl.BACK ) { + + drawBuffers[ 0 ] = gl.BACK; + + needsUpdate = true; - 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; + if ( needsUpdate ) { + + if ( capabilities.isWebGL2 ) { + + gl.drawBuffers( drawBuffers ); + + } else { + + extensions.get( 'WEBGL_draw_buffers' ).drawBuffersWEBGL( drawBuffers ); + + } - 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 - }); } - return data; + } -} + function useProgram( program ) { -const _basePosition = /*@__PURE__*/new Vector3(); + if ( currentProgram !== program ) { -const _skinIndex = /*@__PURE__*/new Vector4(); + gl.useProgram( program ); -const _skinWeight = /*@__PURE__*/new Vector4(); + currentProgram = program; -const _vector$5 = /*@__PURE__*/new Vector3(); + return true; -const _matrix = /*@__PURE__*/new Matrix4(); + } -class SkinnedMesh extends Mesh { - constructor(geometry, material) { - super(geometry, material); - this.isSkinnedMesh = true; - this.type = 'SkinnedMesh'; - this.bindMode = 'attached'; - this.bindMatrix = new Matrix4(); - this.bindMatrixInverse = new Matrix4(); - } + return false; - copy(source, recursive) { - super.copy(source, recursive); - this.bindMode = source.bindMode; - this.bindMatrix.copy(source.bindMatrix); - this.bindMatrixInverse.copy(source.bindMatrixInverse); - this.skeleton = source.skeleton; - return this; } - bind(skeleton, bindMatrix) { - this.skeleton = skeleton; + 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; - 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(); - } + const factorToGL = { + [ ZeroFactor ]: gl.ZERO, + [ OneFactor ]: gl.ONE, + [ SrcColorFactor ]: gl.SRC_COLOR, + [ SrcAlphaFactor ]: gl.SRC_ALPHA, + [ SrcAlphaSaturateFactor ]: gl.SRC_ALPHA_SATURATE, + [ DstColorFactor ]: gl.DST_COLOR, + [ DstAlphaFactor ]: gl.DST_ALPHA, + [ OneMinusSrcColorFactor ]: gl.ONE_MINUS_SRC_COLOR, + [ OneMinusSrcAlphaFactor ]: gl.ONE_MINUS_SRC_ALPHA, + [ OneMinusDstColorFactor ]: gl.ONE_MINUS_DST_COLOR, + [ OneMinusDstAlphaFactor ]: gl.ONE_MINUS_DST_ALPHA + }; - normalizeSkinWeights() { - const vector = new Vector4(); - const skinWeight = this.geometry.attributes.skinWeight; + function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) { - for (let i = 0, l = skinWeight.count; i < l; i++) { - vector.fromBufferAttribute(skinWeight, i); - const scale = 1.0 / vector.manhattanLength(); + if ( blending === NoBlending ) { + + if ( currentBlendingEnabled === true ) { + + disable( gl.BLEND ); + currentBlendingEnabled = false; - if (scale !== Infinity) { - vector.multiplyScalar(scale); - } else { - vector.set(1, 0, 0, 0); // do something reasonable } - skinWeight.setXYZW(i, vector.x, vector.y, vector.z, vector.w); + return; + } - } - updateMatrixWorld(force) { - super.updateMatrixWorld(force); + if ( currentBlendingEnabled === false ) { + + enable( gl.BLEND ); + currentBlendingEnabled = true; - if (this.bindMode === 'attached') { - this.bindMatrixInverse.copy(this.matrixWorld).invert(); - } else if (this.bindMode === 'detached') { - this.bindMatrixInverse.copy(this.bindMatrix).invert(); - } else { - console.warn('THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode); } - } - boneTransform(index, target) { - const skeleton = this.skeleton; - const geometry = this.geometry; + if ( blending !== CustomBlending ) { - _skinIndex.fromBufferAttribute(geometry.attributes.skinIndex, index); + if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) { - _skinWeight.fromBufferAttribute(geometry.attributes.skinWeight, index); + if ( currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation ) { - _basePosition.copy(target).applyMatrix4(this.bindMatrix); + gl.blendEquation( gl.FUNC_ADD ); - target.set(0, 0, 0); + currentBlendEquation = AddEquation; + currentBlendEquationAlpha = AddEquation; - for (let i = 0; i < 4; i++) { - const weight = _skinWeight.getComponent(i); + } - if (weight !== 0) { - const boneIndex = _skinIndex.getComponent(i); + if ( premultipliedAlpha ) { - _matrix.multiplyMatrices(skeleton.bones[boneIndex].matrixWorld, skeleton.boneInverses[boneIndex]); + switch ( blending ) { - target.addScaledVector(_vector$5.copy(_basePosition).applyMatrix4(_matrix), weight); - } - } + case NormalBlending: + gl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); + break; - return target.applyMatrix4(this.bindMatrixInverse); - } + 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; -class Bone extends Object3D { - constructor() { - super(); - this.isBone = true; - this.type = 'Bone'; - } + case MultiplyBlending: + gl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA ); + break; -} + default: + console.error( 'THREE.WebGLState: Invalid blending: ', blending ); + break; -class DataTexture extends Texture { - constructor(data = null, width = 1, height = 1, format, type, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, encoding) { - super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); - this.isDataTexture = true; - this.image = { - data: data, - width: width, - height: height - }; - this.generateMipmaps = false; - this.flipY = false; - this.unpackAlignment = 1; - } + } -} + } else { -const _offsetMatrix = /*@__PURE__*/new Matrix4(); + switch ( blending ) { -const _identityMatrix = /*@__PURE__*/new Matrix4(); + case NormalBlending: + gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); + break; -class Skeleton { - constructor(bones = [], boneInverses = []) { - this.uuid = generateUUID(); - this.bones = bones.slice(0); - this.boneInverses = boneInverses; - this.boneMatrices = null; - this.boneTexture = null; - this.boneTextureSize = 0; - this.frame = -1; - this.init(); - } + case AdditiveBlending: + gl.blendFunc( gl.SRC_ALPHA, gl.ONE ); + break; - init() { - const bones = this.bones; - const boneInverses = this.boneInverses; - this.boneMatrices = new Float32Array(bones.length * 16); // calculate inverse bone matrices if necessary + case SubtractiveBlending: + gl.blendFuncSeparate( gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE ); + break; - 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 = []; + case MultiplyBlending: + gl.blendFunc( gl.ZERO, gl.SRC_COLOR ); + break; + + default: + console.error( 'THREE.WebGLState: Invalid blending: ', blending ); + break; + + } - for (let i = 0, il = this.bones.length; i < il; i++) { - this.boneInverses.push(new Matrix4()); } - } - } - } - calculateInverses() { - this.boneInverses.length = 0; + currentBlendSrc = null; + currentBlendDst = null; + currentBlendSrcAlpha = null; + currentBlendDstAlpha = null; - for (let i = 0, il = this.bones.length; i < il; i++) { - const inverse = new Matrix4(); + currentBlending = blending; + currentPremultipledAlpha = premultipliedAlpha; - if (this.bones[i]) { - inverse.copy(this.bones[i].matrixWorld).invert(); } - this.boneInverses.push(inverse); + return; + } - } - pose() { - // recover the bind-time world matrices - for (let i = 0, il = this.bones.length; i < il; i++) { - const bone = this.bones[i]; + // custom blending - if (bone) { - bone.matrixWorld.copy(this.boneInverses[i]).invert(); - } - } // compute the local matrices, positions, rotations and scales + blendEquationAlpha = blendEquationAlpha || blendEquation; + blendSrcAlpha = blendSrcAlpha || blendSrc; + blendDstAlpha = blendDstAlpha || blendDst; + if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) { - for (let i = 0, il = this.bones.length; i < il; i++) { - const bone = this.bones[i]; + gl.blendEquationSeparate( equationToGL[ blendEquation ], equationToGL[ blendEquationAlpha ] ); - if (bone) { - if (bone.parent && bone.parent.isBone) { - bone.matrix.copy(bone.parent.matrixWorld).invert(); - bone.matrix.multiply(bone.matrixWorld); - } else { - bone.matrix.copy(bone.matrixWorld); - } + currentBlendEquation = blendEquation; + currentBlendEquationAlpha = blendEquationAlpha; - 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 + if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) { - 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; + gl.blendFuncSeparate( factorToGL[ blendSrc ], factorToGL[ blendDst ], factorToGL[ blendSrcAlpha ], factorToGL[ blendDstAlpha ] ); - _offsetMatrix.multiplyMatrices(matrix, boneInverses[i]); + currentBlendSrc = blendSrc; + currentBlendDst = blendDst; + currentBlendSrcAlpha = blendSrcAlpha; + currentBlendDstAlpha = blendDstAlpha; - _offsetMatrix.toArray(boneMatrices, i * 16); } - if (boneTexture !== null) { - boneTexture.needsUpdate = true; - } - } + currentBlending = blending; + currentPremultipledAlpha = false; - clone() { - return new Skeleton(this.bones, this.boneInverses); } - computeBoneTexture() { - // layout (1 matrix = 4 pixels) - // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4) - // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8) - // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16) - // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32) - // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64) - let size = Math.sqrt(this.bones.length * 4); // 4 pixels needed for 1 matrix + function setMaterial( material, frontFaceCW ) { - size = ceilPowerOfTwo(size); - size = Math.max(size, 4); - const boneMatrices = new Float32Array(size * size * 4); // 4 floats per RGBA pixel + material.side === DoubleSide + ? disable( gl.CULL_FACE ) + : enable( gl.CULL_FACE ); - boneMatrices.set(this.boneMatrices); // copy current values + let flipSided = ( material.side === BackSide ); + if ( frontFaceCW ) flipSided = ! flipSided; - const boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType); - boneTexture.needsUpdate = true; - this.boneMatrices = boneMatrices; - this.boneTexture = boneTexture; - this.boneTextureSize = size; - return this; - } + setFlipSided( flipSided ); - getBoneByName(name) { - for (let i = 0, il = this.bones.length; i < il; i++) { - const bone = this.bones[i]; + ( material.blending === NormalBlending && material.transparent === false ) + ? setBlending( NoBlending ) + : setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha ); - if (bone.name === name) { - return bone; - } - } + depthBuffer.setFunc( material.depthFunc ); + depthBuffer.setTest( material.depthTest ); + depthBuffer.setMask( material.depthWrite ); + colorBuffer.setMask( material.colorWrite ); - return undefined; - } + 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 ); - dispose() { - if (this.boneTexture !== null) { - this.boneTexture.dispose(); - this.boneTexture = null; } - } - fromJSON(json, bones) { - this.uuid = json.uuid; + setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); - for (let i = 0, l = json.bones.length; i < l; i++) { - const uuid = json.bones[i]; - let bone = bones[uuid]; + material.alphaToCoverage === true + ? enable( gl.SAMPLE_ALPHA_TO_COVERAGE ) + : disable( gl.SAMPLE_ALPHA_TO_COVERAGE ); - 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: { - version: 4.5, - type: 'Skeleton', - generator: 'Skeleton.toJSON' - }, - bones: [], - boneInverses: [] - }; - 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()); - } + function setFlipSided( flipSided ) { - return data; - } + if ( currentFlipSided !== flipSided ) { -} + if ( flipSided ) { -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.'); - } + gl.frontFace( gl.CW ); - super(array, itemSize, normalized); - this.isInstancedBufferAttribute = true; - this.meshPerAttribute = meshPerAttribute; - } + } else { - copy(source) { - super.copy(source); - this.meshPerAttribute = source.meshPerAttribute; - return this; - } + gl.frontFace( gl.CCW ); - toJSON() { - const data = super.toJSON(); - data.meshPerAttribute = this.meshPerAttribute; - data.isInstancedBufferAttribute = true; - return data; - } + } -} + currentFlipSided = flipSided; -const _instanceLocalMatrix = /*@__PURE__*/new Matrix4(); + } -const _instanceWorldMatrix = /*@__PURE__*/new Matrix4(); + } -const _instanceIntersects = []; + function setCullFace( cullFace ) { -const _mesh = /*@__PURE__*/new Mesh(); + if ( cullFace !== CullFaceNone ) { -class InstancedMesh extends Mesh { - constructor(geometry, material, count) { - super(geometry, material); - this.isInstancedMesh = true; - this.instanceMatrix = new InstancedBufferAttribute(new Float32Array(count * 16), 16); - this.instanceColor = null; - this.count = count; - this.frustumCulled = false; - } + enable( gl.CULL_FACE ); - copy(source, recursive) { - super.copy(source, recursive); - this.instanceMatrix.copy(source.instanceMatrix); - if (source.instanceColor !== null) this.instanceColor = source.instanceColor.clone(); - this.count = source.count; - return this; - } + if ( cullFace !== currentCullFace ) { - getColorAt(index, color) { - color.fromArray(this.instanceColor.array, index * 3); - } + if ( cullFace === CullFaceBack ) { - getMatrixAt(index, matrix) { - matrix.fromArray(this.instanceMatrix.array, index * 16); - } + gl.cullFace( gl.BACK ); - raycast(raycaster, intersects) { - const matrixWorld = this.matrixWorld; - const raycastTimes = this.count; - _mesh.geometry = this.geometry; - _mesh.material = this.material; - if (_mesh.material === undefined) return; + } else if ( cullFace === CullFaceFront ) { - for (let instanceId = 0; instanceId < raycastTimes; instanceId++) { - // calculate the world matrix for each instance - this.getMatrixAt(instanceId, _instanceLocalMatrix); + gl.cullFace( gl.FRONT ); - _instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix); // the mesh represents this single instance + } else { + gl.cullFace( gl.FRONT_AND_BACK ); - _mesh.matrixWorld = _instanceWorldMatrix; + } - _mesh.raycast(raycaster, _instanceIntersects); // process the result of raycast + } + } else { - for (let i = 0, l = _instanceIntersects.length; i < l; i++) { - const intersect = _instanceIntersects[i]; - intersect.instanceId = instanceId; - intersect.object = this; - intersects.push(intersect); - } + disable( gl.CULL_FACE ); - _instanceIntersects.length = 0; } - } - setColorAt(index, color) { - if (this.instanceColor === null) { - this.instanceColor = new InstancedBufferAttribute(new Float32Array(this.instanceMatrix.count * 3), 3); - } + currentCullFace = cullFace; - color.toArray(this.instanceColor.array, index * 3); } - setMatrixAt(index, matrix) { - matrix.toArray(this.instanceMatrix.array, index * 16); - } + function setLineWidth( width ) { - updateMorphTargets() {} + if ( width !== currentLineWidth ) { - dispose() { - this.dispatchEvent({ - type: 'dispose' - }); - } + if ( lineWidthAvailable ) gl.lineWidth( width ); -} + currentLineWidth = width; -class LineBasicMaterial extends Material { - constructor(parameters) { - super(); - this.isLineBasicMaterial = true; - this.type = 'LineBasicMaterial'; - this.color = new Color(0xffffff); - this.linewidth = 1; - this.linecap = 'round'; - this.linejoin = 'round'; - this.fog = true; - this.setValues(parameters); - } + } - copy(source) { - super.copy(source); - this.color.copy(source.color); - this.linewidth = source.linewidth; - this.linecap = source.linecap; - this.linejoin = source.linejoin; - this.fog = source.fog; - return this; } -} + function setPolygonOffset( polygonOffset, factor, units ) { -const _start$1 = /*@__PURE__*/new Vector3(); + if ( polygonOffset ) { -const _end$1 = /*@__PURE__*/new Vector3(); + enable( gl.POLYGON_OFFSET_FILL ); -const _inverseMatrix$1 = /*@__PURE__*/new Matrix4(); + if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) { -const _ray$1 = /*@__PURE__*/new Ray(); + gl.polygonOffset( factor, units ); -const _sphere$1 = /*@__PURE__*/new Sphere(); + currentPolygonOffsetFactor = factor; + currentPolygonOffsetUnits = units; -class Line extends Object3D { - constructor(geometry = new BufferGeometry(), material = new LineBasicMaterial()) { - super(); - this.isLine = true; - this.type = 'Line'; - this.geometry = geometry; - this.material = material; - this.updateMorphTargets(); - } + } - copy(source, recursive) { - super.copy(source, recursive); - this.material = source.material; - this.geometry = source.geometry; - return this; - } + } else { - computeLineDistances() { - const geometry = this.geometry; // we assume non-indexed geometry + disable( gl.POLYGON_OFFSET_FILL ); - 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); + function setScissorTest( scissorTest ) { - lineDistances[i] = lineDistances[i - 1]; - lineDistances[i] += _start$1.distanceTo(_end$1); - } + if ( scissorTest ) { + + enable( gl.SCISSOR_TEST ); - geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1)); } else { - console.warn('THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.'); + + disable( gl.SCISSOR_TEST ); + } - 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 + // texture - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + function activeTexture( webglSlot ) { - _sphere$1.copy(geometry.boundingSphere); + if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1; - _sphere$1.applyMatrix4(matrixWorld); + if ( currentTextureSlot !== webglSlot ) { - _sphere$1.radius += threshold; - if (raycaster.ray.intersectsSphere(_sphere$1) === false) return; // + gl.activeTexture( webglSlot ); + currentTextureSlot = webglSlot; - _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(); - const vEnd = new Vector3(); - const interSegment = new Vector3(); - const interRay = new Vector3(); - const step = this.isLineSegments ? 2 : 1; - const index = geometry.index; - const attributes = geometry.attributes; - const positionAttribute = attributes.position; + function bindTexture( webglType, webglTexture, webglSlot ) { - if (index !== null) { - const start = Math.max(0, drawRange.start); - const end = Math.min(index.count, drawRange.start + drawRange.count); + if ( webglSlot === undefined ) { - 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); + if ( currentTextureSlot === null ) { - const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment); + webglSlot = gl.TEXTURE0 + maxTextures - 1; - if (distSq > localThresholdSq) continue; - interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation + } else { + + webglSlot = currentTextureSlot; - const distance = raycaster.ray.origin.distanceTo(interRay); - if (distance < raycaster.near || distance > raycaster.far) continue; - intersects.push({ - distance: distance, - // What do we want? intersection point on the ray or on the segment?? - // point: raycaster.ray.at( distance ), - point: interSegment.clone().applyMatrix4(this.matrixWorld), - index: i, - face: null, - faceIndex: null, - object: this - }); } - } else { - 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); + let boundTexture = currentBoundTextures[ webglSlot ]; - if (distSq > localThresholdSq) continue; - interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation + if ( boundTexture === undefined ) { + + boundTexture = { type: undefined, texture: undefined }; + currentBoundTextures[ webglSlot ] = boundTexture; - const distance = raycaster.ray.origin.distanceTo(interRay); - if (distance < raycaster.near || distance > raycaster.far) continue; - intersects.push({ - distance: distance, - // What do we want? intersection point on the ray or on the segment?? - // point: raycaster.ray.at( distance ), - point: interSegment.clone().applyMatrix4(this.matrixWorld), - index: i, - face: null, - faceIndex: null, - object: this - }); - } } - } - updateMorphTargets() { - const geometry = this.geometry; - const morphAttributes = geometry.morphAttributes; - const keys = Object.keys(morphAttributes); + if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) { - if (keys.length > 0) { - const morphAttribute = morphAttributes[keys[0]]; + if ( currentTextureSlot !== webglSlot ) { - if (morphAttribute !== undefined) { - this.morphTargetInfluences = []; - this.morphTargetDictionary = {}; + gl.activeTexture( webglSlot ); + currentTextureSlot = webglSlot; - for (let m = 0, ml = morphAttribute.length; m < ml; m++) { - const name = morphAttribute[m].name || String(m); - this.morphTargetInfluences.push(0); - this.morphTargetDictionary[name] = m; - } } - } - } -} + gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] ); -const _start = /*@__PURE__*/new Vector3(); + boundTexture.type = webglType; + boundTexture.texture = webglTexture; -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 + function unbindTexture() { - if (geometry.index === null) { - const positionAttribute = geometry.attributes.position; - const lineDistances = []; + const boundTexture = currentBoundTextures[ currentTextureSlot ]; - for (let i = 0, l = positionAttribute.count; i < l; i += 2) { - _start.fromBufferAttribute(positionAttribute, i); + if ( boundTexture !== undefined && boundTexture.type !== undefined ) { - _end.fromBufferAttribute(positionAttribute, i + 1); + gl.bindTexture( boundTexture.type, null ); - lineDistances[i] = i === 0 ? 0 : lineDistances[i - 1]; - lineDistances[i + 1] = lineDistances[i] + _start.distanceTo(_end); - } + boundTexture.type = undefined; + boundTexture.texture = undefined; - geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1)); - } else { - console.warn('THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.'); } - return this; } -} + function compressedTexImage2D() { -class LineLoop extends Line { - constructor(geometry, material) { - super(geometry, material); - this.isLineLoop = true; - this.type = 'LineLoop'; - } + try { -} + gl.compressedTexImage2D.apply( gl, arguments ); -class PointsMaterial extends Material { - constructor(parameters) { - super(); - this.isPointsMaterial = true; - this.type = 'PointsMaterial'; - this.color = new Color(0xffffff); - this.map = null; - this.alphaMap = null; - this.size = 1; - this.sizeAttenuation = true; - this.fog = true; - this.setValues(parameters); - } + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } - copy(source) { - super.copy(source); - this.color.copy(source.color); - this.map = source.map; - this.alphaMap = source.alphaMap; - this.size = source.size; - this.sizeAttenuation = source.sizeAttenuation; - this.fog = source.fog; - return this; } -} + function compressedTexImage3D() { -const _inverseMatrix = /*@__PURE__*/new Matrix4(); + try { -const _ray = /*@__PURE__*/new Ray(); + gl.compressedTexImage3D.apply( gl, arguments ); -const _sphere = /*@__PURE__*/new Sphere(); + } catch ( error ) { -const _position$2 = /*@__PURE__*/new Vector3(); + console.error( 'THREE.WebGLState:', error ); -class Points extends Object3D { - constructor(geometry = new BufferGeometry(), material = new PointsMaterial()) { - super(); - this.isPoints = true; - this.type = 'Points'; - this.geometry = geometry; - 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 - - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + function texSubImage2D() { - _sphere.copy(geometry.boundingSphere); + try { - _sphere.applyMatrix4(matrixWorld); + gl.texSubImage2D.apply( gl, arguments ); - _sphere.radius += threshold; - if (raycaster.ray.intersectsSphere(_sphere) === false) return; // + } catch ( error ) { - _inverseMatrix.copy(matrixWorld).invert(); + console.error( 'THREE.WebGLState:', error ); - _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); + function texSubImage3D() { - for (let i = start, il = end; i < il; i++) { - const a = index.getX(i); + try { - _position$2.fromBufferAttribute(positionAttribute, a); + gl.texSubImage3D.apply( gl, arguments ); - 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); + } catch ( error ) { - for (let i = start, l = end; i < l; i++) { - _position$2.fromBufferAttribute(positionAttribute, i); + console.error( 'THREE.WebGLState:', error ); - testPoint(_position$2, i, localThresholdSq, matrixWorld, raycaster, intersects, this); - } } + } - updateMorphTargets() { - const geometry = this.geometry; - const morphAttributes = geometry.morphAttributes; - const keys = Object.keys(morphAttributes); + function compressedTexSubImage2D() { - if (keys.length > 0) { - const morphAttribute = morphAttributes[keys[0]]; + try { - if (morphAttribute !== undefined) { - this.morphTargetInfluences = []; - this.morphTargetDictionary = {}; + gl.compressedTexSubImage2D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); - for (let m = 0, ml = morphAttribute.length; m < ml; m++) { - const name = morphAttribute[m].name || String(m); - this.morphTargetInfluences.push(0); - this.morphTargetDictionary[name] = m; - } - } } + } -} + function compressedTexSubImage3D() { -function testPoint(point, index, localThresholdSq, matrixWorld, raycaster, intersects, object) { - const rayPointDistanceSq = _ray.distanceSqToPoint(point); + try { - if (rayPointDistanceSq < localThresholdSq) { - const intersectPoint = new Vector3(); + gl.compressedTexSubImage3D.apply( gl, arguments ); - _ray.closestPointToPoint(point, intersectPoint); + } catch ( error ) { - intersectPoint.applyMatrix4(matrixWorld); - const distance = raycaster.ray.origin.distanceTo(intersectPoint); - if (distance < raycaster.near || distance > raycaster.far) return; - intersects.push({ - distance: distance, - distanceToRay: Math.sqrt(rayPointDistanceSq), - point: intersectPoint, - index: index, - face: null, - object: object - }); - } -} - -class VideoTexture extends Texture { - constructor(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) { - super(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); - this.isVideoTexture = true; - this.minFilter = minFilter !== undefined ? minFilter : LinearFilter; - this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; - this.generateMipmaps = false; - const scope = this; + console.error( 'THREE.WebGLState:', error ); - function updateVideo() { - scope.needsUpdate = true; - video.requestVideoFrameCallback(updateVideo); } - if ('requestVideoFrameCallback' in video) { - video.requestVideoFrameCallback(updateVideo); - } } - clone() { - return new this.constructor(this.image).copy(this); - } + function texStorage2D() { - update() { - const video = this.image; - const hasVideoFrameCallback = ('requestVideoFrameCallback' in video); + try { + + gl.texStorage2D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); - if (hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA) { - this.needsUpdate = true; } + } -} + function texStorage3D() { -class FramebufferTexture extends Texture { - constructor(width, height, format) { - super({ - width, - height - }); - this.isFramebufferTexture = true; - this.format = format; - this.magFilter = NearestFilter; - this.minFilter = NearestFilter; - this.generateMipmaps = false; - this.needsUpdate = true; - } + try { -} + gl.texStorage3D.apply( gl, arguments ); -class CompressedTexture extends Texture { - constructor(mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding) { - super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); - this.isCompressedTexture = true; - this.image = { - width: width, - height: height - }; - this.mipmaps = mipmaps; // no flipping for cube textures - // (also flipping doesn't work for compressed textures ) + } catch ( error ) { - this.flipY = false; // can't generate mipmaps for compressed textures - // mips must be embedded in DDS files + console.error( 'THREE.WebGLState:', error ); + + } - this.generateMipmaps = false; } -} + function texImage2D() { -class CanvasTexture extends Texture { - constructor(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) { - super(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); - this.isCanvasTexture = true; - this.needsUpdate = true; - } + try { -} + gl.texImage2D.apply( gl, arguments ); -/** - * Extensible curve object. - * - * Some common of curve methods: - * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget ) - * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget ) - * .getPoints(), .getSpacedPoints() - * .getLength() - * .updateArcLengths() - * - * This following curves inherit from THREE.Curve: - * - * -- 2D curves -- - * THREE.ArcCurve - * THREE.CubicBezierCurve - * THREE.EllipseCurve - * THREE.LineCurve - * THREE.QuadraticBezierCurve - * THREE.SplineCurve - * - * -- 3D curves -- - * THREE.CatmullRomCurve3 - * THREE.CubicBezierCurve3 - * THREE.LineCurve3 - * THREE.QuadraticBezierCurve3 - * - * A series of curves can be represented as a THREE.CurvePath. - * - **/ + } catch ( error ) { -class Curve { - constructor() { - this.type = 'Curve'; - this.arcLengthDivisions = 200; - } // Virtual base class method to overwrite and implement in subclasses - // - t [0 .. 1] + console.error( 'THREE.WebGLState:', error ); + } - getPoint() { - console.warn('THREE.Curve: .getPoint() not implemented.'); - return null; - } // Get point at relative position in curve according to arc length - // - u [0 .. 1] + } + function texImage3D() { - getPointAt(u, optionalTarget) { - const t = this.getUtoTmapping(u); - return this.getPoint(t, optionalTarget); - } // Get sequence of points using getPoint( t ) + try { + gl.texImage3D.apply( gl, arguments ); - getPoints(divisions = 5) { - const points = []; + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); - for (let d = 0; d <= divisions; d++) { - points.push(this.getPoint(d / divisions)); } - return points; - } // Get sequence of points using getPointAt( u ) + } + // - getSpacedPoints(divisions = 5) { - const points = []; + function scissor( scissor ) { - for (let d = 0; d <= divisions; d++) { - points.push(this.getPointAt(d / divisions)); - } + if ( currentScissor.equals( scissor ) === false ) { - return points; - } // Get total curve arc length + gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w ); + currentScissor.copy( scissor ); + } - getLength() { - const lengths = this.getLengths(); - return lengths[lengths.length - 1]; - } // Get list of cumulative segment lengths + } + function viewport( viewport ) { - getLengths(divisions = this.arcLengthDivisions) { - if (this.cacheArcLengths && this.cacheArcLengths.length === divisions + 1 && !this.needsUpdate) { - return this.cacheArcLengths; - } + if ( currentViewport.equals( viewport ) === false ) { - this.needsUpdate = false; - const cache = []; - let current, - last = this.getPoint(0); - let sum = 0; - cache.push(0); + gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w ); + currentViewport.copy( viewport ); - 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. } - updateArcLengths() { - this.needsUpdate = true; - this.getLengths(); - } // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant + function updateUBOMapping( uniformsGroup, program ) { + let mapping = uboProgramMap.get( program ); - getUtoTmapping(u, distance) { - const arcLengths = this.getLengths(); - let i = 0; - const il = arcLengths.length; - let targetArcLength; // The targeted u distance value to get + if ( mapping === undefined ) { - if (distance) { - targetArcLength = distance; - } else { - targetArcLength = u * arcLengths[il - 1]; - } // binary search for the index with largest value smaller than target u distance + mapping = new WeakMap(); + uboProgramMap.set( program, mapping ); - let low = 0, - high = il - 1, - comparison; + } - while (low <= high) { - i = Math.floor(low + (high - low) / 2); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats + let blockIndex = mapping.get( uniformsGroup ); - comparison = arcLengths[i] - targetArcLength; + if ( blockIndex === undefined ) { - if (comparison < 0) { - low = i + 1; - } else if (comparison > 0) { - high = i - 1; - } else { - high = i; - break; // DONE - } - } + blockIndex = gl.getUniformBlockIndex( program, uniformsGroup.name ); - i = high; + mapping.set( uniformsGroup, blockIndex ); - if (arcLengths[i] === targetArcLength) { - return i / (il - 1); - } // 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 + function uniformBlockBinding( uniformsGroup, program ) { - const segmentFraction = (targetArcLength - lengthBefore) / segmentLength; // add that fractional amount to t + const mapping = uboProgramMap.get( program ); + const blockIndex = mapping.get( uniformsGroup ); - const t = (i + segmentFraction) / (il - 1); - return t; - } // Returns a unit vector tangent at t - // In case any sub curve does not implement its tangent derivation, - // 2 points a small delta apart will be used to find its gradient - // which seems to give a reasonable approximation + if ( uboBindings.get( program ) !== blockIndex ) { + // bind shader specific block index to global block point + gl.uniformBlockBinding( program, blockIndex, uniformsGroup.__bindingPointIndex ); - getTangent(t, optionalTarget) { - const delta = 0.0001; - let t1 = t - delta; - let t2 = t + delta; // Capping in case of danger - - if (t1 < 0) t1 = 0; - if (t2 > 1) t2 = 1; - const pt1 = this.getPoint(t1); - const pt2 = this.getPoint(t2); - const tangent = optionalTarget || (pt1.isVector2 ? new Vector2() : new Vector3()); - tangent.copy(pt2).sub(pt1).normalize(); - return tangent; - } + uboBindings.set( program, blockIndex ); - 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 + } - 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 + // + function reset() { - normals[0] = new Vector3(); - binormals[0] = new Vector3(); - let min = Number.MAX_VALUE; - const tx = Math.abs(tangents[0].x); - const ty = Math.abs(tangents[0].y); - const tz = Math.abs(tangents[0].z); + // reset state - if (tx <= min) { - min = tx; - normal.set(1, 0, 0); - } + gl.disable( gl.BLEND ); + gl.disable( gl.CULL_FACE ); + gl.disable( gl.DEPTH_TEST ); + gl.disable( gl.POLYGON_OFFSET_FILL ); + gl.disable( gl.SCISSOR_TEST ); + gl.disable( gl.STENCIL_TEST ); + gl.disable( gl.SAMPLE_ALPHA_TO_COVERAGE ); - if (ty <= min) { - min = ty; - normal.set(0, 1, 0); - } + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.ONE, gl.ZERO ); + gl.blendFuncSeparate( gl.ONE, gl.ZERO, gl.ONE, gl.ZERO ); - if (tz <= min) { - normal.set(0, 0, 1); - } + gl.colorMask( true, true, true, true ); + gl.clearColor( 0, 0, 0, 0 ); - 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 + gl.depthMask( true ); + gl.depthFunc( gl.LESS ); + gl.clearDepth( 1 ); - 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]); + gl.stencilMask( 0xffffffff ); + gl.stencilFunc( gl.ALWAYS, 0, 0xffffffff ); + gl.stencilOp( gl.KEEP, gl.KEEP, gl.KEEP ); + gl.clearStencil( 0 ); - 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 + gl.cullFace( gl.BACK ); + gl.frontFace( gl.CCW ); - normals[i].applyMatrix4(mat.makeRotationAxis(vec, theta)); - } + gl.polygonOffset( 0, 0 ); - 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 + gl.activeTexture( gl.TEXTURE0 ); + gl.bindFramebuffer( gl.FRAMEBUFFER, null ); - if (closed === true) { - let theta = Math.acos(clamp(normals[0].dot(normals[segments]), -1, 1)); - theta /= segments; + if ( isWebGL2 === true ) { - if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) { - theta = -theta; - } + gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, null ); + gl.bindFramebuffer( gl.READ_FRAMEBUFFER, null ); - 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); - } + gl.useProgram( null ); - copy(source) { - this.arcLengthDivisions = source.arcLengthDivisions; - return this; - } + gl.lineWidth( 1 ); - toJSON() { - const data = { - metadata: { - version: 4.5, - type: 'Curve', - generator: 'Curve.toJSON' - } - }; - data.arcLengthDivisions = this.arcLengthDivisions; - data.type = this.type; - return data; - } + gl.scissor( 0, 0, gl.canvas.width, gl.canvas.height ); + gl.viewport( 0, 0, gl.canvas.width, gl.canvas.height ); - fromJSON(json) { - this.arcLengthDivisions = json.arcLengthDivisions; - return this; - } + // reset internals -} + enabledCapabilities = {}; -class EllipseCurve extends Curve { - constructor(aX = 0, aY = 0, xRadius = 1, yRadius = 1, aStartAngle = 0, aEndAngle = Math.PI * 2, aClockwise = false, aRotation = 0) { - super(); - this.isEllipseCurve = true; - this.type = 'EllipseCurve'; - this.aX = aX; - this.aY = aY; - this.xRadius = xRadius; - this.yRadius = yRadius; - this.aStartAngle = aStartAngle; - this.aEndAngle = aEndAngle; - this.aClockwise = aClockwise; - this.aRotation = aRotation; - } + currentTextureSlot = null; + currentBoundTextures = {}; - 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 + currentBoundFramebuffers = {}; + currentDrawbuffers = new WeakMap(); + defaultDrawbuffers = []; - while (deltaAngle < 0) deltaAngle += twoPi; + currentProgram = null; - while (deltaAngle > twoPi) deltaAngle -= twoPi; + currentBlendingEnabled = false; + currentBlending = null; + currentBlendEquation = null; + currentBlendSrc = null; + currentBlendDst = null; + currentBlendEquationAlpha = null; + currentBlendSrcAlpha = null; + currentBlendDstAlpha = null; + currentPremultipledAlpha = false; - if (deltaAngle < Number.EPSILON) { - if (samePoints) { - deltaAngle = 0; - } else { - deltaAngle = twoPi; - } - } + currentFlipSided = null; + currentCullFace = null; - if (this.aClockwise === true && !samePoints) { - if (deltaAngle === twoPi) { - deltaAngle = -twoPi; - } else { - deltaAngle = deltaAngle - twoPi; - } - } + currentLineWidth = null; - const angle = this.aStartAngle + t * deltaAngle; - let x = this.aX + this.xRadius * Math.cos(angle); - let y = this.aY + this.yRadius * Math.sin(angle); + currentPolygonOffsetFactor = null; + currentPolygonOffsetUnits = null; - 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. + currentScissor.set( 0, 0, gl.canvas.width, gl.canvas.height ); + currentViewport.set( 0, 0, gl.canvas.width, gl.canvas.height ); - x = tx * cos - ty * sin + this.aX; - y = tx * sin + ty * cos + this.aY; - } + colorBuffer.reset(); + depthBuffer.reset(); + stencilBuffer.reset(); - return point.set(x, y); } - copy(source) { - super.copy(source); - this.aX = source.aX; - this.aY = source.aY; - this.xRadius = source.xRadius; - this.yRadius = source.yRadius; - this.aStartAngle = source.aStartAngle; - this.aEndAngle = source.aEndAngle; - this.aClockwise = source.aClockwise; - this.aRotation = source.aRotation; - return this; - } + return { - toJSON() { - const data = super.toJSON(); - data.aX = this.aX; - data.aY = this.aY; - data.xRadius = this.xRadius; - data.yRadius = this.yRadius; - data.aStartAngle = this.aStartAngle; - data.aEndAngle = this.aEndAngle; - data.aClockwise = this.aClockwise; - data.aRotation = this.aRotation; - return data; - } + buffers: { + color: colorBuffer, + depth: depthBuffer, + stencil: stencilBuffer + }, - fromJSON(json) { - super.fromJSON(json); - this.aX = json.aX; - this.aY = json.aY; - this.xRadius = json.xRadius; - this.yRadius = json.yRadius; - this.aStartAngle = json.aStartAngle; - this.aEndAngle = json.aEndAngle; - this.aClockwise = json.aClockwise; - this.aRotation = json.aRotation; - return this; - } + enable: enable, + disable: disable, -} + bindFramebuffer: bindFramebuffer, + drawBuffers: drawBuffers, -class ArcCurve extends EllipseCurve { - constructor(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { - super(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); - this.isArcCurve = true; - this.type = 'ArcCurve'; - } + useProgram: useProgram, -} + setBlending: setBlending, + setMaterial: setMaterial, -/** - * Centripetal CatmullRom Curve - which is useful for avoiding - * cusps and self-intersections in non-uniform catmull rom curves. - * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf - * - * curve.type accepts centripetal(default), chordal and catmullrom - * curve.tension is used for catmullrom which defaults to 0.5 - */ + setFlipSided: setFlipSided, + setCullFace: setCullFace, -/* -Based on an optimized c++ solution in - - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/ - - http://ideone.com/NoEbVM + setLineWidth: setLineWidth, + setPolygonOffset: setPolygonOffset, -This CubicPoly class could be used for reusing some variables and calculations, -but for three.js curve use, it could be possible inlined and flatten into a single function call -which can be placed in CurveUtils. -*/ + setScissorTest: setScissorTest, -function CubicPoly() { - let c0 = 0, - c1 = 0, - c2 = 0, - c3 = 0; - /* - * Compute coefficients for a cubic polynomial - * p(s) = c0 + c1*s + c2*s^2 + c3*s^3 - * such that - * p(0) = x0, p(1) = x1 - * and - * p'(0) = t0, p'(1) = t1. - */ + activeTexture: activeTexture, + bindTexture: bindTexture, + unbindTexture: unbindTexture, + compressedTexImage2D: compressedTexImage2D, + compressedTexImage3D: compressedTexImage3D, + texImage2D: texImage2D, + texImage3D: texImage3D, - 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; - } + updateUBOMapping: updateUBOMapping, + uniformBlockBinding: uniformBlockBinding, - return { - initCatmullRom: function (x0, x1, x2, x3, tension) { - init(x1, x2, tension * (x2 - x0), tension * (x3 - x1)); - }, - 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] + texStorage2D: texStorage2D, + texStorage3D: texStorage3D, + texSubImage2D: texSubImage2D, + texSubImage3D: texSubImage3D, + compressedTexSubImage2D: compressedTexSubImage2D, + compressedTexSubImage3D: compressedTexSubImage3D, + + scissor: scissor, + viewport: viewport, + + reset: reset - t1 *= dt1; - t2 *= dt1; - init(x1, x2, t1, t2); - }, - calc: function (t) { - const t2 = t * t; - const t3 = t2 * t; - return c0 + c1 * t + c2 * t2 + c3 * t3; - } }; -} // +} -const tmp = new Vector3(); -const px = new CubicPoly(), - py = new CubicPoly(), - pz = new CubicPoly(); +function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) { -class CatmullRomCurve3 extends Curve { - constructor(points = [], closed = false, curveType = 'centripetal', tension = 0.5) { - super(); - this.isCatmullRomCurve3 = true; - this.type = 'CatmullRomCurve3'; - this.points = points; - this.closed = closed; - this.curveType = curveType; - this.tension = tension; - } + const isWebGL2 = capabilities.isWebGL2; + const maxTextures = capabilities.maxTextures; + const maxCubemapSize = capabilities.maxCubemapSize; + 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 = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test( navigator.userAgent ); - getPoint(t, optionalTarget = new Vector3()) { - const point = optionalTarget; - const points = this.points; - const l = points.length; - const p = (l - (this.closed ? 0 : 1)) * t; - let intPoint = Math.floor(p); - let weight = p - intPoint; + const _videoTextures = new WeakMap(); + let _canvas; - 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; - } + const _sources = new WeakMap(); // maps WebglTexture objects to instances of Source - let p0, p3; // 4 points (p1 & p2 defined below) + // 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). - if (this.closed || intPoint > 0) { - p0 = points[(intPoint - 1) % l]; - } else { - // extrapolate first point - tmp.subVectors(points[0], points[1]).add(points[0]); - p0 = tmp; - } + let useOffscreenCanvas = false; - const p1 = points[intPoint % l]; - const p2 = points[(intPoint + 1) % l]; + try { - if (this.closed || intPoint + 2 < l) { - p3 = points[(intPoint + 2) % l]; - } else { - // extrapolate last point - tmp.subVectors(points[l - 1], points[l - 2]).add(points[l - 1]); - p3 = tmp; - } + useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' + // eslint-disable-next-line compat/compat + && ( new OffscreenCanvas( 1, 1 ).getContext( '2d' ) ) !== null; + + } catch ( err ) { + + // Ignore any errors - 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 - - if (dt1 < 1e-4) dt1 = 1.0; - if (dt0 < 1e-4) dt0 = dt1; - if (dt2 < 1e-4) dt2 = dt1; - px.initNonuniformCatmullRom(p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2); - py.initNonuniformCatmullRom(p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2); - pz.initNonuniformCatmullRom(p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2); - } else if (this.curveType === 'catmullrom') { - px.initCatmullRom(p0.x, p1.x, p2.x, p3.x, this.tension); - py.initCatmullRom(p0.y, p1.y, p2.y, p3.y, this.tension); - pz.initCatmullRom(p0.z, p1.z, p2.z, p3.z, this.tension); - } - - point.set(px.calc(weight), py.calc(weight), pz.calc(weight)); - return point; } - copy(source) { - super.copy(source); - this.points = []; + function createCanvas( width, height ) { - for (let i = 0, l = source.points.length; i < l; i++) { - const point = source.points[i]; - this.points.push(point.clone()); - } + // Use OffscreenCanvas when available. Specially needed in web workers + + return useOffscreenCanvas ? + // eslint-disable-next-line compat/compat + new OffscreenCanvas( width, height ) : createElementNS( 'canvas' ); - this.closed = source.closed; - this.curveType = source.curveType; - this.tension = source.tension; - return this; } - toJSON() { - const data = super.toJSON(); - data.points = []; + function resizeImage( image, needsPowerOfTwo, needsNewCanvas, maxSize ) { - for (let i = 0, l = this.points.length; i < l; i++) { - const point = this.points[i]; - data.points.push(point.toArray()); - } + let scale = 1; - data.closed = this.closed; - data.curveType = this.curveType; - data.tension = this.tension; - return data; - } + // handle case if texture exceeds max size - fromJSON(json) { - super.fromJSON(json); - this.points = []; + if ( image.width > maxSize || image.height > maxSize ) { + + scale = maxSize / Math.max( image.width, image.height ); - 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; - } + // only perform resize if necessary -} + if ( scale < 1 || needsPowerOfTwo === true ) { -/** - * 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; -} // + // 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 ) ) { -function QuadraticBezierP0(t, p) { - const k = 1 - t; - return k * k * p; -} + const floor = needsPowerOfTwo ? floorPowerOfTwo : Math.floor; -function QuadraticBezierP1(t, p) { - return 2 * (1 - t) * t * p; -} + const width = floor( scale * image.width ); + const height = floor( scale * image.height ); -function QuadraticBezierP2(t, p) { - return t * t * p; -} + if ( _canvas === undefined ) _canvas = createCanvas( width, height ); -function QuadraticBezier(t, p0, p1, p2) { - return QuadraticBezierP0(t, p0) + QuadraticBezierP1(t, p1) + QuadraticBezierP2(t, p2); -} // + // cube textures can't reuse the same canvas + const canvas = needsNewCanvas ? createCanvas( width, height ) : _canvas; -function CubicBezierP0(t, p) { - const k = 1 - t; - return k * k * k * p; -} + canvas.width = width; + canvas.height = height; -function CubicBezierP1(t, p) { - const k = 1 - t; - return 3 * k * k * t * p; -} + const context = canvas.getContext( '2d' ); + context.drawImage( image, 0, 0, width, height ); -function CubicBezierP2(t, p) { - return 3 * (1 - t) * t * t * p; -} + console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' ); -function CubicBezierP3(t, p) { - return t * t * t * p; -} + return canvas; -function CubicBezier(t, p0, p1, p2, p3) { - return CubicBezierP0(t, p0) + CubicBezierP1(t, p1) + CubicBezierP2(t, p2) + CubicBezierP3(t, p3); -} + } else { -class CubicBezierCurve extends Curve { - constructor(v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2(), v3 = new Vector2()) { - super(); - this.isCubicBezierCurve = true; - this.type = 'CubicBezierCurve'; - this.v0 = v0; - this.v1 = v1; - this.v2 = v2; - this.v3 = v3; - } + if ( 'data' in image ) { - getPoint(t, optionalTarget = new Vector2()) { - const point = optionalTarget; - const v0 = this.v0, - v1 = this.v1, - v2 = this.v2, - v3 = this.v3; - point.set(CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.y, v3.y)); - return point; - } + console.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').' ); - copy(source) { - super.copy(source); - this.v0.copy(source.v0); - this.v1.copy(source.v1); - this.v2.copy(source.v2); - this.v3.copy(source.v3); - return this; - } + } - toJSON() { - const data = super.toJSON(); - data.v0 = this.v0.toArray(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); - data.v3 = this.v3.toArray(); - return data; - } + return image; - fromJSON(json) { - super.fromJSON(json); - this.v0.fromArray(json.v0); - this.v1.fromArray(json.v1); - this.v2.fromArray(json.v2); - this.v3.fromArray(json.v3); - return this; - } + } -} + } + + return image; -class CubicBezierCurve3 extends Curve { - constructor(v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3(), v3 = new Vector3()) { - super(); - this.isCubicBezierCurve3 = true; - this.type = 'CubicBezierCurve3'; - this.v0 = v0; - this.v1 = v1; - 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; - 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; + function isPowerOfTwo$1( image ) { + + return isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ); + } - copy(source) { - super.copy(source); - this.v0.copy(source.v0); - this.v1.copy(source.v1); - this.v2.copy(source.v2); - this.v3.copy(source.v3); - return this; + function textureNeedsPowerOfTwo( texture ) { + + if ( isWebGL2 ) return false; + + return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) || + ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ); + } - toJSON() { - const data = super.toJSON(); - data.v0 = this.v0.toArray(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); - data.v3 = this.v3.toArray(); - return data; + function textureNeedsGenerateMipmaps( texture, supportsMips ) { + + return texture.generateMipmaps && supportsMips && + texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; + } - fromJSON(json) { - super.fromJSON(json); - this.v0.fromArray(json.v0); - this.v1.fromArray(json.v1); - this.v2.fromArray(json.v2); - this.v3.fromArray(json.v3); - return this; + function generateMipmap( target ) { + + _gl.generateMipmap( target ); + } -} + function getInternalFormat( internalFormatName, glFormat, glType, encoding, forceLinearEncoding = false ) { -class LineCurve extends Curve { - constructor(v1 = new Vector2(), v2 = new Vector2()) { - super(); - this.isLineCurve = true; - this.type = 'LineCurve'; - this.v1 = v1; - this.v2 = v2; - } + if ( isWebGL2 === false ) return glFormat; - getPoint(t, optionalTarget = new Vector2()) { - const point = optionalTarget; + if ( internalFormatName !== null ) { - if (t === 1) { - point.copy(this.v2); - } else { - point.copy(this.v2).sub(this.v1); - point.multiplyScalar(t).add(this.v1); - } + if ( _gl[ internalFormatName ] !== undefined ) return _gl[ internalFormatName ]; - return point; - } // Line curve is linear, so we can overwrite default getPointAt + console.warn( 'THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'' ); + } - getPointAt(u, optionalTarget) { - return this.getPoint(u, optionalTarget); - } + let internalFormat = glFormat; - getTangent(t, optionalTarget) { - const tangent = optionalTarget || new Vector2(); - tangent.copy(this.v2).sub(this.v1).normalize(); - return tangent; - } + if ( glFormat === _gl.RED ) { - copy(source) { - super.copy(source); - this.v1.copy(source.v1); - this.v2.copy(source.v2); - return this; - } + if ( glType === _gl.FLOAT ) internalFormat = _gl.R32F; + if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.R16F; + if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = _gl.R8; - 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; - } + 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; -class LineCurve3 extends Curve { - constructor(v1 = new Vector3(), v2 = new Vector3()) { - super(); - this.isLineCurve3 = true; - this.type = 'LineCurve3'; - this.v1 = v1; - this.v2 = v2; - } + } - getPoint(t, optionalTarget = new Vector3()) { - const point = optionalTarget; + 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 && 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 (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 + 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' ); - 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; - } + return internalFormat; - 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; - } + function getMipLevels( texture, image, supportsMips ) { -} + if ( textureNeedsGenerateMipmaps( texture, supportsMips ) === true || ( texture.isFramebufferTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) ) { -class QuadraticBezierCurve extends Curve { - constructor(v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2()) { - super(); - this.isQuadraticBezierCurve = true; - this.type = 'QuadraticBezierCurve'; - this.v0 = v0; - this.v1 = v1; - this.v2 = v2; - } + return Math.log2( Math.max( image.width, image.height ) ) + 1; - getPoint(t, optionalTarget = new Vector2()) { - const point = optionalTarget; - const v0 = this.v0, - v1 = this.v1, - v2 = this.v2; - point.set(QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y)); - return point; - } + } else if ( texture.mipmaps !== undefined && texture.mipmaps.length > 0 ) { - copy(source) { - super.copy(source); - this.v0.copy(source.v0); - this.v1.copy(source.v1); - this.v2.copy(source.v2); - return this; - } + // user-defined mipmaps - toJSON() { - const data = super.toJSON(); - data.v0 = this.v0.toArray(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); - return data; - } + return texture.mipmaps.length; - fromJSON(json) { - super.fromJSON(json); - this.v0.fromArray(json.v0); - this.v1.fromArray(json.v1); - this.v2.fromArray(json.v2); - return this; - } + } else if ( texture.isCompressedTexture && Array.isArray( texture.image ) ) { -} + return image.mipmaps.length; -class QuadraticBezierCurve3 extends Curve { - constructor(v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3()) { - super(); - this.isQuadraticBezierCurve3 = true; - this.type = 'QuadraticBezierCurve3'; - this.v0 = v0; - this.v1 = v1; - this.v2 = v2; - } + } else { - getPoint(t, optionalTarget = new Vector3()) { - const point = optionalTarget; - const v0 = this.v0, - v1 = this.v1, - v2 = this.v2; - point.set(QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y), QuadraticBezier(t, v0.z, v1.z, v2.z)); - return point; - } + // texture without mipmaps (only base level) - copy(source) { - super.copy(source); - this.v0.copy(source.v0); - this.v1.copy(source.v1); - this.v2.copy(source.v2); - return this; - } + return 1; - toJSON() { - const data = super.toJSON(); - data.v0 = this.v0.toArray(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); - return data; - } + } - fromJSON(json) { - super.fromJSON(json); - this.v0.fromArray(json.v0); - this.v1.fromArray(json.v1); - this.v2.fromArray(json.v2); - return this; } -} + // Fallback filters for non-power-of-2 textures -class SplineCurve extends Curve { - constructor(points = []) { - super(); - this.isSplineCurve = true; - this.type = 'SplineCurve'; - this.points = points; - } + function filterFallback( f ) { - getPoint(t, optionalTarget = new Vector2()) { - const point = optionalTarget; - const points = this.points; - const p = (points.length - 1) * t; - const intPoint = Math.floor(p); - const weight = p - intPoint; - const p0 = points[intPoint === 0 ? intPoint : intPoint - 1]; - const p1 = points[intPoint]; - const p2 = points[intPoint > points.length - 2 ? points.length - 1 : intPoint + 1]; - const p3 = points[intPoint > points.length - 3 ? points.length - 1 : intPoint + 2]; - point.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y)); - return point; - } + if ( f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter ) { - copy(source) { - super.copy(source); - this.points = []; + return _gl.NEAREST; - for (let i = 0, l = source.points.length; i < l; i++) { - const point = source.points[i]; - this.points.push(point.clone()); } - return this; + return _gl.LINEAR; + } - 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()); - } + function onTextureDispose( event ) { - return data; - } + const texture = event.target; - fromJSON(json) { - super.fromJSON(json); - this.points = []; + texture.removeEventListener( 'dispose', onTextureDispose ); + + deallocateTexture( texture ); + + if ( texture.isVideoTexture ) { + + _videoTextures.delete( texture ); - 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; } -} + function onRenderTargetDispose( event ) { -var Curves = /*#__PURE__*/Object.freeze({ - __proto__: null, - ArcCurve: ArcCurve, - CatmullRomCurve3: CatmullRomCurve3, - CubicBezierCurve: CubicBezierCurve, - CubicBezierCurve3: CubicBezierCurve3, - EllipseCurve: EllipseCurve, - LineCurve: LineCurve, - LineCurve3: LineCurve3, - QuadraticBezierCurve: QuadraticBezierCurve, - QuadraticBezierCurve3: QuadraticBezierCurve3, - SplineCurve: SplineCurve -}); + const renderTarget = event.target; -/************************************************************** - * Curved Path - a curve path is simply a array of connected - * curves, but retains the api of a curve - **************************************************************/ + renderTarget.removeEventListener( 'dispose', onRenderTargetDispose ); -class CurvePath extends Curve { - constructor() { - super(); - this.type = 'CurvePath'; - this.curves = []; - this.autoClose = false; // Automatically closes the path - } + deallocateRenderTarget( renderTarget ); - 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 - // 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') + function deallocateTexture( texture ) { + const textureProperties = properties.get( texture ); - getPoint(t, optionalTarget) { - const d = t * this.getLength(); - const curveLengths = this.getCurveLengths(); - let i = 0; // To think about boundaries points. + if ( textureProperties.__webglInit === undefined ) return; - while (i < curveLengths.length) { - if (curveLengths[i] >= d) { - const diff = curveLengths[i] - d; - const curve = this.curves[i]; - const segmentLength = curve.getLength(); - const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; - return curve.getPointAt(u, optionalTarget); - } + // check if it's necessary to remove the WebGLTexture object - i++; - } + const source = texture.source; + const webglTextures = _sources.get( source ); - return null; // loop where sum != 0, sum > d , sum+1 1 && !points[points.length - 1].equals(points[0])) { - points.push(points[0]); } - return points; - } + if ( renderTarget.depthTexture ) { - copy(source) { - super.copy(source); - this.curves = []; + renderTarget.depthTexture.dispose(); - 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; - } + if ( renderTarget.isWebGLCubeRenderTarget ) { - toJSON() { - const data = super.toJSON(); - data.autoClose = this.autoClose; - data.curves = []; + for ( let i = 0; i < 6; i ++ ) { - for (let i = 0, l = this.curves.length; i < l; i++) { - const curve = this.curves[i]; - data.curves.push(curve.toJSON()); - } + _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] ); + if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] ); - return data; - } + } - fromJSON(json) { - super.fromJSON(json); - this.autoClose = json.autoClose; - this.curves = []; + } else { - 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)); - } + _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer ); + if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer ); + if ( renderTargetProperties.__webglMultisampledFramebuffer ) _gl.deleteFramebuffer( renderTargetProperties.__webglMultisampledFramebuffer ); - return this; - } + if ( renderTargetProperties.__webglColorRenderbuffer ) { -} + for ( let i = 0; i < renderTargetProperties.__webglColorRenderbuffer.length; i ++ ) { -class Path extends CurvePath { - constructor(points) { - super(); - this.type = 'Path'; - this.currentPoint = new Vector2(); + if ( renderTargetProperties.__webglColorRenderbuffer[ i ] ) _gl.deleteRenderbuffer( renderTargetProperties.__webglColorRenderbuffer[ i ] ); - if (points) { - this.setFromPoints(points); - } - } + } + + } - setFromPoints(points) { - this.moveTo(points[0].x, points[0].y); + if ( renderTargetProperties.__webglDepthRenderbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthRenderbuffer ); - for (let i = 1, l = points.length; i < l; i++) { - this.lineTo(points[i].x, points[i].y); } - return this; - } + if ( renderTarget.isWebGLMultipleRenderTargets ) { - moveTo(x, y) { - this.currentPoint.set(x, y); // TODO consider referencing vectors instead of copying? + for ( let i = 0, il = texture.length; i < il; i ++ ) { - return this; - } + const attachmentProperties = properties.get( texture[ i ] ); - 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; - } + if ( attachmentProperties.__webglTexture ) { - 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; - } + _gl.deleteTexture( attachmentProperties.__webglTexture ); - 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; - } + info.memory.textures --; - 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; - } + properties.remove( texture[ i ] ); - absarc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { - this.absellipse(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); - return this; - } + } + + } + + properties.remove( texture ); + properties.remove( renderTarget ); - 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); + let textureUnits = 0; - if (!firstPoint.equals(this.currentPoint)) { - this.lineTo(firstPoint.x, firstPoint.y); - } - } + function resetTextureUnits() { - this.curves.push(curve); - const lastPoint = curve.getPoint(1); - this.currentPoint.copy(lastPoint); - return this; - } + textureUnits = 0; - copy(source) { - super.copy(source); - this.currentPoint.copy(source.currentPoint); - return this; } - toJSON() { - const data = super.toJSON(); - data.currentPoint = this.currentPoint.toArray(); - return data; - } + 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; - fromJSON(json) { - super.fromJSON(json); - this.currentPoint.fromArray(json.currentPoint); - return this; } -} + function getTextureCacheKey( texture ) { -class LatheGeometry extends BufferGeometry { - constructor(points = [new Vector2(0, 0.5), new Vector2(0.5, 0), new Vector2(0, -0.5)], segments = 12, phiStart = 0, phiLength = Math.PI * 2) { - super(); - this.type = 'LatheGeometry'; - this.parameters = { - points: points, - segments: segments, - phiStart: phiStart, - phiLength: phiLength - }; - segments = Math.floor(segments); // clamp phiLength so it's in range of [ 0, 2PI ] + const array = []; - phiLength = clamp(phiLength, 0, Math.PI * 2); // buffers + 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 ); + array.push( texture.internalFormat ); + array.push( texture.format ); + array.push( texture.type ); + array.push( texture.generateMipmaps ); + array.push( texture.premultiplyAlpha ); + array.push( texture.flipY ); + array.push( texture.unpackAlignment ); + array.push( texture.encoding ); - const indices = []; - const vertices = []; - const uvs = []; - const initNormals = []; - const normals = []; // helper variables + return array.join(); - const inverseSegments = 1.0 / segments; - const vertex = new Vector3(); - const uv = new Vector2(); - const normal = new Vector3(); - const curNormal = new Vector3(); - const prevNormal = new Vector3(); - let dx = 0; - 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; - normal.y = -dx; - normal.z = dy * 0.0; - prevNormal.copy(normal); - 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; - normal.y = -dx; - normal.z = dy * 0.0; - curNormal.copy(normal); - normal.x += prevNormal.x; - normal.y += prevNormal.y; - normal.z += prevNormal.z; - normal.normalize(); - initNormals.push(normal.x, normal.y, normal.z); - prevNormal.copy(curNormal); - } - } // generate vertices, uvs and normals + function setTexture2D( texture, slot ) { + const textureProperties = properties.get( texture ); - for (let i = 0; i <= segments; i++) { - const phi = phiStart + i * inverseSegments * phiLength; - const sin = Math.sin(phi); - const cos = Math.cos(phi); + if ( texture.isVideoTexture ) updateVideoTexture( texture ); - 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 + if ( texture.isRenderTargetTexture === false && texture.version > 0 && textureProperties.__version !== texture.version ) { - uv.x = i / segments; - uv.y = j / (points.length - 1); - uvs.push(uv.x, uv.y); // normal + const image = texture.image; - 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 + if ( image === null ) { + console.warn( 'THREE.WebGLRenderer: Texture marked for update but no image data found.' ); - for (let i = 0; i < segments; i++) { - for (let j = 0; j < points.length - 1; j++) { - const base = j + i * points.length; - const a = base; - const b = base + points.length; - const c = base + points.length + 1; - const d = base + 1; // faces + } else if ( image.complete === false ) { - indices.push(a, b, d); - indices.push(c, d, b); - } - } // build geometry + console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete' ); + } else { - this.setIndex(indices); - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - } + uploadTexture( textureProperties, texture, slot ); + return; - static fromJSON(data) { - return new LatheGeometry(data.points, data.segments, data.phiStart, data.phiLength); - } + } -} + } -class CapsuleGeometry extends LatheGeometry { - constructor(radius = 1, length = 1, capSegments = 4, radialSegments = 8) { - const path = new Path(); - path.absarc(0, -length / 2, radius, Math.PI * 1.5, 0); - path.absarc(0, length / 2, radius, 0, Math.PI * 0.5); - super(path.getPoints(capSegments), radialSegments); - this.type = 'CapsuleGeometry'; - this.parameters = { - radius: radius, - height: length, - capSegments: capSegments, - radialSegments: radialSegments - }; - } + state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); - static fromJSON(data) { - return new CapsuleGeometry(data.radius, data.length, data.capSegments, data.radialSegments); } -} + function setTexture2DArray( texture, slot ) { -class CircleGeometry extends BufferGeometry { - constructor(radius = 1, segments = 8, thetaStart = 0, thetaLength = Math.PI * 2) { - super(); - this.type = 'CircleGeometry'; - this.parameters = { - radius: radius, - segments: segments, - thetaStart: thetaStart, - thetaLength: thetaLength - }; - segments = Math.max(3, segments); // buffers + const textureProperties = properties.get( texture ); - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // helper variables + if ( texture.version > 0 && textureProperties.__version !== texture.version ) { - const vertex = new Vector3(); - const uv = new Vector2(); // center point + uploadTexture( textureProperties, texture, slot ); + return; - 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 + state.bindTexture( _gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); - vertex.x = radius * Math.cos(segment); - vertex.y = radius * Math.sin(segment); - vertices.push(vertex.x, vertex.y, vertex.z); // normal + } - normals.push(0, 0, 1); // uvs + function setTexture3D( texture, slot ) { - uv.x = (vertices[i] / radius + 1) / 2; - uv.y = (vertices[i + 1] / radius + 1) / 2; - uvs.push(uv.x, uv.y); - } // indices + const textureProperties = properties.get( texture ); + if ( texture.version > 0 && textureProperties.__version !== texture.version ) { - for (let i = 1; i <= segments; i++) { - indices.push(i, i + 1, 0); - } // build geometry + uploadTexture( textureProperties, texture, slot ); + return; + } - this.setIndex(indices); - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - } + state.bindTexture( _gl.TEXTURE_3D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); - static fromJSON(data) { - return new CircleGeometry(data.radius, data.segments, data.thetaStart, data.thetaLength); } -} - -class CylinderGeometry extends BufferGeometry { - constructor(radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) { - super(); - this.type = 'CylinderGeometry'; - this.parameters = { - radiusTop: radiusTop, - radiusBottom: radiusBottom, - height: height, - radialSegments: radialSegments, - heightSegments: heightSegments, - openEnded: openEnded, - thetaStart: thetaStart, - thetaLength: thetaLength - }; - const scope = this; - radialSegments = Math.floor(radialSegments); - heightSegments = Math.floor(heightSegments); // buffers + function setTextureCube( texture, slot ) { - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // helper variables + const textureProperties = properties.get( texture ); - let index = 0; - const indexArray = []; - const halfHeight = height / 2; - let groupStart = 0; // generate geometry + if ( texture.version > 0 && textureProperties.__version !== texture.version ) { - generateTorso(); + uploadCubeTexture( textureProperties, texture, slot ); + return; - if (openEnded === false) { - if (radiusTop > 0) generateCap(true); - if (radiusBottom > 0) generateCap(false); - } // build geometry + } + state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); - 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 + const wrappingToGL = { + [ RepeatWrapping ]: _gl.REPEAT, + [ ClampToEdgeWrapping ]: _gl.CLAMP_TO_EDGE, + [ MirroredRepeatWrapping ]: _gl.MIRRORED_REPEAT + }; - const slope = (radiusBottom - radiusTop) / height; // generate vertices, normals and uvs + const filterToGL = { + [ NearestFilter ]: _gl.NEAREST, + [ NearestMipmapNearestFilter ]: _gl.NEAREST_MIPMAP_NEAREST, + [ NearestMipmapLinearFilter ]: _gl.NEAREST_MIPMAP_LINEAR, - for (let y = 0; y <= heightSegments; y++) { - const indexRow = []; - const v = y / heightSegments; // calculate the radius of the current row + [ LinearFilter ]: _gl.LINEAR, + [ LinearMipmapNearestFilter ]: _gl.LINEAR_MIPMAP_NEAREST, + [ LinearMipmapLinearFilter ]: _gl.LINEAR_MIPMAP_LINEAR + }; - const radius = v * (radiusBottom - radiusTop) + radiusTop; + function setTextureParameters( textureType, texture, supportsMips ) { - 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 + if ( supportsMips ) { - vertex.x = radius * sinTheta; - vertex.y = -v * height + halfHeight; - vertex.z = radius * cosTheta; - vertices.push(vertex.x, vertex.y, vertex.z); // normal + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, wrappingToGL[ texture.wrapS ] ); + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, wrappingToGL[ texture.wrapT ] ); - normal.set(sinTheta, slope, cosTheta).normalize(); - normals.push(normal.x, normal.y, normal.z); // uv + if ( textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY ) { - uvs.push(u, 1 - v); // save index of vertex in respective row + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_R, wrappingToGL[ texture.wrapR ] ); - indexRow.push(index++); - } // now save vertices of the row in our index array + } + _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterToGL[ texture.magFilter ] ); + _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterToGL[ texture.minFilter ] ); - indexArray.push(indexRow); - } // generate indices + } else { + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE ); + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE ); - 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 + if ( textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY ) { - indices.push(a, b, d); - indices.push(b, c, d); // update group counter + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_R, _gl.CLAMP_TO_EDGE ); - groupCount += 6; - } - } // add a group to the geometry. this will ensure multi material support + } + if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) { - scope.addGroup(groupStart, groupCount, 0); // calculate new start value for groups + console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.' ); - groupStart += groupCount; - } + } - function generateCap(top) { - // save the index of the first center vertex - const centerIndexStart = index; - const uv = new Vector2(); - 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. - // because the geometry needs one set of uvs per face, - // we must generate a center vertex per face/segment + _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) ); + _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) ); - for (let x = 1; x <= radialSegments; x++) { - // vertex - vertices.push(0, halfHeight * sign, 0); // normal + if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) { - normals.push(0, sign, 0); // uv + console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.' ); - uvs.push(0.5, 0.5); // increase index + } - index++; - } // save the index of the last center vertex + } + if ( extensions.has( 'EXT_texture_filter_anisotropic' ) === true ) { - const centerIndexEnd = index; // now we generate the surrounding vertices, normals and uvs + const extension = extensions.get( 'EXT_texture_filter_anisotropic' ); - 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 + if ( texture.magFilter === NearestFilter ) return; + if ( texture.minFilter !== NearestMipmapLinearFilter && texture.minFilter !== LinearMipmapLinearFilter ) return; + 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 - vertex.x = radius * sinTheta; - vertex.y = halfHeight * sign; - vertex.z = radius * cosTheta; - vertices.push(vertex.x, vertex.y, vertex.z); // normal + if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) { - normals.push(0, sign, 0); // uv + _gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) ); + properties.get( texture ).__currentAnisotropy = texture.anisotropy; - uv.x = cosTheta * 0.5 + 0.5; - uv.y = sinTheta * 0.5 * sign + 0.5; - uvs.push(uv.x, uv.y); // increase index + } - index++; - } // generate indices + } + } - for (let x = 0; x < radialSegments; x++) { - const c = centerIndexStart + x; - const i = centerIndexEnd + x; + function initTexture( textureProperties, texture ) { - if (top === true) { - // face top - indices.push(i, i + 1, c); - } else { - // face bottom - indices.push(i + 1, i, c); - } + let forceUpload = false; - groupCount += 3; - } // add a group to the geometry. this will ensure multi material support + if ( textureProperties.__webglInit === undefined ) { + textureProperties.__webglInit = true; - scope.addGroup(groupStart, groupCount, top === true ? 1 : 2); // calculate new start value for groups + texture.addEventListener( 'dispose', onTextureDispose ); - groupStart += groupCount; } - } - static fromJSON(data) { - return new CylinderGeometry(data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); - } + // create Source <-> WebGLTextures mapping if necessary -} + const source = texture.source; + let webglTextures = _sources.get( source ); -class ConeGeometry extends CylinderGeometry { - constructor(radius = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) { - super(0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength); - this.type = 'ConeGeometry'; - this.parameters = { - radius: radius, - height: height, - radialSegments: radialSegments, - heightSegments: heightSegments, - openEnded: openEnded, - thetaStart: thetaStart, - thetaLength: thetaLength - }; - } + if ( webglTextures === undefined ) { - static fromJSON(data) { - return new ConeGeometry(data.radius, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); - } + webglTextures = {}; + _sources.set( source, webglTextures ); -} + } -class PolyhedronGeometry extends BufferGeometry { - constructor(vertices = [], indices = [], radius = 1, detail = 0) { - super(); - this.type = 'PolyhedronGeometry'; - this.parameters = { - vertices: vertices, - indices: indices, - radius: radius, - detail: detail - }; // default buffer data + // check if there is already a WebGLTexture object for the given texture parameters - const vertexBuffer = []; - const uvBuffer = []; // the subdivision creates the vertex buffer data + const textureCacheKey = getTextureCacheKey( texture ); - subdivide(detail); // all vertices should lie on a conceptual sphere with a given radius + if ( textureCacheKey !== textureProperties.__cacheKey ) { - applyRadius(radius); // finally, create the uv data + // if not, create a new instance of WebGLTexture - generateUVs(); // build non-indexed geometry + if ( webglTextures[ textureCacheKey ] === undefined ) { - this.setAttribute('position', new Float32BufferAttribute(vertexBuffer, 3)); - this.setAttribute('normal', new Float32BufferAttribute(vertexBuffer.slice(), 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvBuffer, 2)); + // create new entry - if (detail === 0) { - this.computeVertexNormals(); // flat normals - } else { - this.normalizeNormals(); // smooth normals - } // helper functions + webglTextures[ textureCacheKey ] = { + texture: _gl.createTexture(), + usedTimes: 0 + }; + info.memory.textures ++; - 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 + // when a new instance of WebGLTexture was created, a texture upload is required + // even if the image contents are identical - 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 + forceUpload = true; - 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 + webglTextures[ textureCacheKey ].usedTimes ++; - const v = []; // construct all of the vertices for this subdivision + // 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. - 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; + const webglTexture = webglTextures[ textureProperties.__cacheKey ]; - for (let j = 0; j <= rows; j++) { - if (j === 0 && i === cols) { - v[i][j] = aj; - } else { - v[i][j] = aj.clone().lerp(bj, j / rows); - } - } - } // construct all of the faces + if ( webglTexture !== undefined ) { + webglTextures[ textureProperties.__cacheKey ].usedTimes --; - for (let i = 0; i < cols; i++) { - for (let j = 0; j < 2 * (cols - i) - 1; j++) { - const k = Math.floor(j / 2); + if ( webglTexture.usedTimes === 0 ) { - if (j % 2 === 0) { - pushVertex(v[i][k + 1]); - pushVertex(v[i + 1][k]); - pushVertex(v[i][k]); - } else { - pushVertex(v[i][k + 1]); - pushVertex(v[i + 1][k + 1]); - pushVertex(v[i + 1][k]); - } - } - } - } + deleteTexture( texture ); - function applyRadius(radius) { - 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]; - vertex.y = vertexBuffer[i + 1]; - vertex.z = vertexBuffer[i + 2]; - vertex.normalize().multiplyScalar(radius); - vertexBuffer[i + 0] = vertex.x; - vertexBuffer[i + 1] = vertex.y; - vertexBuffer[i + 2] = vertex.z; } - } - function generateUVs() { - const vertex = new Vector3(); + // store references to cache key and WebGLTexture object - for (let i = 0; i < vertexBuffer.length; i += 3) { - vertex.x = vertexBuffer[i + 0]; - vertex.y = vertexBuffer[i + 1]; - vertex.z = vertexBuffer[i + 2]; - const u = azimuth(vertex) / 2 / Math.PI + 0.5; - const v = inclination(vertex) / Math.PI + 0.5; - uvBuffer.push(u, 1 - v); - } + textureProperties.__cacheKey = textureCacheKey; + textureProperties.__webglTexture = webglTextures[ textureCacheKey ].texture; - 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 - - if (max > 0.9 && min < 0.1) { - if (x0 < 0.2) uvBuffer[i + 0] += 1; - if (x1 < 0.2) uvBuffer[i + 2] += 1; - if (x2 < 0.2) uvBuffer[i + 4] += 1; - } - } - } - - function pushVertex(vertex) { - vertexBuffer.push(vertex.x, vertex.y, vertex.z); - } + return forceUpload; - 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(); - const c = new Vector3(); - const centroid = new Vector3(); - const uvA = new Vector2(); - const uvB = new Vector2(); - const uvC = new Vector2(); + function uploadTexture( textureProperties, texture, slot ) { - 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]); - c.set(vertexBuffer[i + 6], vertexBuffer[i + 7], vertexBuffer[i + 8]); - uvA.set(uvBuffer[j + 0], uvBuffer[j + 1]); - uvB.set(uvBuffer[j + 2], uvBuffer[j + 3]); - uvC.set(uvBuffer[j + 4], uvBuffer[j + 5]); - centroid.copy(a).add(b).add(c).divideScalar(3); - const azi = azimuth(centroid); - correctUV(uvA, j + 0, a, azi); - correctUV(uvB, j + 2, b, azi); - correctUV(uvC, j + 4, c, azi); - } - } + let textureType = _gl.TEXTURE_2D; - function correctUV(uv, stride, vector, azimuth) { - if (azimuth < 0 && uv.x === 1) { - uvBuffer[stride] = uv.x - 1; - } + if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) textureType = _gl.TEXTURE_2D_ARRAY; + if ( texture.isData3DTexture ) textureType = _gl.TEXTURE_3D; - 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. + const forceUpload = initTexture( textureProperties, texture ); + const source = texture.source; + state.bindTexture( textureType, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); - function azimuth(vector) { - return Math.atan2(vector.z, -vector.x); - } // Angle above the XZ plane. + const sourceProperties = properties.get( source ); + if ( source.version !== sourceProperties.__version || forceUpload === true ) { - function inclination(vector) { - return Math.atan2(-vector.y, Math.sqrt(vector.x * vector.x + vector.z * vector.z)); - } - } + state.activeTexture( _gl.TEXTURE0 + slot ); - static fromJSON(data) { - return new PolyhedronGeometry(data.vertices, data.indices, data.radius, data.details); - } + _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 ); -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/φ) - -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); - this.type = 'DodecahedronGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; - } + const supportsMips = isPowerOfTwo$1( image ) || isWebGL2, + glFormat = utils.convert( texture.format, texture.encoding ); - static fromJSON(data) { - return new DodecahedronGeometry(data.radius, data.detail); - } + let glType = utils.convert( texture.type ), + glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding, texture.isVideoTexture ); -} + setTextureParameters( textureType, texture, supportsMips ); -const _v0 = new Vector3(); + let mipmap; + const mipmaps = texture.mipmaps; -const _v1$1 = new Vector3(); + const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true ); + const allocateMemory = ( sourceProperties.__version === undefined ) || ( forceUpload === true ); + const levels = getMipLevels( texture, image, supportsMips ); -const _normal = new Vector3(); + if ( texture.isDepthTexture ) { -const _triangle = new Triangle(); + // populate depth texture with dummy data -class EdgesGeometry extends BufferGeometry { - constructor(geometry = null, thresholdAngle = 1) { - super(); - this.type = 'EdgesGeometry'; - this.parameters = { - geometry: geometry, - thresholdAngle: thresholdAngle - }; + glInternalFormat = _gl.DEPTH_COMPONENT; - if (geometry !== null) { - const precisionPoints = 4; - const precision = Math.pow(10, precisionPoints); - const thresholdDot = Math.cos(DEG2RAD * thresholdAngle); - const indexAttr = geometry.getIndex(); - const positionAttr = geometry.getAttribute('position'); - const indexCount = indexAttr ? indexAttr.count : positionAttr.count; - const indexArr = [0, 0, 0]; - const vertKeys = ['a', 'b', 'c']; - const hashes = new Array(3); - const edgeData = {}; - const vertices = []; + if ( isWebGL2 ) { - for (let i = 0; i < indexCount; i += 3) { - if (indexAttr) { - indexArr[0] = indexAttr.getX(i); - indexArr[1] = indexAttr.getX(i + 1); - indexArr[2] = indexAttr.getX(i + 2); - } else { - indexArr[0] = i; - indexArr[1] = i + 1; - indexArr[2] = i + 2; - } + if ( texture.type === FloatType ) { - const { - a, - b, - c - } = _triangle; - a.fromBufferAttribute(positionAttr, indexArr[0]); - b.fromBufferAttribute(positionAttr, indexArr[1]); - c.fromBufferAttribute(positionAttr, indexArr[2]); + glInternalFormat = _gl.DEPTH_COMPONENT32F; - _triangle.getNormal(_normal); // create hashes for the edge from the vertices + } else if ( texture.type === UnsignedIntType ) { + glInternalFormat = _gl.DEPTH_COMPONENT24; - 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 + } else if ( texture.type === UnsignedInt248Type ) { - if (hashes[0] === hashes[1] || hashes[1] === hashes[2] || hashes[2] === hashes[0]) { - continue; - } // iterate over every edge + glInternalFormat = _gl.DEPTH24_STENCIL8; + } else { - for (let j = 0; j < 3; j++) { - // get the first and next vertex making up the edge - const jNext = (j + 1) % 3; - const vecHash0 = hashes[j]; - const vecHash1 = hashes[jNext]; - const v0 = _triangle[vertKeys[j]]; - 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. - if (_normal.dot(edgeData[reverseHash].normal) <= thresholdDot) { - vertices.push(v0.x, v0.y, v0.z); - vertices.push(v1.x, v1.y, v1.z); - } + glInternalFormat = _gl.DEPTH_COMPONENT16; // WebGL2 requires sized internalformat for glTexImage2D - edgeData[reverseHash] = null; - } else if (!(hash in edgeData)) { - // if we've already got an edge here then skip adding a new one - edgeData[hash] = { - index0: indexArr[j], - index1: indexArr[jNext], - normal: _normal.clone() - }; } - } - } // iterate over all remaining, unmatched edges and add them to the vertex array + } else { - for (const key in edgeData) { - if (edgeData[key]) { - const { - index0, - index1 - } = edgeData[key]; + if ( texture.type === FloatType ) { - _v0.fromBufferAttribute(positionAttr, index0); + console.error( 'WebGLRenderer: Floating point depth texture requires WebGL2.' ); - _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)); - } - } + // validation checks for WebGL 1 -} + if ( texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT ) { -class Shape extends Path { - constructor(points) { - super(points); - this.uuid = generateUUID(); - this.type = 'Shape'; - this.holes = []; - } + // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are + // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT + // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) + if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) { - getPointsHoles(divisions) { - const holesPts = []; + console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' ); - for (let i = 0, l = this.holes.length; i < l; i++) { - holesPts[i] = this.holes[i].getPoints(divisions); - } + texture.type = UnsignedIntType; + glType = utils.convert( texture.type ); - return holesPts; - } // get points of shape and holes (keypoints based on segments parameter) + } + } - extractPoints(divisions) { - return { - shape: this.getPoints(divisions), - holes: this.getPointsHoles(divisions) - }; - } + if ( texture.format === DepthStencilFormat && glInternalFormat === _gl.DEPTH_COMPONENT ) { - copy(source) { - super.copy(source); - this.holes = []; + // Depth stencil textures need the DEPTH_STENCIL internal format + // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) + glInternalFormat = _gl.DEPTH_STENCIL; - for (let i = 0, l = source.holes.length; i < l; i++) { - const hole = source.holes[i]; - this.holes.push(hole.clone()); - } + // 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 ) { - return this; - } + console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' ); - toJSON() { - const data = super.toJSON(); - data.uuid = this.uuid; - data.holes = []; + texture.type = UnsignedInt248Type; + glType = utils.convert( texture.type ); - 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)); - } + if ( allocateMemory ) { - return this; - } + if ( useTexStorage ) { -} + state.texStorage2D( _gl.TEXTURE_2D, 1, glInternalFormat, image.width, image.height ); -/** - * Port from https://github.com/mapbox/earcut (v2.2.2) - */ -const Earcut = { - triangulate: function (data, holeIndices, dim = 2) { - const hasHoles = holeIndices && holeIndices.length; - const outerLen = hasHoles ? holeIndices[0] * dim : data.length; - let outerNode = linkedList(data, 0, outerLen, dim, true); - 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 + } else { - if (data.length > 80 * dim) { - minX = maxX = data[0]; - minY = maxY = data[1]; + state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null ); - for (let i = dim; i < outerLen; i += dim) { - x = data[i]; - y = data[i + 1]; - if (x < minX) minX = x; - if (y < minY) minY = y; - if (x > maxX) maxX = x; - if (y > maxY) maxY = y; - } // minX, minY and invSize are later used to transform coords into integers for z-order calculation + } + } - invSize = Math.max(maxX - minX, maxY - minY); - invSize = invSize !== 0 ? 1 / invSize : 0; - } + } else if ( texture.isDataTexture ) { - earcutLinked(outerNode, triangles, dim, minX, minY, invSize); - return triangles; - } -}; // create a circular doubly linked list from polygon points in the specified winding order + // 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 -function linkedList(data, start, end, dim, clockwise) { - let i, last; + if ( mipmaps.length > 0 && supportsMips ) { - 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 ( useTexStorage && allocateMemory ) { - if (last && equals(last, last.next)) { - removeNode(last); - last = last.next; - } + state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height ); - return last; -} // eliminate colinear or duplicate points + } + for ( let i = 0, il = mipmaps.length; i < il; i ++ ) { -function filterPoints(start, end) { - if (!start) return start; - if (!end) end = start; - let p = start, - again; + mipmap = mipmaps[ i ]; - do { - again = false; + if ( useTexStorage ) { - if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { - removeNode(p); - p = end = p.prev; - if (p === p.next) break; - again = true; - } else { - p = p.next; - } - } while (again || p !== end); + state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); - return end; -} // main ear slicing loop which triangulates a polygon (given as a linked list) + } else { + state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); -function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { - 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 + } - while (ear.prev !== ear.next) { - prev = ear.prev; - next = ear.next; + texture.generateMipmaps = false; - 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 + } else { - ear = next.next; - stop = next.next; - continue; - } + if ( useTexStorage ) { - ear = next; // if we looped through the whole remaining polygon and can't find any more ears + if ( allocateMemory ) { - if (ear === stop) { - // try filtering points and slicing again - if (!pass) { - earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); // if this didn't work, try curing all small self-intersections locally - } else if (pass === 1) { - ear = cureLocalIntersections(filterPoints(ear), triangles, dim); - earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); // as a last resort, try splitting the remaining polygon into two - } else if (pass === 2) { - splitEarcut(ear, triangles, dim, minX, minY, invSize); - } + state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height ); - break; - } - } -} // check whether a polygon node forms a valid ear with adjacent nodes + } + state.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data ); -function isEar(ear) { - const a = ear.prev, - b = ear, - c = ear.next; - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear - // now make sure we don't have other points inside the potential ear + } else { - let p = ear.next.next; + state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data ); - while (p !== ear.prev) { - if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; - p = p.next; - } + } - return true; -} + } -function isEarHashed(ear, minX, minY, invSize) { - const a = ear.prev, - b = ear, - c = ear.next; - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear - // triangle bbox; min & max are calculated like this for speed + } else if ( texture.isCompressedTexture ) { - 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; + if ( texture.isCompressedArrayTexture ) { - const minZ = zOrder(minTX, minTY, minX, minY, invSize), - maxZ = zOrder(maxTX, maxTY, minX, minY, invSize); - let p = ear.prevZ, - n = ear.nextZ; // look for points inside the triangle in both directions + if ( useTexStorage && allocateMemory ) { - while (p && p.z >= minZ && n && n.z <= maxZ) { - if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; - p = p.prevZ; - if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; - n = n.nextZ; - } // look for remaining points in decreasing z-order + state.texStorage3D( _gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height, image.depth ); + } - while (p && p.z >= minZ) { - if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; - p = p.prevZ; - } // look for remaining points in increasing z-order + for ( let i = 0, il = mipmaps.length; i < il; i ++ ) { + mipmap = mipmaps[ i ]; - while (n && n.z <= maxZ) { - if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; - n = n.nextZ; - } + if ( texture.format !== RGBAFormat ) { - return true; -} // go through all polygon nodes and cure small local self-intersections + if ( glFormat !== null ) { + if ( useTexStorage ) { -function cureLocalIntersections(start, triangles, dim) { - let p = start; + state.compressedTexSubImage3D( _gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data, 0, 0 ); - do { - const a = p.prev, - b = p.next.next; + } else { - 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 + state.compressedTexImage3D( _gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, mipmap.data, 0, 0 ); - removeNode(p); - removeNode(p.next); - p = start = b; - } + } - p = p.next; - } while (p !== start); + } else { - return filterPoints(p); -} // try splitting polygon into two and triangulate them independently + console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); + } -function splitEarcut(start, triangles, dim, minX, minY, invSize) { - // look for a valid diagonal that divides the polygon into two - let a = start; + } else { - do { - let b = a.next.next; + if ( useTexStorage ) { - 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 + state.texSubImage3D( _gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data ); - a = filterPoints(a, a.next); - c = filterPoints(c, c.next); // run earcut on each half + } else { - earcutLinked(a, triangles, dim, minX, minY, invSize); - earcutLinked(c, triangles, dim, minX, minY, invSize); - return; - } + state.texImage3D( _gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, glFormat, glType, mipmap.data ); - b = b.next; - } + } - a = a.next; - } while (a !== start); -} // 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; + } else { - for (i = 0, len = holeIndices.length; i < len; i++) { - start = holeIndices[i] * dim; - end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; - list = linkedList(data, start, end, dim, false); - if (list === list.next) list.steiner = true; - queue.push(getLeftmost(list)); - } + if ( useTexStorage && allocateMemory ) { - queue.sort(compareX); // process holes from left to right + state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height ); - for (i = 0; i < queue.length; i++) { - eliminateHole(queue[i], outerNode); - outerNode = filterPoints(outerNode, outerNode.next); - } + } - return outerNode; -} + for ( let i = 0, il = mipmaps.length; i < il; i ++ ) { -function compareX(a, b) { - return a.x - b.x; -} // find a bridge between vertices that connects hole with an outer ring and link it + mipmap = mipmaps[ i ]; + if ( texture.format !== RGBAFormat ) { -function eliminateHole(hole, outerNode) { - outerNode = findHoleBridge(hole, outerNode); + if ( glFormat !== null ) { - if (outerNode) { - const b = splitPolygon(outerNode, hole); // filter collinear points around the cuts + if ( useTexStorage ) { - filterPoints(outerNode, outerNode.next); - filterPoints(b, b.next); - } -} // David Eberly's algorithm for finding a bridge between hole and outer polygon + state.compressedTexSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data ); + } else { -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 + state.compressedTexImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); - 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; + } else { - if (x === hx) { - if (hy === p.y) return p; - if (hy === p.next.y) return p.next; - } + console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); - m = p.x < p.next.x ? p : p.next; - } - } + } - p = p.next; - } while (p !== outerNode); + } else { - 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 + if ( useTexStorage ) { - const stop = m, - mx = m.x, - my = m.y; - let tanMin = Infinity, - tan; - p = m; + state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); - 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 + } else { - if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) { - m = p; - tanMin = tan; - } - } + state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); - p = p.next; - } while (p !== stop); + } - return m; -} // 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 + } + } else if ( texture.isDataArrayTexture ) { -function indexCurve(start, minX, minY, invSize) { - let p = start; + if ( useTexStorage ) { - do { - if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize); - p.prevZ = p.prev; - p.nextZ = p.next; - p = p.next; - } while (p !== start); - - 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 + if ( allocateMemory ) { + state.texStorage3D( _gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth ); -function sortLinked(list) { - let i, - 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; + state.texSubImage3D( _gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data ); - for (i = 0; i < inSize; i++) { - pSize++; - q = q.nextZ; - if (!q) break; - } + } else { - qSize = inSize; + state.texImage3D( _gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data ); - while (pSize > 0 || qSize > 0 && q) { - if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { - e = p; - p = p.nextZ; - pSize--; - } else { - e = q; - q = q.nextZ; - qSize--; } - if (tail) tail.nextZ = e;else list = e; - e.prevZ = tail; - tail = e; - } + } else if ( texture.isData3DTexture ) { - p = q; - } + if ( useTexStorage ) { - tail.nextZ = null; - inSize *= 2; - } while (numMerges > 1); + if ( allocateMemory ) { - return list; -} // z-order of a point given coords and inverse of the longer side of data bbox + state.texStorage3D( _gl.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth ); + } -function zOrder(x, y, minX, minY, invSize) { - // coords are transformed into non-negative 15-bit integer range - x = 32767 * (x - minX) * invSize; - y = 32767 * (y - minY) * invSize; - x = (x | x << 8) & 0x00FF00FF; - x = (x | x << 4) & 0x0F0F0F0F; - x = (x | x << 2) & 0x33333333; - x = (x | x << 1) & 0x55555555; - y = (y | y << 8) & 0x00FF00FF; - y = (y | y << 4) & 0x0F0F0F0F; - y = (y | y << 2) & 0x33333333; - y = (y | y << 1) & 0x55555555; - return x | y << 1; -} // find the leftmost node of a polygon ring - - -function getLeftmost(start) { - let p = start, - leftmost = start; + state.texSubImage3D( _gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data ); - do { - if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p; - p = p.next; - } while (p !== start); + } else { - return leftmost; -} // check if a point lies within a convex triangle + state.texImage3D( _gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data ); + } -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) + } else if ( texture.isFramebufferTexture ) { + if ( allocateMemory ) { -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 -} // signed area of a triangle + if ( useTexStorage ) { + state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height ); -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 + } else { + let width = image.width, height = image.height; -function equals(p1, p2) { - return p1.x === p2.x && p1.y === p2.y; -} // check if two segments intersect + for ( let i = 0; i < levels; i ++ ) { + state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, width, height, 0, glFormat, glType, null ); -function intersects(p1, q1, p2, q2) { - const o1 = sign(area(p1, q1, p2)); - const o2 = sign(area(p1, q1, q2)); - const o3 = sign(area(p2, q2, p1)); - const o4 = sign(area(p2, q2, q1)); - if (o1 !== o2 && o3 !== o4) return true; // general case + width >>= 1; + height >>= 1; - 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 + } else { - return false; -} // for collinear points p, q, r, check if point q lies on segment pr + // 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 -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); -} + if ( mipmaps.length > 0 && supportsMips ) { -function sign(num) { - return num > 0 ? 1 : num < 0 ? -1 : 0; -} // check if a polygon diagonal intersects any polygon segments + if ( useTexStorage && allocateMemory ) { + state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height ); -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); + for ( let i = 0, il = mipmaps.length; i < il; i ++ ) { - return false; -} // check if a polygon diagonal is locally inside the polygon + mipmap = mipmaps[ i ]; + if ( useTexStorage ) { -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 + state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap ); + } else { -function middleInside(a, b) { - let p = a, - inside = false; - const px = (a.x + b.x) / 2, - py = (a.y + b.y) / 2; + state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap ); - 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 + } + texture.generateMipmaps = false; -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; - a.next = b; - b.prev = a; - a2.next = an; - an.prev = a2; - b2.next = a2; - a2.prev = b2; - bp.next = b2; - b2.prev = bp; - return b2; -} // create a node and optionally link it with previous one (in a circular doubly linked list) + } else { + if ( useTexStorage ) { -function insertNode(i, x, y, last) { - const p = new Node(i, x, y); + if ( allocateMemory ) { - if (!last) { - p.prev = p; - p.next = p; - } else { - p.next = last.next; - p.prev = last; - last.next.prev = p; - last.next = p; - } + state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height ); - 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; -} + state.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image ); -function Node(i, x, y) { - // vertex index in coordinates array - this.i = i; // vertex coordinates + } else { - this.x = x; - this.y = y; // previous and next vertex nodes in a polygon ring + state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image ); - this.prev = null; - this.next = null; // z-order curve value + } - this.z = null; // previous and next nodes in z-order + } - this.prevZ = null; - this.nextZ = null; // indicates whether this is a steiner point + } - this.steiner = false; -} + if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { -function signedArea(data, start, end, dim) { - let sum = 0; + generateMipmap( textureType ); - 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; -} + sourceProperties.__version = source.version; -class ShapeUtils { - // calculate area of the contour polygon - static area(contour) { - const n = contour.length; - let a = 0.0; + if ( texture.onUpdate ) texture.onUpdate( texture ); - 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; - } + textureProperties.__version = texture.version; - 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); // + function uploadCubeTexture( textureProperties, texture, slot ) { - let holeIndex = contour.length; - holes.forEach(removeDupEndPts); + if ( texture.image.length !== 6 ) return; - for (let i = 0; i < holes.length; i++) { - holeIndices.push(holeIndex); - holeIndex += holes[i].length; - addContour(vertices, holes[i]); - } // + const forceUpload = initTexture( textureProperties, texture ); + const source = texture.source; + state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); - const triangles = Earcut.triangulate(vertices, holeIndices); // + const sourceProperties = properties.get( source ); - for (let i = 0; i < triangles.length; i += 3) { - faces.push(triangles.slice(i, i + 3)); - } + if ( source.version !== sourceProperties.__version || forceUpload === true ) { - return faces; - } + 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 ); -function removeDupEndPts(points) { - const l = points.length; + const isCompressed = ( texture.isCompressedTexture || texture.image[ 0 ].isCompressedTexture ); + const isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture ); - if (l > 2 && points[l - 1].equals(points[0])) { - points.pop(); - } -} + const cubeImage = []; -function addContour(vertices, contour) { - for (let i = 0; i < contour.length; i++) { - vertices.push(contour[i].x); - vertices.push(contour[i].y); - } -} + for ( let i = 0; i < 6; i ++ ) { -/** - * Creates extruded geometry from a path shape. - * - * parameters = { - * - * curveSegments: , // number of points on the curves - * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too - * depth: , // Depth to extrude the shape - * - * bevelEnabled: , // turn on bevel - * bevelThickness: , // how deep into the original shape bevel goes - * bevelSize: , // how far from shape outline (including bevelOffset) is bevel - * bevelOffset: , // how far from shape outline does bevel start - * bevelSegments: , // number of bevel layers - * - * extrudePath: // curve to extrude shape along - * - * UVGenerator: // object that provides UV generator functions - * - * } - */ + if ( ! isCompressed && ! isDataTexture ) { -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(); - this.type = 'ExtrudeGeometry'; - this.parameters = { - shapes: shapes, - options: options - }; - shapes = Array.isArray(shapes) ? shapes : [shapes]; - const scope = this; - const verticesArray = []; - const uvArray = []; + cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, maxCubemapSize ); - for (let i = 0, l = shapes.length; i < l; i++) { - const shape = shapes[i]; - addShape(shape); - } // build geometry + } else { + cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ]; - this.setAttribute('position', new Float32BufferAttribute(verticesArray, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvArray, 2)); - this.computeVertexNormals(); // functions + } - function addShape(shape) { - const placeholder = []; // options + cubeImage[ i ] = verifyColorSpace( texture, cubeImage[ i ] ); - const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; - const steps = options.steps !== undefined ? options.steps : 1; - let depth = options.depth !== undefined ? options.depth : 1; - let bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; - let bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 0.2; - let bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 0.1; - 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; // deprecated options + } - if (options.amount !== undefined) { - console.warn('THREE.ExtrudeBufferGeometry: amount has been renamed to depth.'); - depth = options.amount; - } // + 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 ); + const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true ); + const allocateMemory = ( sourceProperties.__version === undefined ) || ( forceUpload === true ); + let levels = getMipLevels( texture, image, supportsMips ); - let extrudePts, - extrudeByPath = false; - let splineTube, binormal, normal, position2; + setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, supportsMips ); - 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? + let mipmaps; - splineTube = extrudePath.computeFrenetFrames(steps, false); // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); + if ( isCompressed ) { - binormal = new Vector3(); - normal = new Vector3(); - position2 = new Vector3(); - } // Safeguards if bevels are not enabled + if ( useTexStorage && allocateMemory ) { + state.texStorage2D( _gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height ); - if (!bevelEnabled) { - bevelSegments = 0; - bevelThickness = 0; - bevelSize = 0; - bevelOffset = 0; - } // Variables initialization + } + for ( let i = 0; i < 6; i ++ ) { - const shapePoints = shape.extractPoints(curveSegments); - let vertices = shapePoints.shape; - const holes = shapePoints.holes; - const reverse = !ShapeUtils.isClockWise(vertices); + mipmaps = cubeImage[ i ].mipmaps; - if (reverse) { - vertices = vertices.reverse(); // Maybe we should also check if holes are in the opposite direction, just to be safe ... + for ( let j = 0; j < mipmaps.length; j ++ ) { - for (let h = 0, hl = holes.length; h < hl; h++) { - const ahole = holes[h]; + const mipmap = mipmaps[ j ]; - if (ShapeUtils.isClockWise(ahole)) { - holes[h] = ahole.reverse(); - } - } - } + if ( texture.format !== RGBAFormat ) { - const faces = ShapeUtils.triangulateShape(vertices, holes); - /* Vertices */ + if ( glFormat !== null ) { - const contour = vertices; // vertices has all points but contour has only points of circumference + if ( useTexStorage ) { - for (let h = 0, hl = holes.length; h < hl; h++) { - const ahole = holes[h]; - vertices = vertices.concat(ahole); - } + state.compressedTexSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data ); - function scalePt2(pt, vec, size) { - if (!vec) console.error('THREE.ExtrudeGeometry: vec does not exist'); - return vec.clone().multiplyScalar(size).add(pt); - } + } else { - const vlen = vertices.length, - flen = faces.length; // Find directions for point movement + state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); - function getBevelVec(inPt, inPrev, inNext) { - // computes for inPt the corresponding point inPt' on a new contour - // shifted by 1 unit (length of normalized vector) to the left - // if we walk along contour clockwise, this new contour is outside the old one - // - // inPt' is the intersection of the two lines parallel to the two - // adjacent edges of inPt at a distance of 1 unit on the left side. - 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; - 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 + } else { - const collinear0 = v_prev_x * v_next_y - v_prev_y * v_next_x; + console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' ); - 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 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 + } else { - 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 + if ( useTexStorage ) { - 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 + state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); - const v_trans_lensq = v_trans_x * v_trans_x + v_trans_y * v_trans_y; + } else { - if (v_trans_lensq <= 2) { - return new Vector2(v_trans_x, v_trans_y); - } else { - shrink_by = Math.sqrt(v_trans_lensq / 2); - } - } else { - // handle special case of collinear edges - let direction_eq = false; // assumes: opposite + state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); - if (v_prev_x > Number.EPSILON) { - if (v_next_x > Number.EPSILON) { - direction_eq = true; - } - } else { - if (v_prev_x < -Number.EPSILON) { - if (v_next_x < -Number.EPSILON) { - direction_eq = true; - } - } else { - if (Math.sign(v_prev_y) === Math.sign(v_next_y)) { - direction_eq = true; } + } - } - if (direction_eq) { - // console.log("Warning: lines are a straight sequence"); - v_trans_x = -v_prev_y; - v_trans_y = v_prev_x; - shrink_by = Math.sqrt(v_prev_lensq); - } else { - // console.log("Warning: lines are a straight spike"); - v_trans_x = v_prev_x; - v_trans_y = v_prev_y; - shrink_by = Math.sqrt(v_prev_lensq / 2); } - } - return new Vector2(v_trans_x / shrink_by, v_trans_y / shrink_by); - } + } - const contourMovements = []; + } else { - 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) - // console.log('i,j,k', i, j , k) + mipmaps = texture.mipmaps; - contourMovements[i] = getBevelVec(contour[i], contour[j], contour[k]); - } + if ( useTexStorage && allocateMemory ) { - const holesMovements = []; - let oneHoleMovements, - verticesMovements = contourMovements.concat(); + // 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) - for (let h = 0, hl = holes.length; h < hl; h++) { - const ahole = holes[h]; - oneHoleMovements = []; + if ( mipmaps.length > 0 ) levels ++; - 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) + state.texStorage2D( _gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, cubeImage[ 0 ].width, cubeImage[ 0 ].height ); - oneHoleMovements[i] = getBevelVec(ahole[i], ahole[j], ahole[k]); } - holesMovements.push(oneHoleMovements); - verticesMovements = verticesMovements.concat(oneHoleMovements); - } // Loop bevelSegments, 1 for the front, 1 for the back + for ( let i = 0; i < 6; i ++ ) { + if ( isDataTexture ) { - 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 + if ( useTexStorage ) { - 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 + state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[ i ].width, cubeImage[ i ].height, glFormat, glType, cubeImage[ i ].data ); + } else { - for (let h = 0, hl = holes.length; h < hl; h++) { - const ahole = holes[h]; - oneHoleMovements = holesMovements[h]; + 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 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; // Back facing vertices + for ( let j = 0; j < mipmaps.length; j ++ ) { - for (let i = 0; i < vlen; i++) { - const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i]; + const mipmap = mipmaps[ j ]; + const mipmapImage = mipmap.image[ i ].image; - 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 + if ( useTexStorage ) { + state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data ); - 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 ++ ) { + } else { + state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data ); - 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 + } - 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 + } + } else { - for (let h = 0, hl = holes.length; h < hl; h++) { - const ahole = holes[h]; - oneHoleMovements = holesMovements[h]; + if ( useTexStorage ) { - for (let i = 0, il = ahole.length; i < il; i++) { - const vert = scalePt2(ahole[i], oneHoleMovements[i], bs); + state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[ i ] ); - if (!extrudeByPath) { - v(vert.x, vert.y, depth + z); } else { - v(vert.x, vert.y + extrudePts[steps - 1].y, extrudePts[steps - 1].x + z); - } - } - } - } - /* Faces */ - // Top and bottom faces + state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] ); - buildLidFaces(); // Sides faces + } - buildSideFaces(); ///// Internal functions + for ( let j = 0; j < mipmaps.length; j ++ ) { - function buildLidFaces() { - const start = verticesArray.length / 3; + const mipmap = mipmaps[ j ]; - if (bevelEnabled) { - let layer = 0; // steps + 1 + if ( useTexStorage ) { - let offset = vlen * layer; // Bottom faces + state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[ i ] ); - for (let i = 0; i < flen; i++) { - const face = faces[i]; - f3(face[2] + offset, face[1] + offset, face[0] + offset); - } + } else { - layer = steps + bevelSegments * 2; - offset = vlen * layer; // Top faces + state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] ); - for (let i = 0; i < flen; i++) { - const face = faces[i]; - f3(face[0] + offset, face[1] + offset, face[2] + offset); - } - } else { - // Bottom faces - for (let i = 0; i < flen; i++) { - const face = faces[i]; - f3(face[2], face[1], face[0]); - } // 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 + } + if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { - function buildSideFaces() { - const start = verticesArray.length / 3; - let layeroffset = 0; - sidewalls(contour, layeroffset); - layeroffset += contour.length; + // We assume images for cube map have the same size. + generateMipmap( _gl.TEXTURE_CUBE_MAP ); - for (let h = 0, hl = holes.length; h < hl; h++) { - const ahole = holes[h]; - sidewalls(ahole, layeroffset); //, true + } - layeroffset += ahole.length; - } + sourceProperties.__version = source.version; - scope.addGroup(start, verticesArray.length / 3 - start, 1); - } + if ( texture.onUpdate ) texture.onUpdate( texture ); - 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); + textureProperties.__version = texture.version; - 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; - f4(a, b, c, d); - } - } - } + } - function v(x, y, z) { - placeholder.push(x); - placeholder.push(y); - placeholder.push(z); - } + // Render targets - function f3(a, b, c) { - addVertex(a); - addVertex(b); - addVertex(c); - const nextIndex = verticesArray.length / 3; - const uvs = uvgen.generateTopUV(scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1); - addUV(uvs[0]); - addUV(uvs[1]); - addUV(uvs[2]); - } - - function f4(a, b, c, d) { - addVertex(a); - addVertex(b); - addVertex(d); - addVertex(b); - addVertex(c); - addVertex(d); - const nextIndex = verticesArray.length / 3; - const uvs = uvgen.generateSideWallUV(scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1); - addUV(uvs[0]); - addUV(uvs[1]); - addUV(uvs[3]); - addUV(uvs[1]); - addUV(uvs[2]); - addUV(uvs[3]); - } + // Setup storage for target texture and bind it to correct framebuffer + function setupFrameBufferTexture( framebuffer, renderTarget, texture, attachment, textureTarget ) { - function addVertex(index) { - verticesArray.push(placeholder[index * 3 + 0]); - verticesArray.push(placeholder[index * 3 + 1]); - verticesArray.push(placeholder[index * 3 + 2]); - } + 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 ); - function addUV(vector2) { - uvArray.push(vector2.x); - uvArray.push(vector2.y); - } - } - } + if ( ! renderTargetProperties.__hasExternalTextures ) { - toJSON() { - const data = super.toJSON(); - const shapes = this.parameters.shapes; - const options = this.parameters.options; - return toJSON$1(shapes, options, data); - } + if ( textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY ) { - static fromJSON(data, shapes) { - const geometryShapes = []; + state.texImage3D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, renderTarget.depth, 0, glFormat, glType, null ); - for (let j = 0, jl = data.shapes.length; j < jl; j++) { - const shape = shapes[data.shapes[j]]; - geometryShapes.push(shape); - } + } else { - const extrudePath = data.options.extrudePath; + state.texImage2D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null ); + + } - if (extrudePath !== undefined) { - data.options.extrudePath = new Curves[extrudePath.type]().fromJSON(extrudePath); } - return new ExtrudeGeometry(geometryShapes, data.options); - } + state.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); -} + if ( useMultisampledRTT( renderTarget ) ) { -const WorldUVGenerator = { - generateTopUV: function (geometry, vertices, indexA, indexB, indexC) { - const a_x = vertices[indexA * 3]; - const a_y = vertices[indexA * 3 + 1]; - const b_x = vertices[indexB * 3]; - const b_y = vertices[indexB * 3 + 1]; - const c_x = vertices[indexC * 3]; - const c_y = vertices[indexC * 3 + 1]; - return [new Vector2(a_x, a_y), new Vector2(b_x, b_y), new Vector2(c_x, c_y)]; - }, - generateSideWallUV: function (geometry, vertices, indexA, indexB, indexC, indexD) { - const a_x = vertices[indexA * 3]; - const a_y = vertices[indexA * 3 + 1]; - const a_z = vertices[indexA * 3 + 2]; - const b_x = vertices[indexB * 3]; - const b_y = vertices[indexB * 3 + 1]; - const b_z = vertices[indexB * 3 + 2]; - const c_x = vertices[indexC * 3]; - const c_y = vertices[indexC * 3 + 1]; - const c_z = vertices[indexC * 3 + 2]; - 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 { - return [new Vector2(a_y, 1 - a_z), new Vector2(b_y, 1 - b_z), new Vector2(c_y, 1 - c_z), new Vector2(d_y, 1 - d_z)]; - } - } -}; + multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ) ); -function toJSON$1(shapes, options, data) { - data.shapes = []; + } 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 ); - if (Array.isArray(shapes)) { - for (let i = 0, l = shapes.length; i < l; i++) { - const shape = shapes[i]; - data.shapes.push(shape.uuid); } - } else { - data.shapes.push(shapes.uuid); - } - data.options = Object.assign({}, options); - if (options.extrudePath !== undefined) data.options.extrudePath = options.extrudePath.toJSON(); - return data; -} + state.bindFramebuffer( _gl.FRAMEBUFFER, null ); -class IcosahedronGeometry extends PolyhedronGeometry { - constructor(radius = 1, detail = 0) { - const t = (1 + Math.sqrt(5)) / 2; - const vertices = [-1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, 0, -1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, t, 0, -1, t, 0, 1, -t, 0, -1, -t, 0, 1]; - const indices = [0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1]; - super(vertices, indices, radius, detail); - this.type = 'IcosahedronGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; } - static fromJSON(data) { - return new IcosahedronGeometry(data.radius, data.detail); - } -} + // Setup storage for internal depth/stencil buffers and bind to correct framebuffer + function setupRenderBufferStorage( renderbuffer, renderTarget, isMultisample ) { -class OctahedronGeometry extends PolyhedronGeometry { - constructor(radius = 1, detail = 0) { - const vertices = [1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1]; - const indices = [0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2]; - super(vertices, indices, radius, detail); - this.type = 'OctahedronGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; - } + _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer ); - static fromJSON(data) { - return new OctahedronGeometry(data.radius, data.detail); - } + if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) { -} + let glInternalFormat = _gl.DEPTH_COMPONENT16; -class RingGeometry extends BufferGeometry { - constructor(innerRadius = 0.5, outerRadius = 1, thetaSegments = 8, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2) { - super(); - this.type = 'RingGeometry'; - this.parameters = { - innerRadius: innerRadius, - outerRadius: outerRadius, - thetaSegments: thetaSegments, - phiSegments: phiSegments, - thetaStart: thetaStart, - thetaLength: thetaLength - }; - thetaSegments = Math.max(3, thetaSegments); - phiSegments = Math.max(1, phiSegments); // buffers + if ( isMultisample || useMultisampledRTT( renderTarget ) ) { - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // some helper variables + const depthTexture = renderTarget.depthTexture; - let radius = innerRadius; - const radiusStep = (outerRadius - innerRadius) / phiSegments; - const vertex = new Vector3(); - const uv = new Vector2(); // generate vertices, normals and uvs + if ( depthTexture && depthTexture.isDepthTexture ) { - 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 + if ( depthTexture.type === FloatType ) { + + glInternalFormat = _gl.DEPTH_COMPONENT32F; - vertex.x = radius * Math.cos(segment); - vertex.y = radius * Math.sin(segment); - vertices.push(vertex.x, vertex.y, vertex.z); // normal + } else if ( depthTexture.type === UnsignedIntType ) { - normals.push(0, 0, 1); // uv + glInternalFormat = _gl.DEPTH_COMPONENT24; - uv.x = (vertex.x / outerRadius + 1) / 2; - uv.y = (vertex.y / outerRadius + 1) / 2; - uvs.push(uv.x, uv.y); - } // increase the radius for next row of vertices + } + } - radius += radiusStep; - } // indices + const samples = getRenderTargetSamples( renderTarget ); + if ( useMultisampledRTT( renderTarget ) ) { - for (let j = 0; j < phiSegments; j++) { - const thetaSegmentLevel = j * (thetaSegments + 1); + multisampledRTTExt.renderbufferStorageMultisampleEXT( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); - 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 + } else { + + _gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + + } + + } else { + + _gl.renderbufferStorage( _gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height ); - indices.push(a, b, d); - indices.push(b, c, d); } - } // build geometry + _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); - this.setIndex(indices); - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - } + } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) { - static fromJSON(data) { - return new RingGeometry(data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength); - } + const samples = getRenderTargetSamples( renderTarget ); -} + if ( isMultisample && useMultisampledRTT( renderTarget ) === false ) { -class ShapeGeometry extends BufferGeometry { - constructor(shapes = new Shape([new Vector2(0, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)]), curveSegments = 12) { - super(); - this.type = 'ShapeGeometry'; - this.parameters = { - shapes: shapes, - curveSegments: curveSegments - }; // buffers + _gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height ); - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // helper variables + } else if ( useMultisampledRTT( renderTarget ) ) { - let groupStart = 0; - let groupCount = 0; // allow single and array values for "shapes" parameter + multisampledRTTExt.renderbufferStorageMultisampleEXT( _gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height ); - if (Array.isArray(shapes) === false) { - addShape(shapes); - } else { - for (let i = 0; i < shapes.length; i++) { - addShape(shapes[i]); - this.addGroup(groupStart, groupCount, i); // enables MultiMaterial support + } else { + + _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height ); - groupStart += groupCount; - groupCount = 0; } - } // 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 + _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); - 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 + } else { - if (ShapeUtils.isClockWise(shapeVertices) === false) { - shapeVertices = shapeVertices.reverse(); - } + const textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [ renderTarget.texture ]; - for (let i = 0, l = shapeHoles.length; i < l; i++) { - const shapeHole = shapeHoles[i]; + for ( let i = 0; i < textures.length; i ++ ) { - if (ShapeUtils.isClockWise(shapeHole) === true) { - shapeHoles[i] = shapeHole.reverse(); - } - } + const texture = textures[ i ]; - const faces = ShapeUtils.triangulateShape(shapeVertices, shapeHoles); // join vertices of inner and outer paths to a single array + 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 ); - for (let i = 0, l = shapeHoles.length; i < l; i++) { - const shapeHole = shapeHoles[i]; - shapeVertices = shapeVertices.concat(shapeHole); - } // vertices, normals, uvs + if ( isMultisample && useMultisampledRTT( renderTarget ) === false ) { + _gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); - 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 + } else if ( useMultisampledRTT( renderTarget ) ) { + multisampledRTTExt.renderbufferStorageMultisampleEXT( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + + } else { + + _gl.renderbufferStorage( _gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height ); + + } - for (let i = 0, l = faces.length; i < l; i++) { - const face = faces[i]; - const a = face[0] + indexOffset; - const b = face[1] + indexOffset; - const c = face[2] + indexOffset; - indices.push(a, b, c); - groupCount += 3; } + } - } - toJSON() { - const data = super.toJSON(); - const shapes = this.parameters.shapes; - return toJSON(shapes, data); + _gl.bindRenderbuffer( _gl.RENDERBUFFER, null ); + } - static fromJSON(data, shapes) { - const geometryShapes = []; + // Setup resources for a Depth Texture for a FBO (needs an extension) + function setupDepthTexture( framebuffer, renderTarget ) { - for (let j = 0, jl = data.shapes.length; j < jl; j++) { - const shape = shapes[data.shapes[j]]; - geometryShapes.push(shape); - } + const isCube = ( renderTarget && renderTarget.isWebGLCubeRenderTarget ); + if ( isCube ) throw new Error( 'Depth Texture with cube render targets is not supported' ); - return new ShapeGeometry(geometryShapes, data.curveSegments); - } + state.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); -} + if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) { -function toJSON(shapes, data) { - data.shapes = []; + throw new Error( 'renderTarget.depthTexture must be an instance of THREE.DepthTexture' ); - if (Array.isArray(shapes)) { - for (let i = 0, l = shapes.length; i < l; i++) { - const shape = shapes[i]; - data.shapes.push(shape.uuid); } - } else { - data.shapes.push(shapes.uuid); - } - return data; -} + // 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 ) { -class SphereGeometry extends BufferGeometry { - constructor(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI) { - super(); - this.type = 'SphereGeometry'; - this.parameters = { - radius: radius, - widthSegments: widthSegments, - heightSegments: heightSegments, - phiStart: phiStart, - phiLength: phiLength, - thetaStart: thetaStart, - thetaLength: thetaLength - }; - widthSegments = Math.max(3, Math.floor(widthSegments)); - heightSegments = Math.max(2, Math.floor(heightSegments)); - const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI); - let index = 0; - const grid = []; - const vertex = new Vector3(); - const normal = new Vector3(); // buffers + renderTarget.depthTexture.image.width = renderTarget.width; + renderTarget.depthTexture.image.height = renderTarget.height; + renderTarget.depthTexture.needsUpdate = true; - const indices = []; - const vertices = []; - const normals = []; - 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 + setTexture2D( renderTarget.depthTexture, 0 ); - let uOffset = 0; + const webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture; + const samples = getRenderTargetSamples( renderTarget ); - if (iy == 0 && thetaStart == 0) { - uOffset = 0.5 / widthSegments; - } else if (iy == heightSegments && thetaEnd == Math.PI) { - uOffset = -0.5 / widthSegments; - } + if ( renderTarget.depthTexture.format === DepthFormat ) { + + if ( useMultisampledRTT( renderTarget ) ) { - for (let ix = 0; ix <= widthSegments; ix++) { - const u = ix / widthSegments; // vertex + multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples ); - 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 + } else { - normal.copy(vertex).normalize(); - normals.push(normal.x, normal.y, normal.z); // uv + _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 ); - uvs.push(u + uOffset, 1 - v); - verticesRow.push(index++); } - grid.push(verticesRow); - } // indices + } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) { + + if ( useMultisampledRTT( renderTarget ) ) { + + multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples ); + + } else { + _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 ); - for (let iy = 0; iy < heightSegments; iy++) { - for (let ix = 0; ix < widthSegments; ix++) { - const a = grid[iy][ix + 1]; - const b = grid[iy][ix]; - const c = grid[iy + 1][ix]; - const d = grid[iy + 1][ix + 1]; - if (iy !== 0 || thetaStart > 0) indices.push(a, b, d); - if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d); } - } // build geometry + } else { + + throw new Error( 'Unknown depthTexture format' ); - 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); } -} + // Setup GL resources for a non-texture depth buffer + function setupDepthRenderbuffer( renderTarget ) { -class TetrahedronGeometry extends PolyhedronGeometry { - constructor(radius = 1, detail = 0) { - const vertices = [1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1]; - const indices = [2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1]; - super(vertices, indices, radius, detail); - this.type = 'TetrahedronGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; - } + const renderTargetProperties = properties.get( renderTarget ); + const isCube = ( renderTarget.isWebGLCubeRenderTarget === true ); - static fromJSON(data) { - return new TetrahedronGeometry(data.radius, data.detail); - } + if ( renderTarget.depthTexture && ! renderTargetProperties.__autoAllocateDepthBuffer ) { -} + if ( isCube ) throw new Error( 'target.depthTexture not supported in Cube render targets' ); -class TorusGeometry extends BufferGeometry { - constructor(radius = 1, tube = 0.4, radialSegments = 8, tubularSegments = 6, arc = Math.PI * 2) { - super(); - this.type = 'TorusGeometry'; - this.parameters = { - radius: radius, - tube: tube, - radialSegments: radialSegments, - tubularSegments: tubularSegments, - arc: arc - }; - radialSegments = Math.floor(radialSegments); - tubularSegments = Math.floor(tubularSegments); // buffers + setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget ); - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // helper variables + } else { - const center = new Vector3(); - const vertex = new Vector3(); - const normal = new Vector3(); // generate vertices, normals and uvs + if ( isCube ) { - 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 + renderTargetProperties.__webglDepthbuffer = []; - 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 + for ( let i = 0; i < 6; i ++ ) { - 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 + state.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] ); + renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget, false ); - uvs.push(i / tubularSegments); - uvs.push(j / radialSegments); - } - } // generate indices + } + } else { - 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 + state.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer ); + renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget, false ); - indices.push(a, b, d); - indices.push(b, c, d); } - } // 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)); - } + state.bindFramebuffer( _gl.FRAMEBUFFER, null ); - static fromJSON(data) { - return new TorusGeometry(data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc); } -} + // rebind framebuffer with external textures + function rebindTextures( renderTarget, colorTexture, depthTexture ) { -class TorusKnotGeometry extends BufferGeometry { - constructor(radius = 1, tube = 0.4, tubularSegments = 64, radialSegments = 8, p = 2, q = 3) { - super(); - this.type = 'TorusKnotGeometry'; - this.parameters = { - radius: radius, - tube: tube, - tubularSegments: tubularSegments, - radialSegments: radialSegments, - p: p, - q: q - }; - tubularSegments = Math.floor(tubularSegments); - radialSegments = Math.floor(radialSegments); // buffers + const renderTargetProperties = properties.get( renderTarget ); - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // helper variables + if ( colorTexture !== undefined ) { - const vertex = new Vector3(); - const normal = new Vector3(); - const P1 = new Vector3(); - const P2 = new Vector3(); - const B = new Vector3(); - const T = new Vector3(); - const N = new Vector3(); // generate vertices, normals and uvs + setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, renderTarget.texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D ); - 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. - // 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 + if ( depthTexture !== undefined ) { - 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 + setupDepthRenderbuffer( renderTarget ); - 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. - // 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) + // Set up GL resources for the render target + function setupRenderTarget( renderTarget ) { - normal.subVectors(vertex, P1).normalize(); - normals.push(normal.x, normal.y, normal.z); // uv + const texture = renderTarget.texture; - uvs.push(i / tubularSegments); - uvs.push(j / radialSegments); - } - } // generate indices + const renderTargetProperties = properties.get( renderTarget ); + const textureProperties = properties.get( texture ); + renderTarget.addEventListener( 'dispose', onRenderTargetDispose ); - 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 + if ( renderTarget.isWebGLMultipleRenderTargets !== true ) { - indices.push(a, b, d); - indices.push(b, c, d); - } - } // build geometry + if ( textureProperties.__webglTexture === undefined ) { + textureProperties.__webglTexture = _gl.createTexture(); - 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 + } + + textureProperties.__version = texture.version; + info.memory.textures ++; - function calculatePositionOnCurve(u, p, q, radius, position) { - const cu = Math.cos(u); - const su = Math.sin(u); - const quOverP = q / p * u; - const cs = Math.cos(quOverP); - position.x = radius * (2 + cs) * 0.5 * cu; - position.y = radius * (2 + cs) * su * 0.5; - position.z = radius * Math.sin(quOverP) * 0.5; } - } - static fromJSON(data) { - return new TorusKnotGeometry(data.radius, data.tube, data.tubularSegments, data.radialSegments, data.p, data.q); - } + const isCube = ( renderTarget.isWebGLCubeRenderTarget === true ); + const isMultipleRenderTargets = ( renderTarget.isWebGLMultipleRenderTargets === true ); + const supportsMips = isPowerOfTwo$1( renderTarget ) || isWebGL2; -} + // Setup framebuffer -class TubeGeometry extends BufferGeometry { - constructor(path = new QuadraticBezierCurve3(new Vector3(-1, -1, 0), new Vector3(-1, 1, 0), new Vector3(1, 1, 0)), tubularSegments = 64, radius = 1, radialSegments = 8, closed = false) { - super(); - this.type = 'TubeGeometry'; - this.parameters = { - path: path, - tubularSegments: tubularSegments, - radius: radius, - radialSegments: radialSegments, - closed: closed - }; - const frames = path.computeFrenetFrames(tubularSegments, closed); // expose internals + if ( isCube ) { - this.tangents = frames.tangents; - this.normals = frames.normals; - this.binormals = frames.binormals; // helper variables + renderTargetProperties.__webglFramebuffer = []; - const vertex = new Vector3(); - const normal = new Vector3(); - const uv = new Vector2(); - let P = new Vector3(); // buffer + for ( let i = 0; i < 6; i ++ ) { - const vertices = []; - const normals = []; - const uvs = []; - const indices = []; // create buffer data + renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer(); - generateBufferData(); // 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 + } else { - 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 - // at the regular position on the given path - // - // if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ) + renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); + if ( isMultipleRenderTargets ) { - generateSegment(closed === false ? tubularSegments : 0); // uvs are generated in a separate function. - // this makes it easy compute correct values for closed geometries + if ( capabilities.drawBuffers ) { - generateUVs(); // finally create faces + const textures = renderTarget.texture; - generateIndices(); - } + for ( let i = 0, il = textures.length; i < il; i ++ ) { - 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 + const attachmentProperties = properties.get( textures[ i ] ); - const N = frames.normals[i]; - const B = frames.binormals[i]; // generate normals and vertices for the current segment + if ( attachmentProperties.__webglTexture === undefined ) { - 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 + attachmentProperties.__webglTexture = _gl.createTexture(); - 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 + info.memory.textures ++; - vertex.x = P.x + radius * normal.x; - vertex.y = P.y + radius * normal.y; - vertex.z = P.z + radius * normal.z; - vertices.push(vertex.x, vertex.y, vertex.z); - } - } + } - 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 + } + + } else { + + console.warn( 'THREE.WebGLRenderer: WebGLMultipleRenderTargets can only be used with WebGL2 or WEBGL_draw_buffers extension.' ); - 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++) { - uv.x = i / tubularSegments; - uv.y = j / radialSegments; - uvs.push(uv.x, uv.y); + 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, 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 ); + } + } - } - toJSON() { - const data = super.toJSON(); - data.path = this.parameters.path.toJSON(); - return data; - } + // Setup color buffer - 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); - } + if ( isCube ) { -} + state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture ); + setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, supportsMips ); -class WireframeGeometry extends BufferGeometry { - constructor(geometry = null) { - super(); - this.type = 'WireframeGeometry'; - this.parameters = { - geometry: geometry - }; + for ( let i = 0; i < 6; i ++ ) { - if (geometry !== null) { - // buffer - const vertices = []; - const edges = new Set(); // helper variables + setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i ); - 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 ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { + + generateMipmap( _gl.TEXTURE_CUBE_MAP ); - if (groups.length === 0) { - groups = [{ - start: 0, - count: indices.count, - materialIndex: 0 - }]; - } // create a data structure that contains all edges without duplicates + } + state.unbindTexture(); - for (let o = 0, ol = groups.length; o < ol; ++o) { - const group = groups[o]; - const groupStart = group.start; - const groupCount = group.count; + } else if ( isMultipleRenderTargets ) { - 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); + 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 ); - if (isUniqueEdge(start, end, edges) === true) { - vertices.push(start.x, start.y, start.z); - vertices.push(end.x, end.y, end.z); - } - } - } } - } else { - // non-indexed BufferGeometry - 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); + } + + 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; + + } else { + + console.error( 'THREE.WebGLTextures: THREE.Data3DTexture and THREE.DataArrayTexture only supported with WebGL2.' ); - if (isUniqueEdge(start, end, edges) === true) { - vertices.push(start.x, start.y, start.z); - vertices.push(end.x, end.y, end.z); - } - } } - } // build geometry + } + + 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(); - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); } - } -} + // Setup depth and stencil buffers -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 + if ( renderTarget.depthBuffer ) { - if (edges.has(hash1) === true || edges.has(hash2) === true) { - return false; - } else { - edges.add(hash1); - edges.add(hash2); - return true; - } -} + setupDepthRenderbuffer( renderTarget ); -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 -}); + } -class ShadowMaterial extends Material { - constructor(parameters) { - super(); - this.isShadowMaterial = true; - this.type = 'ShadowMaterial'; - this.color = new Color(0x000000); - this.transparent = true; - this.fog = true; - this.setValues(parameters); } - copy(source) { - super.copy(source); - this.color.copy(source.color); - this.fog = source.fog; - return this; - } + 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(); + + } + + } -class RawShaderMaterial extends ShaderMaterial { - constructor(parameters) { - super(parameters); - this.isRawShaderMaterial = true; - this.type = 'RawShaderMaterial'; } -} + function updateMultisampleRenderTarget( renderTarget ) { -class MeshStandardMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshStandardMaterial = true; - this.defines = { - 'STANDARD': '' - }; - this.type = 'MeshStandardMaterial'; - this.color = new Color(0xffffff); // diffuse + if ( ( isWebGL2 && renderTarget.samples > 0 ) && useMultisampledRTT( renderTarget ) === false ) { - this.roughness = 1.0; - this.metalness = 0.0; - this.map = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; - this.emissive = new Color(0x000000); - this.emissiveIntensity = 1.0; - this.emissiveMap = null; - this.bumpMap = null; - this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2(1, 1); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.roughnessMap = null; - this.metalnessMap = null; - this.alphaMap = null; - this.envMap = null; - this.envMapIntensity = 1.0; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; - this.flatShading = false; - this.fog = true; - this.setValues(parameters); - } + const textures = renderTarget.isWebGLMultipleRenderTargets ? renderTarget.texture : [ renderTarget.texture ]; + const width = renderTarget.width; + const height = renderTarget.height; + let mask = _gl.COLOR_BUFFER_BIT; + const invalidationArray = []; + const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; + const renderTargetProperties = properties.get( renderTarget ); + const isMultipleRenderTargets = ( renderTarget.isWebGLMultipleRenderTargets === true ); - copy(source) { - super.copy(source); - this.defines = { - 'STANDARD': '' - }; - this.color.copy(source.color); - this.roughness = source.roughness; - this.metalness = source.metalness; - this.map = source.map; - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; - this.emissive.copy(source.emissive); - this.emissiveMap = source.emissiveMap; - this.emissiveIntensity = source.emissiveIntensity; - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy(source.normalScale); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.roughnessMap = source.roughnessMap; - this.metalnessMap = source.metalnessMap; - this.alphaMap = source.alphaMap; - this.envMap = source.envMap; - this.envMapIntensity = source.envMapIntensity; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; - this.flatShading = source.flatShading; - this.fog = source.fog; - return this; - } + // 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 ); + + } -class MeshPhysicalMaterial extends MeshStandardMaterial { - constructor(parameters) { - super(); - this.isMeshPhysicalMaterial = true; - this.defines = { - 'STANDARD': '', - 'PHYSICAL': '' - }; - this.type = 'MeshPhysicalMaterial'; - this.clearcoatMap = null; - this.clearcoatRoughness = 0.0; - this.clearcoatRoughnessMap = null; - this.clearcoatNormalScale = new Vector2(1, 1); - this.clearcoatNormalMap = null; - this.ior = 1.5; - Object.defineProperty(this, 'reflectivity', { - get: function () { - return clamp(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1); - }, - set: function (reflectivity) { - this.ior = (1 + 0.4 * reflectivity) / (1 - 0.4 * reflectivity); } - }); - this.iridescenceMap = null; - this.iridescenceIOR = 1.3; - this.iridescenceThicknessRange = [100, 400]; - this.iridescenceThicknessMap = null; - this.sheenColor = new Color(0x000000); - this.sheenColorMap = null; - this.sheenRoughness = 1.0; - this.sheenRoughnessMap = null; - this.transmissionMap = null; - this.thickness = 0; - this.thicknessMap = null; - this.attenuationDistance = 0.0; - this.attenuationColor = new Color(1, 1, 1); - this.specularIntensity = 1.0; - this.specularIntensityMap = null; - this.specularColor = new Color(1, 1, 1); - this.specularColorMap = null; - this._sheen = 0.0; - this._clearcoat = 0; - this._iridescence = 0; - this._transmission = 0; - this.setValues(parameters); - } - get sheen() { - return this._sheen; - } + state.bindFramebuffer( _gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer ); + state.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer ); - set sheen(value) { - if (this._sheen > 0 !== value > 0) { - this.version++; - } + for ( let i = 0; i < textures.length; i ++ ) { - this._sheen = value; - } + invalidationArray.push( _gl.COLOR_ATTACHMENT0 + i ); - get clearcoat() { - return this._clearcoat; - } + 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 + 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 ); - set clearcoat(value) { - if (this._clearcoat > 0 !== value > 0) { - this.version++; } - this._clearcoat = value; } - get iridescence() { - return this._iridescence; - } + function getRenderTargetSamples( renderTarget ) { - set iridescence(value) { - if (this._iridescence > 0 !== value > 0) { - this.version++; - } + return Math.min( maxSamples, renderTarget.samples ); - this._iridescence = value; } - get transmission() { - return this._transmission; + function useMultisampledRTT( renderTarget ) { + + const renderTargetProperties = properties.get( renderTarget ); + + return isWebGL2 && renderTarget.samples > 0 && extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true && renderTargetProperties.__useRenderToTexture !== false; + } - set transmission(value) { - if (this._transmission > 0 !== value > 0) { - this.version++; + function updateVideoTexture( texture ) { + + const frame = info.render.frame; + + // Check the last frame we updated the VideoTexture + + if ( _videoTextures.get( texture ) !== frame ) { + + _videoTextures.set( texture, frame ); + texture.update(); + } - this._transmission = value; } - copy(source) { - super.copy(source); - this.defines = { - 'STANDARD': '', - 'PHYSICAL': '' - }; - this.clearcoat = source.clearcoat; - this.clearcoatMap = source.clearcoatMap; - this.clearcoatRoughness = source.clearcoatRoughness; - this.clearcoatRoughnessMap = source.clearcoatRoughnessMap; - this.clearcoatNormalMap = source.clearcoatNormalMap; - this.clearcoatNormalScale.copy(source.clearcoatNormalScale); - this.ior = source.ior; - this.iridescence = source.iridescence; - this.iridescenceMap = source.iridescenceMap; - this.iridescenceIOR = source.iridescenceIOR; - this.iridescenceThicknessRange = [...source.iridescenceThicknessRange]; - this.iridescenceThicknessMap = source.iridescenceThicknessMap; - this.sheen = source.sheen; - this.sheenColor.copy(source.sheenColor); - this.sheenColorMap = source.sheenColorMap; - this.sheenRoughness = source.sheenRoughness; - this.sheenRoughnessMap = source.sheenRoughnessMap; - this.transmission = source.transmission; - this.transmissionMap = source.transmissionMap; - this.thickness = source.thickness; - this.thicknessMap = source.thicknessMap; - this.attenuationDistance = source.attenuationDistance; - this.attenuationColor.copy(source.attenuationColor); - this.specularIntensity = source.specularIntensity; - this.specularIntensityMap = source.specularIntensityMap; - this.specularColor.copy(source.specularColor); - this.specularColorMap = source.specularColorMap; - return this; - } + function verifyColorSpace( texture, image ) { -} + const encoding = texture.encoding; + const format = texture.format; + const type = texture.type; -class MeshPhongMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshPhongMaterial = true; - this.type = 'MeshPhongMaterial'; - this.color = new Color(0xffffff); // diffuse + if ( texture.isCompressedTexture === true || texture.isVideoTexture === true || texture.format === _SRGBAFormat ) return image; - this.specular = new Color(0x111111); - this.shininess = 30; - this.map = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; - this.emissive = new Color(0x000000); - this.emissiveIntensity = 1.0; - this.emissiveMap = null; - this.bumpMap = null; - this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2(1, 1); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.specularMap = null; - this.alphaMap = null; - this.envMap = null; - this.combine = MultiplyOperation; - this.reflectivity = 1; - this.refractionRatio = 0.98; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; - this.flatShading = false; - this.fog = true; - this.setValues(parameters); - } + if ( encoding !== LinearEncoding ) { - copy(source) { - super.copy(source); - this.color.copy(source.color); - this.specular.copy(source.specular); - this.shininess = source.shininess; - this.map = source.map; - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; - this.emissive.copy(source.emissive); - this.emissiveMap = source.emissiveMap; - this.emissiveIntensity = source.emissiveIntensity; - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy(source.normalScale); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.specularMap = source.specularMap; - this.alphaMap = source.alphaMap; - this.envMap = source.envMap; - this.combine = source.combine; - this.reflectivity = source.reflectivity; - this.refractionRatio = source.refractionRatio; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; - this.flatShading = source.flatShading; - this.fog = source.fog; - return this; - } + // sRGB -} + if ( encoding === sRGBEncoding ) { -class MeshToonMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshToonMaterial = true; - this.defines = { - 'TOON': '' + 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.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.' ); + + } + + } + + } else { + + console.error( 'THREE.WebGLTextures: Unsupported texture encoding:', encoding ); + + } + + } + + return image; + + } + + // + + this.allocateTextureUnit = allocateTextureUnit; + this.resetTextureUnits = resetTextureUnits; + + this.setTexture2D = setTexture2D; + this.setTexture2DArray = setTexture2DArray; + this.setTexture3D = setTexture3D; + this.setTextureCube = setTextureCube; + this.rebindTextures = rebindTextures; + this.setupRenderTarget = setupRenderTarget; + this.updateRenderTargetMipmap = updateRenderTargetMipmap; + this.updateMultisampleRenderTarget = updateMultisampleRenderTarget; + this.setupDepthRenderbuffer = setupDepthRenderbuffer; + this.setupFrameBufferTexture = setupFrameBufferTexture; + this.useMultisampledRTT = useMultisampledRTT; + +} + +function WebGLUtils( gl, extensions, capabilities ) { + + const isWebGL2 = capabilities.isWebGL2; + + function convert( p, encoding = null ) { + + let extension; + + if ( p === UnsignedByteType ) return gl.UNSIGNED_BYTE; + if ( p === UnsignedShort4444Type ) return gl.UNSIGNED_SHORT_4_4_4_4; + if ( p === UnsignedShort5551Type ) return gl.UNSIGNED_SHORT_5_5_5_1; + + if ( p === ByteType ) return gl.BYTE; + if ( p === ShortType ) return gl.SHORT; + if ( p === UnsignedShortType ) return gl.UNSIGNED_SHORT; + 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; + + // 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. + + 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 === 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; + if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + + } else { + + return null; + + } + + } 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; + if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; + if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; + + } else { + + return null; + + } + + } + + } + + // 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; + if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + + } else { + + return null; + + } + + } + + // 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 + + 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 + + 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; + if ( p === RGBA_ASTC_5x5_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR; + if ( p === RGBA_ASTC_6x5_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR; + if ( p === RGBA_ASTC_6x6_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR; + if ( p === RGBA_ASTC_8x5_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR; + if ( p === RGBA_ASTC_8x6_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR; + if ( p === RGBA_ASTC_8x8_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR; + if ( p === RGBA_ASTC_10x5_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR; + if ( p === RGBA_ASTC_10x6_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR; + if ( p === RGBA_ASTC_10x8_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR; + if ( p === RGBA_ASTC_10x10_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR; + if ( p === RGBA_ASTC_12x10_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR; + if ( p === RGBA_ASTC_12x12_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR; + + } else { + + return null; + + } + + } + + // 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; + + } + + } + + // RGTC + + if ( p === RED_RGTC1_Format || p === SIGNED_RED_RGTC1_Format || p === RED_GREEN_RGTC2_Format || p === SIGNED_RED_GREEN_RGTC2_Format ) { + + extension = extensions.get( 'EXT_texture_compression_rgtc' ); + + if ( extension !== null ) { + + if ( p === RGBA_BPTC_Format ) return extension.COMPRESSED_RED_RGTC1_EXT; + if ( p === SIGNED_RED_RGTC1_Format ) return extension.COMPRESSED_SIGNED_RED_RGTC1_EXT; + if ( p === RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_RED_GREEN_RGTC2_EXT; + if ( p === SIGNED_RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_SIGNED_RED_GREEN_RGTC2_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) + + return ( gl[ p ] !== undefined ) ? gl[ p ] : null; + + } + + return { convert: convert }; + +} + +class ArrayCamera extends PerspectiveCamera { + + constructor( array = [] ) { + + super(); + + this.isArrayCamera = true; + + this.cameras = array; + + } + +} + +class Group extends Object3D { + + constructor() { + + super(); + + 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(); + this._hand.matrixAutoUpdate = false; + this._hand.visible = false; + + this._hand.joints = {}; + this._hand.inputState = { pinching: false }; + + } + + return this._hand; + + } + + getTargetRaySpace() { + + if ( this._targetRay === null ) { + + this._targetRay = new Group(); + this._targetRay.matrixAutoUpdate = false; + this._targetRay.visible = false; + this._targetRay.hasLinearVelocity = false; + this._targetRay.linearVelocity = new Vector3(); + this._targetRay.hasAngularVelocity = false; + this._targetRay.angularVelocity = new Vector3(); + + } + + return this._targetRay; + + } + + getGripSpace() { + + if ( this._grip === null ) { + + this._grip = new Group(); + this._grip.matrixAutoUpdate = false; + this._grip.visible = false; + this._grip.hasLinearVelocity = false; + this._grip.linearVelocity = new Vector3(); + 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; + let handPose = null; + + 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 ); + + // 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 + 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( { + type: 'pinchend', + handedness: inputSource.handedness, + target: this + } ); + + } else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) { + + hand.inputState.pinching = true; + this.dispatchEvent( { + type: 'pinchstart', + handedness: inputSource.handedness, + target: this + } ); + + } + + } else { + + if ( 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 ); + + } else { + + grip.hasAngularVelocity = false; + + } + + } + + } + + } + + 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 + 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 ); + + this.isDepthTexture = true; + + this.image = { width: width, height: height }; + + this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; + this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; + + this.flipY = false; + this.generateMipmaps = false; + + } + + +} + +class WebXRManager extends EventDispatcher { + + constructor( renderer, gl ) { + + super(); + + const scope = this; + + let session = null; + let framebufferScaleFactor = 1.0; + + let referenceSpace = null; + let referenceSpaceType = 'local-floor'; + // Set default foveation to maximum. + let foveation = 1.0; + let customReferenceSpace = null; + + let pose = null; + let glBinding = null; + let glProjLayer = null; + let glBaseLayer = null; + let xrFrame = null; + const attributes = gl.getContextAttributes(); + let initialRenderTarget = null; + let newRenderTarget = null; + + const controllers = []; + const controllerInputSources = []; + + const planes = new Set(); + const planesLastChangedTimes = new Map(); + + // + + const cameraL = new PerspectiveCamera(); + cameraL.layers.enable( 1 ); + cameraL.viewport = new Vector4(); + + const cameraR = new PerspectiveCamera(); + cameraR.layers.enable( 2 ); + cameraR.viewport = new Vector4(); + + const cameras = [ cameraL, cameraR ]; + + const cameraVR = new ArrayCamera(); + cameraVR.layers.enable( 1 ); + cameraVR.layers.enable( 2 ); + + let _currentDepthNear = 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, data: event.inputSource } ); + + } + + } + + function onSessionEnd() { + + session.removeEventListener( 'select', onSessionEvent ); + session.removeEventListener( 'selectstart', onSessionEvent ); + session.removeEventListener( 'selectend', onSessionEvent ); + session.removeEventListener( 'squeeze', onSessionEvent ); + session.removeEventListener( 'squeezestart', onSessionEvent ); + 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 + + renderer.setRenderTarget( initialRenderTarget ); + + glBaseLayer = null; + glProjLayer = null; + glBinding = null; + session = null; + newRenderTarget = null; + + // + + animation.stop(); + + scope.isPresenting = false; + + scope.dispatchEvent( { 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 ); + session.addEventListener( 'selectstart', onSessionEvent ); + session.addEventListener( 'selectend', onSessionEvent ); + session.addEventListener( 'squeeze', onSessionEvent ); + session.addEventListener( 'squeezestart', onSessionEvent ); + 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, + alpha: attributes.alpha, + depth: attributes.depth, + stencil: attributes.stencil, + framebufferScaleFactor: framebufferScaleFactor + }; + + glBaseLayer = new XRWebGLLayer( session, gl, layerInit ); + + session.updateRenderState( { baseLayer: glBaseLayer } ); + + newRenderTarget = new WebGLRenderTarget( + glBaseLayer.framebufferWidth, + glBaseLayer.framebufferHeight, + { + format: RGBAFormat, + type: UnsignedByteType, + 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, + scaleFactor: framebufferScaleFactor + }; + + glBinding = new XRWebGLBinding( session, gl ); + + glProjLayer = glBinding.createProjectionLayer( projectionlayerInit ); + + session.updateRenderState( { layers: [ glProjLayer ] } ); + + newRenderTarget = new WebGLRenderTarget( + glProjLayer.textureWidth, + glProjLayer.textureHeight, + { + format: RGBAFormat, + type: UnsignedByteType, + depthTexture: new DepthTexture( glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat ), + stencilBuffer: attributes.stencil, + encoding: renderer.outputEncoding, + samples: attributes.antialias ? 4 : 0 + } ); + + const renderTargetProperties = renderer.properties.get( newRenderTarget ); + renderTargetProperties.__ignoreDepthValues = glProjLayer.ignoreDepthValues; + + } + + newRenderTarget.isXRRenderTarget = true; // TODO Remove this when possible, see #23278 + + this.setFoveation( foveation ); + + customReferenceSpace = null; + referenceSpace = await session.requestReferenceSpace( referenceSpaceType ); + + animation.setContext( session ); + animation.start(); + + scope.isPresenting = true; + + scope.dispatchEvent( { type: 'sessionstart' } ); + + } + + }; + + 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 ].disconnect( inputSource ); + + } + + } + + // 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 ); + controllerIndex = i; + break; + + } else if ( controllerInputSources[ i ] === null ) { + + controllerInputSources[ i ] = inputSource; + controllerIndex = i; + break; + + } + + } + + // If all controllers do currently receive input we ignore new ones + + if ( controllerIndex === - 1 ) break; + + } + + const controller = controllers[ controllerIndex ]; + + if ( controller ) { + + 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 + // 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 ]; + const bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ]; + + 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 zOffset = ipd / ( - leftFov + rightFov ); + 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 + // 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; + const right2 = right + ( ipd - xOffset ); + const top2 = topFov * far / far2 * near2; + 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 + } ); + + _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 ); + + // update user camera and its children + + camera.matrix.copy( cameraVR.matrix ); + 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 + + 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 && glBaseLayer === null ) { + + return undefined; + + } + + return foveation; + + }; + + this.setFoveation = function ( value ) { + + // 0 = no foveation = full resolution + // 1 = maximum foveation = the edges render at lower resolution + + foveation = value; + + if ( glProjLayer !== null ) { + + glProjLayer.fixedFoveation = value; + + } + + if ( glBaseLayer !== null && glBaseLayer.fixedFoveation !== undefined ) { + + glBaseLayer.fixedFoveation = value; + + } + + }; + + 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; + + // 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. + 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 ) { + + fog.color.getRGB( uniforms.fogColor.value, getUnlitUniformColorSpace( renderer ) ); + + if ( fog.isFog ) { + + uniforms.fogNear.value = fog.near; + uniforms.fogFar.value = fog.far; + + } else if ( fog.isFogExp2 ) { + + uniforms.fogDensity.value = fog.density; + + } + + } + + function refreshMaterialUniforms( uniforms, material, pixelRatio, height, transmissionRenderTarget ) { + + if ( material.isMeshBasicMaterial ) { + + refreshUniformsCommon( uniforms, material ); + + } else if ( material.isMeshLambertMaterial ) { + + refreshUniformsCommon( uniforms, material ); + + } else if ( material.isMeshToonMaterial ) { + + refreshUniformsCommon( uniforms, material ); + refreshUniformsToon( uniforms, material ); + + } else if ( material.isMeshPhongMaterial ) { + + refreshUniformsCommon( uniforms, material ); + refreshUniformsPhong( uniforms, material ); + + } else if ( material.isMeshStandardMaterial ) { + + refreshUniformsCommon( uniforms, material ); + refreshUniformsStandard( uniforms, material ); + + if ( material.isMeshPhysicalMaterial ) { + + refreshUniformsPhysical( uniforms, material, transmissionRenderTarget ); + + } + + } else if ( material.isMeshMatcapMaterial ) { + + refreshUniformsCommon( uniforms, material ); + refreshUniformsMatcap( uniforms, material ); + + } else if ( material.isMeshDepthMaterial ) { + + refreshUniformsCommon( uniforms, material ); + + } else if ( material.isMeshDistanceMaterial ) { + + refreshUniformsCommon( uniforms, material ); + refreshUniformsDistance( uniforms, material ); + + } else if ( material.isMeshNormalMaterial ) { + + refreshUniformsCommon( uniforms, material ); + + } else if ( material.isLineBasicMaterial ) { + + refreshUniformsLine( uniforms, material ); + + if ( material.isLineDashedMaterial ) { + + refreshUniformsDash( uniforms, material ); + + } + + } else if ( material.isPointsMaterial ) { + + refreshUniformsPoints( uniforms, material, pixelRatio, height ); + + } else if ( material.isSpriteMaterial ) { + + refreshUniformsSprites( uniforms, material ); + + } else if ( material.isShadowMaterial ) { + + uniforms.color.value.copy( material.color ); + uniforms.opacity.value = material.opacity; + + } else if ( material.isShaderMaterial ) { + + material.uniformsNeedUpdate = false; // #15581 + + } + + } + + 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; + + uniforms.reflectivity.value = material.reflectivity; + uniforms.ior.value = material.ior; + uniforms.refractionRatio.value = material.refractionRatio; + + } + + if ( material.lightMap ) { + + 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 + // 1. color map + // 2. specular map + // 3. displacementMap map + // 4. normal map + // 5. bump map + // 6. roughnessMap map + // 7. metalnessMap map + // 8. alphaMap map + // 9. emissiveMap map + // 10. clearcoat map + // 11. clearcoat normal map + // 12. clearcoat roughnessMap map + // 13. iridescence map + // 14. iridescence thickness map + // 15. specular intensity map + // 16. specular tint map + // 17. transmission map + // 18. thickness map + + let uvScaleMap; + + if ( material.map ) { + + uvScaleMap = material.map; + + } else if ( material.specularMap ) { + + uvScaleMap = material.specularMap; + + } else if ( material.displacementMap ) { + + uvScaleMap = material.displacementMap; + + } else if ( material.normalMap ) { + + uvScaleMap = material.normalMap; + + } else if ( material.bumpMap ) { + + uvScaleMap = material.bumpMap; + + } else if ( material.roughnessMap ) { + + uvScaleMap = material.roughnessMap; + + } else if ( material.metalnessMap ) { + + uvScaleMap = material.metalnessMap; + + } else if ( material.alphaMap ) { + + uvScaleMap = material.alphaMap; + + } else if ( material.emissiveMap ) { + + uvScaleMap = material.emissiveMap; + + } else if ( material.clearcoatMap ) { + + uvScaleMap = material.clearcoatMap; + + } else if ( material.clearcoatNormalMap ) { + + uvScaleMap = material.clearcoatNormalMap; + + } else if ( material.clearcoatRoughnessMap ) { + + uvScaleMap = material.clearcoatRoughnessMap; + + } else if ( material.iridescenceMap ) { + + uvScaleMap = material.iridescenceMap; + + } else if ( material.iridescenceThicknessMap ) { + + uvScaleMap = material.iridescenceThicknessMap; + + } else if ( material.specularIntensityMap ) { + + uvScaleMap = material.specularIntensityMap; + + } else if ( material.specularColorMap ) { + + uvScaleMap = material.specularColorMap; + + } else if ( material.transmissionMap ) { + + uvScaleMap = material.transmissionMap; + + } else if ( material.thicknessMap ) { + + uvScaleMap = material.thicknessMap; + + } else if ( material.sheenColorMap ) { + + uvScaleMap = material.sheenColorMap; + + } 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 + // 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 + // 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 + // 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 ) + + } + + function refreshUniformsToon( uniforms, material ) { + + if ( material.gradientMap ) { + + 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 + }; + +} + +function WebGLUniformsGroups( gl, info, capabilities, state ) { + + let buffers = {}; + let updateList = {}; + let allocatedBindingPoints = []; + + const maxBindingPoints = ( capabilities.isWebGL2 ) ? gl.getParameter( gl.MAX_UNIFORM_BUFFER_BINDINGS ) : 0; // binding points are global whereas block indices are per shader program + + function bind( uniformsGroup, program ) { + + 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 + + const webglProgram = program.program; + state.updateUBOMapping( uniformsGroup, webglProgram ); + + // 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(); + const size = uniformsGroup.__size; + const usage = uniformsGroup.usage; + + gl.bindBuffer( gl.UNIFORM_BUFFER, buffer ); + gl.bufferData( gl.UNIFORM_BUFFER, size, usage ); + gl.bindBuffer( gl.UNIFORM_BUFFER, null ); + gl.bindBufferBase( gl.UNIFORM_BUFFER, bindingPointIndex, buffer ); + + return buffer; + + } + + function allocateBindingPointIndex() { + + for ( let i = 0; i < maxBindingPoints; i ++ ) { + + if ( allocatedBindingPoints.indexOf( i ) === - 1 ) { + + allocatedBindingPoints.push( i ); + 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 + + if ( hasUniformChanged( uniform, i, cache ) === true ) { + + const offset = uniform.__offset; + + const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ]; + + let arrayOffset = 0; + + for ( let i = 0; i < values.length; i ++ ) { + + const value = values[ i ]; + + const info = getUniformSize( value ); + + if ( typeof value === 'number' ) { + + uniform.__data[ 0 ] = value; + gl.bufferSubData( gl.UNIFORM_BUFFER, offset + arrayOffset, uniform.__data ); + + } else if ( value.isMatrix3 ) { + + // manually converting 3x3 to 3x4 + + uniform.__data[ 0 ] = value.elements[ 0 ]; + uniform.__data[ 1 ] = value.elements[ 1 ]; + uniform.__data[ 2 ] = value.elements[ 2 ]; + uniform.__data[ 3 ] = value.elements[ 0 ]; + uniform.__data[ 4 ] = value.elements[ 3 ]; + uniform.__data[ 5 ] = value.elements[ 4 ]; + uniform.__data[ 6 ] = value.elements[ 5 ]; + uniform.__data[ 7 ] = value.elements[ 0 ]; + uniform.__data[ 8 ] = value.elements[ 6 ]; + uniform.__data[ 9 ] = value.elements[ 7 ]; + uniform.__data[ 10 ] = value.elements[ 8 ]; + uniform.__data[ 11 ] = value.elements[ 0 ]; + + } else { + + value.toArray( uniform.__data, arrayOffset ); + + arrayOffset += info.storage / Float32Array.BYTES_PER_ELEMENT; + + } + + } + + 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 { + + const values = Array.isArray( value ) ? value : [ value ]; + + const tempValues = []; + + for ( let i = 0; i < values.length; i ++ ) { + + tempValues.push( values[ i ].clone() ); + + } + + cache[ index ] = tempValues; + + } + + return true; + + } else { + + // compare current value with cached entry + + if ( typeof value === 'number' ) { + + if ( cache[ index ] !== value ) { + + cache[ index ] = value; + return true; + + } + + } else { + + const cachedObjects = Array.isArray( cache[ index ] ) ? cache[ index ] : [ cache[ index ] ]; + const values = Array.isArray( value ) ? value : [ value ]; + + for ( let i = 0; i < cachedObjects.length; i ++ ) { + + const cachedObject = cachedObjects[ i ]; + + if ( cachedObject.equals( values[ i ] ) === false ) { + + cachedObject.copy( values[ i ] ); + 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 infos = { + boundary: 0, // bytes + storage: 0 // bytes + }; + + const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ]; + + for ( let j = 0, jl = values.length; j < jl; j ++ ) { + + const value = values[ j ]; + + const info = getUniformSize( value ); + + infos.boundary += info.boundary; + infos.storage += info.storage; + + } + + // the following two properties will be used for partial buffer updates + + uniform.__data = new Float32Array( infos.storage / Float32Array.BYTES_PER_ELEMENT ); + uniform.__offset = offset; + + // + + if ( i > 0 ) { + + chunkOffset = offset % chunkSize; + + const remainingSizeInChunk = chunkSize - chunkOffset; + + // check for chunk overflow + + if ( chunkOffset !== 0 && ( remainingSizeInChunk - infos.boundary ) < 0 ) { + + // add padding and adjust offset + + offset += ( chunkSize - chunkOffset ); + uniform.__offset = offset; + + } + + } + + offset += infos.storage; + + } + + // ensure correct final padding + + chunkOffset = offset % chunkSize; + + if ( chunkOffset > 0 ) offset += ( chunkSize - chunkOffset ); + + // + + uniformsGroup.__size = offset; + uniformsGroup.__cache = {}; + + return this; + + } + + function getUniformSize( value ) { + + const info = { + boundary: 0, // bytes + storage: 0 // bytes + }; + + // 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 ) { + + console.warn( 'THREE.WebGLRenderer: Texture samplers can not be part of an uniforms group.' ); + + } else { + + console.warn( 'THREE.WebGLRenderer: Unsupported uniform value type.', value ); + + } + + return info; + + } + + function onUniformsGroupsDispose( event ) { + + const uniformsGroup = event.target; + + uniformsGroup.removeEventListener( 'dispose', onUniformsGroupsDispose ); + + const index = allocatedBindingPoints.indexOf( uniformsGroup.__bindingPointIndex ); + allocatedBindingPoints.splice( index, 1 ); + + gl.deleteBuffer( buffers[ uniformsGroup.id ] ); + + 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, + + dispose: dispose + + }; + +} + +function createCanvasElement() { + + const canvas = createElementNS( 'canvas' ); + 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; + + 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. + // 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 + + this.domElement = _canvas; + + // Debug configuration container + this.debug = { + + /** + * Enables error checking and reporting when shader programs are being compiled + * @type {boolean} + */ + checkShaderErrors: true + }; + + // clearing + + this.autoClear = true; + this.autoClearColor = true; + this.autoClearDepth = true; + this.autoClearStencil = true; + + // scene graph + + this.sortObjects = true; + + // user-defined clipping + + this.clippingPlanes = []; + this.localClippingEnabled = false; + + // physically based shading + + this.outputEncoding = LinearEncoding; + + // physical lights + + this.physicallyCorrectLights = false; + + // tone mapping + + this.toneMapping = NoToneMapping; + this.toneMappingExposure = 1.0; + + // internal properties + + const _this = this; + + let _isContextLost = false; + + // 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 _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; + + // frustum + + const _frustum = new Frustum(); + + // clipping + + let _clippingEnabled = false; + let _localClippingEnabled = false; + + // transmission + + let _transmissionRenderTarget = null; + + // camera matrices cache + + const _projScreenMatrix = new Matrix4(); + + const _vector2 = new Vector2(); + const _vector3 = new Vector3(); + + const _emptyScene = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: true }; + + function getTargetPixelRatio() { + + return _currentRenderTarget === null ? _pixelRatio : 1; + + } + + // 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, + depth: _depth, + stencil: _stencil, + antialias: _antialias, + premultipliedAlpha: _premultipliedAlpha, + 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 + _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.' ); + + } else { + + throw new Error( 'Error creating WebGL context.' ); + + } + + } + + } + + // Some experimental-webgl implementations do not have getShaderPrecisionFormat + + if ( _gl.getShaderPrecisionFormat === undefined ) { + + _gl.getShaderPrecisionFormat = function () { + + return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 }; + + }; + + } + + } catch ( error ) { + + console.error( 'THREE.WebGLRenderer: ' + error.message ); + throw error; + + } + + 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 ); + + extensions.init( capabilities ); + + utils = new WebGLUtils( _gl, extensions, capabilities ); + + state = new WebGLState( _gl, extensions, capabilities ); + + info = new WebGLInfo( _gl ); + properties = new WebGLProperties(); + textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ); + cubemaps = new WebGLCubeMaps( _this ); + cubeuvmaps = new WebGLCubeUVMaps( _this ); + attributes = new WebGLAttributes( _gl, capabilities ); + bindingStates = new WebGLBindingStates( _gl, extensions, attributes, capabilities ); + geometries = new WebGLGeometries( _gl, attributes, info, bindingStates ); + objects = new WebGLObjects( _gl, geometries, attributes, info ); + morphtargets = new WebGLMorphtargets( _gl, capabilities, textures ); + clipping = new WebGLClipping( properties ); + programCache = new WebGLPrograms( _this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping ); + materials = new WebGLMaterials( _this, properties ); + renderLists = new WebGLRenderLists(); + renderStates = new WebGLRenderStates( extensions, capabilities ); + 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 ); + indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities ); + + info.programs = programCache.programs; + + _this.capabilities = capabilities; + _this.extensions = extensions; + _this.properties = properties; + _this.renderLists = renderLists; + _this.shadowMap = shadowMap; + _this.state = state; + _this.info = info; + + } + + initGLContext(); + + // xr + + const xr = new WebXRManager( _this, _gl ); + + 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; + + _pixelRatio = pixelRatio; + + _canvas.width = Math.floor( width * pixelRatio ); + _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 + + 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(); + cubemaps.dispose(); + cubeuvmaps.dispose(); + objects.dispose(); + bindingStates.dispose(); + uniformsGroups.dispose(); + programCache.dispose(); + + xr.dispose(); + + xr.removeEventListener( 'sessionstart', onXRSessionStart ); + xr.removeEventListener( 'sessionend', onXRSessionEnd ); + + if ( _transmissionRenderTarget ) { + + _transmissionRenderTarget.dispose(); + _transmissionRenderTarget = null; + + } + + animation.stop(); + + }; + + // Events + + function onContextLost( event ) { + + event.preventDefault(); + + console.log( 'THREE.WebGLRenderer: Context Lost.' ); + + _isContextLost = true; + + } + + function onContextRestore( /* event */ ) { + + console.log( 'THREE.WebGLRenderer: Context Restored.' ); + + _isContextLost = false; + + const infoAutoReset = info.autoReset; + const shadowMapEnabled = shadowMap.enabled; + const shadowMapAutoUpdate = shadowMap.autoUpdate; + const shadowMapNeedsUpdate = shadowMap.needsUpdate; + const shadowMapType = shadowMap.type; + + initGLContext(); + + info.autoReset = infoAutoReset; + shadowMap.enabled = shadowMapEnabled; + shadowMap.autoUpdate = shadowMapAutoUpdate; + 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 + + 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 + + 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; + 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 ); + + } + + // + + if ( object.isMesh ) { + + if ( material.wireframe === true ) { + + state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() ); + renderer.setMode( _gl.LINES ); + + } else { + + renderer.setMode( _gl.TRIANGLES ); + + } + + } else if ( object.isLine ) { + + let lineWidth = material.linewidth; + + if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material + + state.setLineWidth( lineWidth * getTargetPixelRatio() ); + + if ( object.isLineSegments ) { + + renderer.setMode( _gl.LINES ); + + } else if ( object.isLineLoop ) { + + renderer.setMode( _gl.LINE_LOOP ); + + } else { + + renderer.setMode( _gl.LINE_STRIP ); + + } + + } else if ( object.isPoints ) { + + renderer.setMode( _gl.POINTS ); + + } else if ( object.isSprite ) { + + renderer.setMode( _gl.TRIANGLES ); + + } + + if ( object.isInstancedMesh ) { + + renderer.renderInstances( drawStart, drawCount, object.count ); + + } else if ( geometry.isInstancedBufferGeometry ) { + + 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 + + this.compile = function ( scene, camera ) { + + function prepare( material, scene, object ) { + + if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) { + + 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 ); + + } + + } + + } ); + + 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 ]; + + prepare( material2, scene, object ); + + } + + } else { + + prepare( material, scene, object ); + + } + + } + + } ); + + renderStateStack.pop(); + currentRenderState = null; + + }; + + // 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 + + 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; + + // update scene graph + + if ( scene.matrixWorldAutoUpdate === true ) scene.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 ); + + currentRenderList = renderLists.get( scene, renderListStack.length ); + currentRenderList.init(); + + 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 ( this.info.autoReset === true ) this.info.reset(); + + // + + 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.updateRenderTargetMipmap( _currentRenderTarget ); + + } + + // + + if ( scene.isScene === true ) scene.onAfterRender( _this, scene, camera ); + + // _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; + + } else if ( object.isLOD ) { + + if ( object.autoUpdate === true ) object.update( camera ); + + } else if ( object.isLight ) { + + currentRenderState.pushLight( object ); + + if ( object.castShadow ) { + + currentRenderState.pushShadow( object ); + + } + + } else if ( object.isSprite ) { + + if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) { + + 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 ); + + } + + } + + } 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 ); + + } + + } + + } else if ( material.visible ) { + + currentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null ); + + } + + } + + } + + } + + 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; + const transparentObjects = currentRenderList.transparent; + + currentRenderState.setupLightsView( camera ); + + if ( _clippingEnabled === true ) clipping.setGlobalState( _this.clippingPlanes, camera ); + + if ( transmissiveObjects.length > 0 ) renderTransmissionPass( opaqueObjects, scene, camera ); + + 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 + + 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, + type: extensions.has( 'EXT_color_buffer_half_float' ) ? HalfFloatType : UnsignedByteType, + minFilter: LinearMipmapLinearFilter, + 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(); + + // 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.forceSinglePass === false ) { + + 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, ... + + const materialProperties = properties.get( material ); + + const lights = currentRenderState.state.lights; + const shadowsArray = currentRenderState.state.shadowsArray; + + 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 + + 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; + + } + + } else { + + parameters.uniforms = programCache.getUniforms( material ); + + material.onBuild( object, parameters, _this ); + + material.onBeforeCompile( parameters, _this ); + + program = programCache.acquireProgram( parameters, programCacheKey ); + 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 ); + + // store the light setup it was created for + + materialProperties.needsLights = materialNeedsLights( material ); + materialProperties.lightsStateVersion = lightsStateVersion; + + if ( materialProperties.needsLights ) { + + // wire up the material to this renderer's lighting state + + uniforms.ambientLightColor.value = lights.state.ambient; + uniforms.lightProbe.value = lights.state.probe; + uniforms.directionalLights.value = lights.state.directional; + uniforms.directionalLightShadows.value = lights.state.directionalShadow; + uniforms.spotLights.value = lights.state.spot; + uniforms.spotLightShadows.value = lights.state.spotShadow; + uniforms.rectAreaLights.value = lights.state.rectArea; + uniforms.ltc_1.value = lights.state.rectAreaLTC1; + uniforms.ltc_2.value = lights.state.rectAreaLTC2; + uniforms.pointLights.value = lights.state.point; + uniforms.pointLightShadows.value = lights.state.pointShadow; + uniforms.hemisphereLights.value = lights.state.hemi; + + uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; + uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix; + uniforms.spotShadowMap.value = lights.state.spotShadowMap; + uniforms.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 + + } + + const progUniforms = program.getUniforms(); + const uniformsList = WebGLUniforms.seqWithValue( progUniforms.seq, uniforms ); + + materialProperties.currentProgram = program; + materialProperties.uniformsList = uniformsList; + + return program; + + } + + function updateCommonMaterialProperties( material, parameters ) { + + const materialProperties = properties.get( material ); + + materialProperties.outputEncoding = parameters.outputEncoding; + materialProperties.instancing = parameters.instancing; + materialProperties.skinning = parameters.skinning; + materialProperties.morphTargets = parameters.morphTargets; + materialProperties.morphNormals = parameters.morphNormals; + materialProperties.morphColors = parameters.morphColors; + materialProperties.morphTargetsCount = parameters.morphTargetsCount; + materialProperties.numClippingPlanes = parameters.numClippingPlanes; + materialProperties.numIntersection = parameters.numClipIntersection; + materialProperties.vertexAlphas = parameters.vertexAlphas; + 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, ... + + textures.resetTextureUnits(); + + const fog = scene.fog; + const environment = material.isMeshStandardMaterial ? scene.environment : null; + const encoding = ( _currentRenderTarget === null ) ? _this.outputEncoding : ( _currentRenderTarget.isXRRenderTarget === true ? _currentRenderTarget.texture.encoding : LinearEncoding ); + const envMap = ( material.isMeshStandardMaterial ? cubeuvmaps : cubemaps ).get( material.envMap || environment ); + const vertexAlphas = material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4; + const vertexTangents = !! material.normalMap && !! geometry.attributes.tangent; + const morphTargets = !! geometry.morphAttributes.position; + const morphNormals = !! geometry.morphAttributes.normal; + const morphColors = !! geometry.morphAttributes.color; + const toneMapping = material.toneMapped ? _this.toneMapping : NoToneMapping; + + const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; + 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 + // 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; + + } else if ( materialProperties.outputEncoding !== encoding ) { + + needsProgramChange = true; + + } else if ( object.isInstancedMesh && materialProperties.instancing === false ) { + + needsProgramChange = true; + + } else if ( ! object.isInstancedMesh && materialProperties.instancing === true ) { + + needsProgramChange = true; + + } else if ( object.isSkinnedMesh && materialProperties.skinning === false ) { + + needsProgramChange = true; + + } else if ( ! object.isSkinnedMesh && materialProperties.skinning === true ) { + + needsProgramChange = true; + + } else if ( materialProperties.envMap !== envMap ) { + + needsProgramChange = true; + + } else if ( material.fog === true && materialProperties.fog !== fog ) { + + needsProgramChange = true; + + } else if ( materialProperties.numClippingPlanes !== undefined && + ( materialProperties.numClippingPlanes !== clipping.numPlanes || + materialProperties.numIntersection !== clipping.numIntersection ) ) { + + needsProgramChange = true; + + } else if ( materialProperties.vertexAlphas !== vertexAlphas ) { + + needsProgramChange = true; + + } else if ( materialProperties.vertexTangents !== vertexTangents ) { + + needsProgramChange = true; + + } else if ( materialProperties.morphTargets !== morphTargets ) { + + needsProgramChange = true; + + } else if ( materialProperties.morphNormals !== morphNormals ) { + + needsProgramChange = true; + + } else if ( materialProperties.morphColors !== morphColors ) { + + needsProgramChange = true; + + } else if ( materialProperties.toneMapping !== toneMapping ) { + + needsProgramChange = true; + + } else if ( capabilities.isWebGL2 === true && materialProperties.morphTargetsCount !== morphTargetsCount ) { + + needsProgramChange = true; + + } + + } 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; + + 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 + // 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) + + 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 + // 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(); + + p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture, textures ); + p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize ); + + } else { + + console.warn( 'THREE.WebGLRenderer: SkinnedMesh can only be used with WebGL 2. With WebGL 1 OES_texture_float and vertex textures support is required.' ); + + } + + } + + } + + 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 + + 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 + + p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix ); + p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix ); + 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 ]; + + uniformsGroups.update( group, program ); + uniformsGroups.bind( group, program ); + + } else { + + console.warn( 'THREE.WebGLRenderer: Uniform Buffer Objects can only be used with WebGL 2.' ); + + } + + } + + } + + return program; + + } + + // If uniforms are marked as clean, they don't need to be loaded to the GPU. + + function markUniformsLightsNeedsUpdate( uniforms, value ) { + + uniforms.ambientLightColor.needsUpdate = value; + uniforms.lightProbe.needsUpdate = value; + + uniforms.directionalLights.needsUpdate = value; + uniforms.directionalLightShadows.needsUpdate = value; + uniforms.pointLights.needsUpdate = value; + uniforms.pointLightShadows.needsUpdate = value; + uniforms.spotLights.needsUpdate = value; + uniforms.spotLightShadows.needsUpdate = value; + uniforms.rectAreaLights.needsUpdate = value; + uniforms.hemisphereLights.needsUpdate = value; + + } + + function materialNeedsLights( material ) { + + return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || + material.isMeshStandardMaterial || material.isShadowMaterial || + ( material.isShaderMaterial && material.lights === true ); + + } + + 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. + if ( extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true ) { + + console.warn( 'THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided' ); + renderTargetProperties.__useRenderToTexture = false; + + } + + } + + } + + }; + + 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 ); + useDefaultFramebuffer = false; + + } else if ( renderTargetProperties.__webglFramebuffer === undefined ) { + + textures.setupRenderTarget( renderTarget ); + + } else if ( renderTargetProperties.__hasExternalTextures ) { + + // 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 ); + + } + + const texture = renderTarget.texture; + + if ( texture.isData3DTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) { + + isRenderTarget3D = true; + + } + + const __webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer; + + if ( renderTarget.isWebGLCubeRenderTarget ) { + + framebuffer = __webglFramebuffer[ activeCubeFace ]; + isCube = true; + + } else if ( ( capabilities.isWebGL2 && renderTarget.samples > 0 ) && textures.useMultisampledRTT( renderTarget ) === false ) { + + framebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer; + + } 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 + + }; + + this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer, activeCubeFaceIndex ) { + + if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) { + + console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' ); + return; + + } + + 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 + ! 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) + + 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 + _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 { + + if ( srcTexture.isCompressedTexture ) { + + _gl.compressedTexSubImage2D( _gl.TEXTURE_2D, level, position.x, position.y, srcTexture.mipmaps[ 0 ].width, srcTexture.mipmaps[ 0 ].height, glFormat, srcTexture.mipmaps[ 0 ].data ); + + } else { + + _gl.texSubImage2D( _gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image ); + + } + + } + + // 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; + + } else if ( dstTexture.isDataArrayTexture ) { + + textures.setTexture2DArray( dstTexture, 0 ); + glTarget = _gl.TEXTURE_2D_ARRAY; + + } else { + + 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.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 ); + + // 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 || texture.isCompressedArrayTexture ) { + + textures.setTexture2DArray( texture, 0 ); + + } else { + + textures.setTexture2D( texture, 0 ); + + } + + state.unbindTexture(); + + }; + + this.resetState = function () { + + _currentActiveCubeFace = 0; + _currentActiveMipmapLevel = 0; + _currentRenderTarget = null; + + state.reset(); + bindingStates.reset(); + + }; + + if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { + + __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); + + } + +} + +class WebGL1Renderer extends WebGLRenderer {} + +WebGL1Renderer.prototype.isWebGL1Renderer = true; + +class FogExp2 { + + constructor( color, density = 0.00025 ) { + + this.isFogExp2 = true; + + this.name = ''; + + this.color = new Color( color ); + this.density = density; + + } + + clone() { + + return new FogExp2( this.color, this.density ); + + } + + toJSON( /* meta */ ) { + + return { + type: 'FogExp2', + color: this.color.getHex(), + density: this.density + }; + + } + +} + +class Fog { + + constructor( color, near = 1, far = 1000 ) { + + this.isFog = true; + + this.name = ''; + + this.color = new Color( color ); + + this.near = near; + this.far = far; + + } + + clone() { + + return new Fog( this.color, this.near, this.far ); + + } + + toJSON( /* meta */ ) { + + return { + type: 'Fog', + color: this.color.getHex(), + near: this.near, + far: this.far + }; + + } + +} + +class Scene extends Object3D { + + constructor() { + + super(); + + this.isScene = true; + + this.type = 'Scene'; + + this.background = null; + this.environment = null; + this.fog = null; + + this.backgroundBlurriness = 0; + this.backgroundIntensity = 1; + + this.overrideMaterial = null; + + 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.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.object.backgroundBlurriness = this.backgroundBlurriness; + if ( this.backgroundIntensity !== 1 ) data.object.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 { + + constructor( array, stride ) { + + this.isInterleavedBuffer = true; + + this.array = array; + this.stride = stride; + this.count = array !== undefined ? array.length / stride : 0; + + this.usage = StaticDrawUsage; + this.updateRange = { offset: 0, count: - 1 }; + + this.version = 0; + + this.uuid = 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; + this.stride = source.stride; + 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 + + 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, + buffer: this.array.buffer._uuid, + type: this.array.constructor.name, + stride: this.stride + }; + + } + +} + +const _vector$6 = /*@__PURE__*/ new Vector3(); + +class InterleavedBufferAttribute { + + constructor( interleavedBuffer, itemSize, offset, normalized = false ) { + + this.isInterleavedBufferAttribute = true; + + this.name = ''; + + this.data = interleavedBuffer; + this.itemSize = itemSize; + this.offset = offset; + + this.normalized = normalized; + + } + + 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 ) { + + let x = this.data.array[ index * this.data.stride + this.offset ]; + + if ( this.normalized ) x = denormalize( x, this.array ); + + return x; + + } + + getY( index ) { + + let y = this.data.array[ index * this.data.stride + this.offset + 1 ]; + + if ( this.normalized ) y = denormalize( y, this.array ); + + return y; + + } + + getZ( index ) { + + let z = this.data.array[ index * this.data.stride + this.offset + 2 ]; + + if ( this.normalized ) z = denormalize( z, this.array ); + + return z; + + } + + getW( index ) { + + 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 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 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 ] ); + + } + + } + + // de-interleave data and save it as an ordinary buffer attribute for now + + return { + itemSize: this.itemSize, + type: this.array.constructor.name, + array: array, + normalized: this.normalized + }; + + } else { + + // 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, + data: this.data.uuid, + offset: this.offset, + normalized: this.normalized + }; + + } + + } + +} + +class SpriteMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isSpriteMaterial = true; + + this.type = 'SpriteMaterial'; + + this.color = new Color( 0xffffff ); + + this.map = null; + + this.alphaMap = null; + + this.rotation = 0; + + this.sizeAttenuation = true; + + this.transparent = true; + + this.fog = true; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.color.copy( source.color ); + + this.map = source.map; + + this.alphaMap = source.alphaMap; + + this.rotation = source.rotation; + + this.sizeAttenuation = source.sizeAttenuation; + + 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 ); + + // 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( { + + distance: distance, + point: _intersectPoint.clone(), + uv: Triangle.getUV( _intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ), + face: null, + 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 + 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.applyMatrix4( _viewWorldMatrix ); + +} + +const _v1$2 = /*@__PURE__*/ new Vector3(); +const _v2$1 = /*@__PURE__*/ new Vector3(); + +class LOD extends Object3D { + + constructor() { + + super(); + + this._currentLevel = 0; + + this.type = 'LOD'; + + Object.defineProperties( this, { + levels: { + enumerable: true, + value: [] + }, + isLOD: { + value: true, + } + } ); + + 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, level.hysteresis ); + + } + + this.autoUpdate = source.autoUpdate; + + return this; + + } + + 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 ++ ) { + + 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 ++ ) { + + 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, + 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 ); + + this.isSkinnedMesh = true; + + this.type = 'SkinnedMesh'; + + this.bindMode = 'attached'; + this.bindMatrix = new Matrix4(); + this.bindMatrixInverse = new Matrix4(); + + } + + copy( source, recursive ) { + + super.copy( source, recursive ); + + this.bindMode = source.bindMode; + this.bindMatrix.copy( source.bindMatrix ); + this.bindMatrixInverse.copy( source.bindMatrixInverse ); + + 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 { + + vector.set( 1, 0, 0, 0 ); // do something reasonable + + } + + 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' ) { + + this.bindMatrixInverse.copy( this.bindMatrix ).invert(); + + } else { + + 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 { + + constructor() { + + super(); + + this.isBone = true; + + this.type = 'Bone'; + + } + +} + +class DataTexture extends Texture { + + constructor( data = null, width = 1, height = 1, format, type, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, encoding ) { + + super( null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); + + this.isDataTexture = true; + + this.image = { data: data, width: width, height: height }; + + this.generateMipmaps = false; + this.flipY = false; + this.unpackAlignment = 1; + + } + +} + +const _offsetMatrix = /*@__PURE__*/ new Matrix4(); +const _identityMatrix = /*@__PURE__*/ new Matrix4(); + +class Skeleton { + + constructor( bones = [], boneInverses = [] ) { + + this.uuid = generateUUID(); + + this.bones = bones.slice( 0 ); + this.boneInverses = boneInverses; + this.boneMatrices = null; + + this.boneTexture = null; + this.boneTextureSize = 0; + + 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 + + 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 + + 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(); + bone.matrix.multiply( bone.matrixWorld ); + + } 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 + + 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; + + _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) + // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8) + // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16) + // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32) + // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64) + + 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 ); + boneTexture.needsUpdate = true; + + this.boneMatrices = boneMatrices; + this.boneTexture = boneTexture; + 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: { + version: 4.5, + type: 'Skeleton', + generator: 'Skeleton.toJSON' + }, + bones: [], + boneInverses: [] + }; + + 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 ) { + + 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 ); + + this.isInstancedMesh = true; + + this.instanceMatrix = new InstancedBufferAttribute( new Float32Array( count * 16 ), 16 ); + 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 ); + + if ( source.instanceColor !== null ) this.instanceColor = source.instanceColor.clone(); + + 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 + + _mesh.matrixWorld = _instanceWorldMatrix; + + _mesh.raycast( raycaster, _instanceIntersects ); + + // process the result of raycast + + for ( let i = 0, l = _instanceIntersects.length; i < l; i ++ ) { + + const intersect = _instanceIntersects[ i ]; + intersect.instanceId = instanceId; + 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 { + + constructor( parameters ) { + + super(); + + this.isLineBasicMaterial = true; + + this.type = 'LineBasicMaterial'; + + this.color = new Color( 0xffffff ); + + this.linewidth = 1; + this.linecap = 'round'; + this.linejoin = 'round'; + + this.fog = true; + + this.setValues( parameters ); + + } + + + copy( source ) { + + super.copy( source ); + + this.color.copy( source.color ); + + this.linewidth = source.linewidth; + this.linecap = source.linecap; + this.linejoin = source.linejoin; + + 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(); + + this.isLine = true; + + this.type = 'Line'; + + this.geometry = geometry; + 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 + + 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 + + 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; + + // + + _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(); + const vEnd = new Vector3(); + const interSegment = new Vector3(); + const interRay = new Vector3(); + const step = this.isLineSegments ? 2 : 1; + + 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 + + const distance = raycaster.ray.origin.distanceTo( interRay ); + + if ( distance < raycaster.near || distance > raycaster.far ) continue; + + intersects.push( { + + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4( this.matrixWorld ), + index: i, + face: null, + faceIndex: null, + object: this + + } ); + + } + + } else { + + 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 + + const distance = raycaster.ray.origin.distanceTo( interRay ); + + if ( distance < raycaster.near || distance > raycaster.far ) continue; + + intersects.push( { + + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4( this.matrixWorld ), + index: i, + face: null, + faceIndex: null, + object: this + + } ); + + } + + } + + } + + 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 ); + this.morphTargetDictionary[ name ] = m; + + } + + } + + } + + } + +} + +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 + + 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 { + + constructor( geometry, material ) { + + super( geometry, material ); + + this.isLineLoop = true; + + this.type = 'LineLoop'; + + } + +} + +class PointsMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isPointsMaterial = true; + + this.type = 'PointsMaterial'; + + this.color = new Color( 0xffffff ); + + this.map = null; + + this.alphaMap = null; + + this.size = 1; + this.sizeAttenuation = true; + + this.fog = true; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.color.copy( source.color ); + + this.map = source.map; + + this.alphaMap = source.alphaMap; + + this.size = source.size; + this.sizeAttenuation = source.sizeAttenuation; + + 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(); + + this.isPoints = true; + + this.type = 'Points'; + + this.geometry = geometry; + 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 + + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + + _sphere.copy( geometry.boundingSphere ); + _sphere.applyMatrix4( matrixWorld ); + _sphere.radius += threshold; + + if ( raycaster.ray.intersectsSphere( _sphere ) === false ) return; + + // + + _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 ); + this.morphTargetDictionary[ name ] = m; + + } + + } + + } + + } + +} + +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; + + intersects.push( { + + distance: distance, + distanceToRay: Math.sqrt( rayPointDistanceSq ), + point: intersectPoint, + index: index, + face: null, + object: object + + } ); + + } + +} + +class VideoTexture extends Texture { + + constructor( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { + + super( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + + this.isVideoTexture = true; + + this.minFilter = minFilter !== undefined ? minFilter : LinearFilter; + 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 { + + constructor( width, height, format ) { + + super( { width, height } ); + + this.isFramebufferTexture = true; + + this.format = format; + + this.magFilter = NearestFilter; + this.minFilter = NearestFilter; + + this.generateMipmaps = false; + + this.needsUpdate = true; + + } + +} + +class CompressedTexture extends Texture { + + constructor( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { + + super( null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); + + this.isCompressedTexture = true; + + this.image = { width: width, height: height }; + 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 + // 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 { + + constructor( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { + + super( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + + this.isCanvasTexture = true; + + this.needsUpdate = true; + + } + +} + +/** + * Extensible curve object. + * + * Some common of curve methods: + * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget ) + * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget ) + * .getPoints(), .getSpacedPoints() + * .getLength() + * .updateArcLengths() + * + * This following curves inherit from THREE.Curve: + * + * -- 2D curves -- + * THREE.ArcCurve + * THREE.CubicBezierCurve + * THREE.EllipseCurve + * THREE.LineCurve + * THREE.QuadraticBezierCurve + * THREE.SplineCurve + * + * -- 3D curves -- + * THREE.CatmullRomCurve3 + * THREE.CubicBezierCurve3 + * THREE.LineCurve3 + * THREE.QuadraticBezierCurve3 + * + * A series of curves can be represented as a THREE.CurvePath. + * + **/ + +class Curve { + + constructor() { + + this.type = 'Curve'; + + this.arcLengthDivisions = 200; + + } + + // Virtual base class method to overwrite and implement in subclasses + // - t [0 .. 1] + + getPoint( /* t, optionalTarget */ ) { + + console.warn( 'THREE.Curve: .getPoint() not implemented.' ); + return null; + + } + + // Get point at relative position in curve according to arc length + // - u [0 .. 1] + + getPointAt( u, optionalTarget ) { + + const t = this.getUtoTmapping( u ); + return this.getPoint( t, optionalTarget ); + + } + + // 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 ) + + 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 + + getLength() { + + const lengths = this.getLengths(); + return lengths[ lengths.length - 1 ]; + + } + + // 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 ); + 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. + + } + + updateArcLengths() { + + this.needsUpdate = true; + this.getLengths(); + + } + + // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant + + getUtoTmapping( u, distance ) { + + const arcLengths = this.getLengths(); + + let i = 0; + const il = arcLengths.length; + + let targetArcLength; // The targeted u distance value to get + + if ( distance ) { + + targetArcLength = distance; + + } else { + + targetArcLength = u * arcLengths[ il - 1 ]; + + } + + // binary search for the index with largest value smaller than target u distance + + let low = 0, high = il - 1, comparison; + + while ( low <= high ) { + + i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats + + comparison = arcLengths[ i ] - targetArcLength; + + if ( comparison < 0 ) { + + low = i + 1; + + } else if ( comparison > 0 ) { + + high = i - 1; + + } else { + + high = i; + 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 + + const lengthBefore = arcLengths[ i ]; + const lengthAfter = arcLengths[ i + 1 ]; + + const segmentLength = lengthAfter - lengthBefore; + + // 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 + // 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 + + if ( t1 < 0 ) t1 = 0; + if ( t2 > 1 ) t2 = 1; + + const pt1 = this.getPoint( t1 ); + const pt2 = this.getPoint( t2 ); + + const tangent = optionalTarget || ( ( pt1.isVector2 ) ? new Vector2() : new Vector3() ); + + 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 + + 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 + + normals[ 0 ] = new Vector3(); + binormals[ 0 ] = new Vector3(); + let min = Number.MAX_VALUE; + 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 + + 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 ( 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: { + version: 4.5, + type: 'Curve', + generator: 'Curve.toJSON' + } + }; + + data.arcLengthDivisions = this.arcLengthDivisions; + data.type = this.type; + + return data; + + } + + fromJSON( json ) { + + this.arcLengthDivisions = json.arcLengthDivisions; + + return this; + + } + +} + +class EllipseCurve extends Curve { + + constructor( aX = 0, aY = 0, xRadius = 1, yRadius = 1, aStartAngle = 0, aEndAngle = Math.PI * 2, aClockwise = false, aRotation = 0 ) { + + super(); + + this.isEllipseCurve = true; + + this.type = 'EllipseCurve'; + + this.aX = aX; + this.aY = aY; + + this.xRadius = xRadius; + this.yRadius = yRadius; + + this.aStartAngle = aStartAngle; + this.aEndAngle = aEndAngle; + + 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 + while ( deltaAngle < 0 ) deltaAngle += twoPi; + while ( deltaAngle > twoPi ) deltaAngle -= twoPi; + + if ( deltaAngle < Number.EPSILON ) { + + if ( samePoints ) { + + deltaAngle = 0; + + } else { + + deltaAngle = twoPi; + + } + + } + + if ( this.aClockwise === true && ! samePoints ) { + + if ( deltaAngle === twoPi ) { + + deltaAngle = - twoPi; + + } else { + + deltaAngle = deltaAngle - twoPi; + + } + + } + + 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. + 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; + this.aY = source.aY; + + this.xRadius = source.xRadius; + this.yRadius = source.yRadius; + + this.aStartAngle = source.aStartAngle; + this.aEndAngle = source.aEndAngle; + + this.aClockwise = source.aClockwise; + + this.aRotation = source.aRotation; + + return this; + + } + + toJSON() { + + const data = super.toJSON(); + + data.aX = this.aX; + data.aY = this.aY; + + data.xRadius = this.xRadius; + data.yRadius = this.yRadius; + + data.aStartAngle = this.aStartAngle; + data.aEndAngle = this.aEndAngle; + + data.aClockwise = this.aClockwise; + + data.aRotation = this.aRotation; + + return data; + + } + + fromJSON( json ) { + + super.fromJSON( json ); + + this.aX = json.aX; + this.aY = json.aY; + + this.xRadius = json.xRadius; + this.yRadius = json.yRadius; + + this.aStartAngle = json.aStartAngle; + this.aEndAngle = json.aEndAngle; + + this.aClockwise = json.aClockwise; + + this.aRotation = json.aRotation; + + return this; + + } + +} + +class ArcCurve extends EllipseCurve { + + constructor( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { + + super( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); + + this.isArcCurve = true; + + this.type = 'ArcCurve'; + + } + +} + +/** + * Centripetal CatmullRom Curve - which is useful for avoiding + * cusps and self-intersections in non-uniform catmull rom curves. + * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf + * + * curve.type accepts centripetal(default), chordal and catmullrom + * curve.tension is used for catmullrom which defaults to 0.5 + */ + + +/* +Based on an optimized c++ solution in + - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/ + - http://ideone.com/NoEbVM + +This CubicPoly class could be used for reusing some variables and calculations, +but for three.js curve use, it could be possible inlined and flatten into a single function call +which can be placed in CurveUtils. +*/ + +function CubicPoly() { + + let c0 = 0, c1 = 0, c2 = 0, c3 = 0; + + /* + * Compute coefficients for a cubic polynomial + * p(s) = c0 + c1*s + c2*s^2 + c3*s^3 + * such that + * p(0) = x0, p(1) = x1 + * and + * p'(0) = t0, p'(1) = t1. + */ + function init( x0, x1, t0, t1 ) { + + c0 = x0; + c1 = t0; + c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1; + c3 = 2 * x0 - 2 * x1 + t0 + t1; + + } + + return { + + initCatmullRom: function ( x0, x1, x2, x3, tension ) { + + init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) ); + + }, + + 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] + t1 *= dt1; + t2 *= dt1; + + init( x1, x2, t1, t2 ); + + }, + + calc: function ( t ) { + + const t2 = t * t; + const t3 = t2 * t; + 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(); + + this.isCatmullRomCurve3 = true; + + this.type = 'CatmullRomCurve3'; + + this.points = points; + this.closed = closed; + this.curveType = curveType; + this.tension = tension; + + } + + getPoint( t, optionalTarget = new Vector3() ) { + + const point = optionalTarget; + + const points = this.points; + const l = points.length; + + 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 ) { + + p0 = points[ ( intPoint - 1 ) % l ]; + + } else { + + // extrapolate first point + 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 { + + // extrapolate last point + tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] ); + p3 = tmp; + + } + + if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) { + + // init Centripetal / Chordal Catmull-Rom + 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 + if ( dt1 < 1e-4 ) dt1 = 1.0; + if ( dt0 < 1e-4 ) dt0 = dt1; + if ( dt2 < 1e-4 ) dt2 = dt1; + + px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 ); + py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 ); + pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 ); + + } else if ( this.curveType === 'catmullrom' ) { + + px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension ); + py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension ); + pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension ); + + } + + point.set( + px.calc( weight ), + py.calc( weight ), + pz.calc( weight ) + ); + + return point; + + } + + 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 ); + +} + +class CubicBezierCurve extends Curve { + + constructor( v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2(), v3 = new Vector2() ) { + + super(); + + this.isCubicBezierCurve = true; + + this.type = 'CubicBezierCurve'; + + this.v0 = v0; + this.v1 = v1; + 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; + + 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 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); + this.v3.copy( source.v3 ); + + return this; + + } + + toJSON() { + + const data = super.toJSON(); + + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + data.v3 = this.v3.toArray(); + + return data; + + } + + fromJSON( json ) { + + super.fromJSON( json ); + + this.v0.fromArray( json.v0 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); + this.v3.fromArray( json.v3 ); + + return this; + + } + +} + +class CubicBezierCurve3 extends Curve { + + constructor( v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3(), v3 = new Vector3() ) { + + super(); + + this.isCubicBezierCurve3 = true; + + this.type = 'CubicBezierCurve3'; + + this.v0 = v0; + this.v1 = v1; + 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; + + 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 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); + this.v3.copy( source.v3 ); + + return this; + + } + + toJSON() { + + const data = super.toJSON(); + + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + data.v3 = this.v3.toArray(); + + return data; + + } + + fromJSON( json ) { + + super.fromJSON( json ); + + this.v0.fromArray( json.v0 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); + this.v3.fromArray( json.v3 ); + + return this; + + } + +} + +class LineCurve extends Curve { + + constructor( v1 = new Vector2(), v2 = new Vector2() ) { + + super(); + + this.isLineCurve = true; + + this.type = 'LineCurve'; + + 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 + 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 { + + constructor( v1 = new Vector3(), v2 = new Vector3() ) { + + super(); + + this.isLineCurve3 = true; + + this.type = 'LineCurve3'; + + 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 + 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 { + + constructor( v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2() ) { + + super(); + + this.isQuadraticBezierCurve = true; + + this.type = 'QuadraticBezierCurve'; + + this.v0 = v0; + this.v1 = v1; + this.v2 = v2; + + } + + getPoint( t, optionalTarget = new Vector2() ) { + + const point = optionalTarget; + + const v0 = this.v0, v1 = this.v1, v2 = this.v2; + + point.set( + QuadraticBezier( t, v0.x, v1.x, v2.x ), + QuadraticBezier( t, v0.y, v1.y, v2.y ) + ); + + return point; + + } + + copy( source ) { + + super.copy( source ); + + this.v0.copy( source.v0 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); + + return this; + + } + + toJSON() { + + const data = super.toJSON(); + + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + + return data; + + } + + fromJSON( json ) { + + super.fromJSON( json ); + + this.v0.fromArray( json.v0 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); + + return this; + + } + +} + +class QuadraticBezierCurve3 extends Curve { + + constructor( v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3() ) { + + super(); + + this.isQuadraticBezierCurve3 = true; + + this.type = 'QuadraticBezierCurve3'; + + this.v0 = v0; + this.v1 = v1; + this.v2 = v2; + + } + + getPoint( t, optionalTarget = new Vector3() ) { + + const point = optionalTarget; + + const v0 = this.v0, v1 = this.v1, v2 = this.v2; + + point.set( + QuadraticBezier( t, v0.x, v1.x, v2.x ), + QuadraticBezier( t, v0.y, v1.y, v2.y ), + QuadraticBezier( t, v0.z, v1.z, v2.z ) + ); + + return point; + + } + + copy( source ) { + + super.copy( source ); + + this.v0.copy( source.v0 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); + + return this; + + } + + toJSON() { + + const data = super.toJSON(); + + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + + return data; + + } + + fromJSON( json ) { + + super.fromJSON( json ); + + this.v0.fromArray( json.v0 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); + + return this; + + } + +} + +class SplineCurve extends Curve { + + constructor( points = [] ) { + + super(); + + this.isSplineCurve = true; + + this.type = 'SplineCurve'; + + this.points = points; + + } + + getPoint( t, optionalTarget = new Vector2() ) { + + const point = optionalTarget; + + const points = this.points; + const p = ( points.length - 1 ) * t; + + const intPoint = Math.floor( p ); + const weight = p - intPoint; + + const p0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ]; + const p1 = points[ intPoint ]; + const p2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ]; + const p3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ]; + + point.set( + CatmullRom( weight, p0.x, p1.x, p2.x, p3.x ), + CatmullRom( weight, p0.y, p1.y, p2.y, p3.y ) + ); + + return point; + + } + + 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({ + __proto__: null, + ArcCurve: ArcCurve, + CatmullRomCurve3: CatmullRomCurve3, + CubicBezierCurve: CubicBezierCurve, + CubicBezierCurve3: CubicBezierCurve3, + EllipseCurve: EllipseCurve, + LineCurve: LineCurve, + LineCurve3: LineCurve3, + QuadraticBezierCurve: QuadraticBezierCurve, + QuadraticBezierCurve3: QuadraticBezierCurve3, + SplineCurve: SplineCurve +}); + +/************************************************************** + * Curved Path - a curve path is simply a array of connected + * curves, but retains the api of a curve + **************************************************************/ + +class CurvePath extends Curve { + + constructor() { + + super(); + + this.type = 'CurvePath'; + + this.curves = []; + this.autoClose = false; // Automatically closes the path + + } + + 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 + // 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. + + while ( i < curveLengths.length ) { + + if ( curveLengths[ i ] >= d ) { + + const diff = curveLengths[ i ] - d; + const curve = this.curves[ i ]; + + const segmentLength = curve.getLength(); + const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; + + return curve.getPointAt( u, optionalTarget ); + + } + + i ++; + + } + + return null; + + // loop where sum != 0, sum > 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 { + + constructor( points ) { + + 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*/ ) { + + 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 { + + constructor( points = [ new Vector2( 0, - 0.5 ), new Vector2( 0.5, 0 ), new Vector2( 0, 0.5 ) ], segments = 12, phiStart = 0, phiLength = Math.PI * 2 ) { + + super(); + + this.type = 'LatheGeometry'; + + this.parameters = { + points: points, + segments: segments, + phiStart: phiStart, + phiLength: phiLength + }; + + segments = Math.floor( segments ); + + // clamp phiLength so it's in range of [ 0, 2PI ] + + phiLength = clamp( phiLength, 0, Math.PI * 2 ); + + // buffers + + const indices = []; + const vertices = []; + const uvs = []; + const initNormals = []; + const normals = []; + + // helper variables + + const inverseSegments = 1.0 / segments; + const vertex = new Vector3(); + const uv = new Vector2(); + const normal = new Vector3(); + const curNormal = new Vector3(); + const prevNormal = new Vector3(); + let dx = 0; + 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; + normal.y = - dx; + normal.z = dy * 0.0; + + prevNormal.copy( normal ); + + 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; + normal.y = - dx; + normal.z = dy * 0.0; + + curNormal.copy( normal ); + + normal.x += prevNormal.x; + normal.y += prevNormal.y; + normal.z += prevNormal.z; + + normal.normalize(); + + initNormals.push( normal.x, normal.y, normal.z ); + + prevNormal.copy( curNormal ); + + } + + } + + // 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 + + uv.x = i / segments; + uv.y = j / ( points.length - 1 ); + + 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 + + for ( let i = 0; i < segments; i ++ ) { + + for ( let j = 0; j < ( points.length - 1 ); j ++ ) { + + const base = j + i * points.length; + + const a = base; + const b = base + points.length; + const c = base + points.length + 1; + const d = base + 1; + + // faces + + indices.push( a, b, d ); + indices.push( c, d, b ); + + } + + } + + // 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 { + + constructor( radius = 1, length = 1, capSegments = 4, radialSegments = 8 ) { + + const path = new Path(); + path.absarc( 0, - length / 2, radius, Math.PI * 1.5, 0 ); + path.absarc( 0, length / 2, radius, 0, Math.PI * 0.5 ); + + super( path.getPoints( capSegments ), radialSegments ); + + this.type = 'CapsuleGeometry'; + + this.parameters = { + radius: radius, + height: length, + capSegments: capSegments, + radialSegments: radialSegments, + }; + + } + + static fromJSON( data ) { + + return new CapsuleGeometry( data.radius, data.length, data.capSegments, data.radialSegments ); + + } + +} + +class CircleGeometry extends BufferGeometry { + + constructor( radius = 1, segments = 32, thetaStart = 0, thetaLength = Math.PI * 2 ) { + + super(); + + this.type = 'CircleGeometry'; + + this.parameters = { + radius: radius, + segments: segments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + + segments = Math.max( 3, segments ); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + + // helper variables + + const vertex = new Vector3(); + 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 + + vertex.x = radius * Math.cos( segment ); + vertex.y = radius * Math.sin( segment ); + + vertices.push( vertex.x, vertex.y, vertex.z ); + + // normal + + normals.push( 0, 0, 1 ); + + // uvs + + uv.x = ( vertices[ i ] / radius + 1 ) / 2; + uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2; + + uvs.push( uv.x, uv.y ); + + } + + // indices + + for ( let i = 1; i <= segments; i ++ ) { + + indices.push( i, i + 1, 0 ); + + } + + // 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 { + + constructor( radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) { + + super(); + + this.type = 'CylinderGeometry'; + + this.parameters = { + radiusTop: radiusTop, + radiusBottom: radiusBottom, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + + const scope = this; + + radialSegments = Math.floor( radialSegments ); + heightSegments = Math.floor( heightSegments ); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + + // helper variables + + let index = 0; + const indexArray = []; + const halfHeight = height / 2; + let groupStart = 0; + + // generate geometry + + generateTorso(); + + if ( openEnded === false ) { + + if ( radiusTop > 0 ) generateCap( true ); + if ( radiusBottom > 0 ) generateCap( false ); + + } + + // 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 + 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 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 + + vertex.x = radius * sinTheta; + vertex.y = - v * height + halfHeight; + vertex.z = radius * cosTheta; + vertices.push( vertex.x, vertex.y, vertex.z ); + + // normal + + normal.set( sinTheta, slope, cosTheta ).normalize(); + normals.push( normal.x, normal.y, normal.z ); + + // uv + + 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 + + indexArray.push( indexRow ); + + } + + // 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 + + indices.push( a, b, d ); + indices.push( b, c, d ); + + // update group counter + + groupCount += 6; + + } + + } + + // add a group to the geometry. this will ensure multi material support + + 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; + + const uv = new Vector2(); + 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. + // 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 + + uvs.push( 0.5, 0.5 ); + + // increase index + + index ++; + + } + + // save the index of the last center vertex + const centerIndexEnd = index; + + // 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 + + vertex.x = radius * sinTheta; + vertex.y = halfHeight * sign; + vertex.z = radius * cosTheta; + vertices.push( vertex.x, vertex.y, vertex.z ); + + // normal + + 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 + + index ++; + + } + + // 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 + + scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 ); + + // 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 { + + constructor( radius = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) { + + super( 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); + + this.type = 'ConeGeometry'; + + this.parameters = { + radius: radius, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + 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 { + + constructor( vertices = [], indices = [], radius = 1, detail = 0 ) { + + super(); + + this.type = 'PolyhedronGeometry'; + + this.parameters = { + vertices: vertices, + indices: indices, + radius: radius, + detail: detail + }; + + // default buffer data + + const vertexBuffer = []; + const uvBuffer = []; + + // the subdivision creates the vertex buffer data + + subdivide( detail ); + + // all vertices should lie on a conceptual sphere with a given radius + + applyRadius( radius ); + + // 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 + + function subdivide( detail ) { + + const a = new Vector3(); + const b = new Vector3(); + 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 + + 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 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; + + } else { + + v[ i ][ j ] = aj.clone().lerp( bj, j / rows ); + + } + + } + + } + + // 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 ] ); + pushVertex( v[ i ][ k ] ); + + } else { + + pushVertex( v[ i ][ k + 1 ] ); + pushVertex( v[ i + 1 ][ k + 1 ] ); + pushVertex( v[ i + 1 ][ k ] ); + + } + + } + + } + + } + + function applyRadius( radius ) { + + 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 ]; + vertex.y = vertexBuffer[ i + 1 ]; + vertex.z = vertexBuffer[ i + 2 ]; + + vertex.normalize().multiplyScalar( radius ); + + vertexBuffer[ i + 0 ] = vertex.x; + vertexBuffer[ i + 1 ] = vertex.y; + vertexBuffer[ i + 2 ] = vertex.z; + + } + + } + + 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 ]; + vertex.z = vertexBuffer[ i + 2 ]; + + const u = azimuth( vertex ) / 2 / Math.PI + 0.5; + 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 + + if ( max > 0.9 && min < 0.1 ) { + + if ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1; + if ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1; + if ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1; + + } + + } + + } + + function pushVertex( vertex ) { + + vertexBuffer.push( vertex.x, vertex.y, vertex.z ); + + } + + function getVertexByIndex( index, vertex ) { + + 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(); + const c = new Vector3(); + + const centroid = new Vector3(); + + 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 ] ); + c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] ); + + uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] ); + uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] ); + uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] ); + + centroid.copy( a ).add( b ).add( c ).divideScalar( 3 ); + + const azi = azimuth( centroid ); + + correctUV( uvA, j + 0, a, azi ); + correctUV( uvB, j + 2, b, azi ); + 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. + + function azimuth( vector ) { + + return Math.atan2( vector.z, - vector.x ); + + } + + + // Angle above the XZ plane. + + function inclination( vector ) { + + return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) ); + + } + + } + + 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/φ) + - 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 ); + + this.type = 'DodecahedronGeometry'; + + this.parameters = { + radius: radius, + 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(); + + this.type = 'EdgesGeometry'; + + this.parameters = { + geometry: geometry, + thresholdAngle: thresholdAngle + }; + + if ( geometry !== null ) { + + const precisionPoints = 4; + const precision = Math.pow( 10, precisionPoints ); + const thresholdDot = Math.cos( DEG2RAD * thresholdAngle ); + + const indexAttr = geometry.getIndex(); + const positionAttr = geometry.getAttribute( 'position' ); + const indexCount = indexAttr ? indexAttr.count : positionAttr.count; + + const indexArr = [ 0, 0, 0 ]; + const vertKeys = [ 'a', 'b', 'c' ]; + const hashes = new Array( 3 ); + + const edgeData = {}; + const vertices = []; + for ( let i = 0; i < indexCount; i += 3 ) { + + if ( indexAttr ) { + + indexArr[ 0 ] = indexAttr.getX( i ); + indexArr[ 1 ] = indexAttr.getX( i + 1 ); + indexArr[ 2 ] = indexAttr.getX( i + 2 ); + + } else { + + indexArr[ 0 ] = i; + indexArr[ 1 ] = i + 1; + indexArr[ 2 ] = i + 2; + + } + + const { a, b, c } = _triangle; + a.fromBufferAttribute( positionAttr, indexArr[ 0 ] ); + b.fromBufferAttribute( positionAttr, indexArr[ 1 ] ); + c.fromBufferAttribute( positionAttr, indexArr[ 2 ] ); + _triangle.getNormal( _normal ); + + // 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 + if ( hashes[ 0 ] === hashes[ 1 ] || hashes[ 1 ] === hashes[ 2 ] || hashes[ 2 ] === hashes[ 0 ] ) { + + continue; + + } + + // 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; + const vecHash0 = hashes[ j ]; + const vecHash1 = hashes[ jNext ]; + const v0 = _triangle[ vertKeys[ j ] ]; + 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. + if ( _normal.dot( edgeData[ reverseHash ].normal ) <= thresholdDot ) { + + vertices.push( v0.x, v0.y, v0.z ); + vertices.push( v1.x, v1.y, v1.z ); + + } + + edgeData[ reverseHash ] = null; + + } else if ( ! ( hash in edgeData ) ) { + + // if we've already got an edge here then skip adding a new one + edgeData[ hash ] = { + + index0: indexArr[ j ], + index1: indexArr[ jNext ], + normal: _normal.clone(), + + }; + + } + + } + + } + + // 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 { + + constructor( points ) { + + super( points ); + + this.uuid = generateUUID(); + + 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) + + extractPoints( divisions ) { + + return { + + shape: this.getPoints( divisions ), + 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.4) + */ + +const Earcut = { + + triangulate: function ( data, holeIndices, dim = 2 ) { + + const hasHoles = holeIndices && holeIndices.length; + const outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length; + let outerNode = linkedList( data, 0, outerLen, dim, true ); + 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 ( 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 ]; + if ( x < minX ) minX = x; + if ( y < minY ) minY = y; + if ( x > maxX ) maxX = x; + if ( y > maxY ) maxY = y; + + } + + // minX, minY and invSize are later used to transform coords into integers for z-order calculation + invSize = Math.max( maxX - minX, maxY - minY ); + invSize = invSize !== 0 ? 32767 / invSize : 0; + + } + + earcutLinked( outerNode, triangles, dim, minX, minY, invSize, 0 ); + + return triangles; + + } + +}; + +// 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 +function filterPoints( start, end ) { + + if ( ! start ) return start; + if ( ! end ) end = start; + + let p = start, + again; + do { + + again = false; + + if ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) { + + removeNode( p ); + p = end = p.prev; + if ( p === p.next ) break; + again = true; + + } else { + + p = p.next; + + } + + } while ( again || p !== end ); + + return end; + +} + +// 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 ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize ); + + let stop = ear, + 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 | 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; + + // 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 + + } else if ( pass === 1 ) { + + ear = cureLocalIntersections( filterPoints( ear ), triangles, dim ); + earcutLinked( ear, triangles, dim, minX, minY, invSize, 2 ); + + // as a last resort, try splitting the remaining polygon into two + + } else if ( pass === 2 ) { + + splitEarcut( ear, triangles, dim, minX, minY, invSize ); + + } + + break; + + } + + } + +} + +// check whether a polygon node forms a valid ear with adjacent nodes +function isEar( ear ) { + + const a = ear.prev, + b = ear, + c = ear.next; + + if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear + + // now make sure we don't have other points inside the potential ear + 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 ); + + 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; + + 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 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 + while ( p && p.z >= minZ && n && n.z <= maxZ ) { + + 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.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 + while ( p && p.z >= minZ ) { + + 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 + while ( n && n.z <= maxZ ) { + + 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 +function cureLocalIntersections( start, triangles, dim ) { + + let p = start; + do { + + const a = p.prev, + 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 | 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 +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 + a = filterPoints( a, a.next ); + c = filterPoints( c, c.next ); + + // 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 +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; + list = linkedList( data, start, end, dim, false ); + if ( list === list.next ) list.steiner = true; + queue.push( getLeftmost( list ) ); + + } + + queue.sort( compareX ); + + // process holes from left to right + for ( i = 0; i < queue.length; i ++ ) { + + 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 +function eliminateHole( hole, outerNode ) { + + const bridge = findHoleBridge( hole, outerNode ); + if ( ! bridge ) { + + 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, + 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; + 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; + + // 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; + let tanMin = Infinity, 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 + + if ( locallyInside( p, hole ) && ( tan < tanMin || ( tan === tanMin && ( p.x > m.x || ( p.x === m.x && sectorContainsSector( m, p ) ) ) ) ) ) { + + m = p; + tanMin = tan; + + } + + } + + p = p.next; + + } while ( p !== stop ); + + return m; + +} + +// 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 +function indexCurve( start, minX, minY, invSize ) { + + let p = start; + do { + + 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 +function sortLinked( list ) { + + let i, 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; + p = p.nextZ; + pSize --; + + } else { + + e = q; + 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 +function zOrder( x, y, minX, minY, invSize ) { + + // coords are transformed into non-negative 15-bit integer range + 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; + x = ( x | ( x << 1 ) ) & 0x55555555; + + y = ( y | ( y << 8 ) ) & 0x00FF00FF; + y = ( y | ( y << 4 ) ) & 0x0F0F0F0F; + y = ( y | ( y << 2 ) ) & 0x33333333; + y = ( y | ( y << 1 ) ) & 0x55555555; + + return x | ( y << 1 ); + +} + +// find the leftmost node of a polygon ring +function getLeftmost( start ) { + + let p = start, + leftmost = start; + do { + + if ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) leftmost = p; + p = p.next; + + } while ( p !== start ); + + return leftmost; + +} + +// 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 ) && + ( 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 ) && // 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 +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 +function equals( p1, p2 ) { + + return p1.x === p2.x && p1.y === p2.y; + +} + +// 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 ) ); + const o3 = sign( area( p2, q2, p1 ) ); + const o4 = sign( area( p2, q2, q1 ) ); + + 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 +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 +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 +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 +function middleInside( a, b ) { + + let p = a, + inside = false; + const px = ( a.x + b.x ) / 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 +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; + + a.next = b; + b.prev = a; + + a2.next = an; + an.prev = a2; + + b2.next = a2; + a2.prev = b2; + + bp.next = b2; + b2.prev = bp; + + return b2; + +} + +// create a node and optionally link it with previous one (in a circular doubly linked list) +function insertNode( i, x, y, last ) { + + const p = new Node( i, x, y ); + + if ( ! last ) { + + p.prev = p; + p.next = p; + + } else { + + p.next = last.next; + p.prev = 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.x = x; + this.y = y; + + // previous and next vertex nodes in a polygon ring + this.prev = null; + this.next = null; + + // 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.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 ); + + // + + 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 ); + + // + + 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 ); + vertices.push( contour[ i ].y ); + + } + +} + +/** + * Creates extruded geometry from a path shape. + * + * parameters = { + * + * curveSegments: , // number of points on the curves + * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too + * depth: , // Depth to extrude the shape + * + * bevelEnabled: , // turn on bevel + * bevelThickness: , // how deep into the original shape bevel goes + * bevelSize: , // how far from shape outline (including bevelOffset) is bevel + * bevelOffset: , // how far from shape outline does bevel start + * bevelSegments: , // number of bevel layers + * + * extrudePath: // curve to extrude shape along + * + * UVGenerator: // object that provides UV generator functions + * + * } + */ + +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(); + + this.type = 'ExtrudeGeometry'; + + this.parameters = { + shapes: shapes, + options: options + }; + + shapes = Array.isArray( shapes ) ? shapes : [ shapes ]; + + 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 + + this.setAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) ); + + this.computeVertexNormals(); + + // functions + + function addShape( shape ) { + + const placeholder = []; + + // options + + const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; + const steps = options.steps !== undefined ? options.steps : 1; + const depth = options.depth !== undefined ? options.depth : 1; + + let bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; + let bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 0.2; + let bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 0.1; + 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; + + // + + let extrudePts, 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); + + binormal = new Vector3(); + normal = new Vector3(); + position2 = new Vector3(); + + } + + // Safeguards if bevels are not enabled + + if ( ! bevelEnabled ) { + + bevelSegments = 0; + bevelThickness = 0; + bevelSize = 0; + bevelOffset = 0; + + } + + // 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 ... + + 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 + + for ( let h = 0, hl = holes.length; h < hl; h ++ ) { + + 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 + + + function getBevelVec( inPt, inPrev, inNext ) { + + // computes for inPt the corresponding point inPt' on a new contour + // shifted by 1 unit (length of normalized vector) to the left + // if we walk along contour clockwise, this new contour is outside the old one + // + // inPt' is the intersection of the two lines parallel to the two + // adjacent edges of inPt at a distance of 1 unit on the left side. + + 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; + 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 + 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 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 sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y - + ( ptNextShift_y - ptPrevShift_y ) * v_next_x ) / + ( v_prev_x * v_next_y - v_prev_y * v_next_x ); + + // vector from inPt to intersection point + + v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x ); + v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y ); + + // Don't normalize!, otherwise sharp corners become ugly + // but prevent crazy spikes + 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 { + + shrink_by = Math.sqrt( v_trans_lensq / 2 ); + + } + + } else { + + // handle special case of collinear edges + + let direction_eq = false; // assumes: opposite + + if ( v_prev_x > Number.EPSILON ) { + + if ( v_next_x > Number.EPSILON ) { + + direction_eq = true; + + } + + } else { + + if ( v_prev_x < - Number.EPSILON ) { + + if ( v_next_x < - Number.EPSILON ) { + + direction_eq = true; + + } + + } else { + + if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) { + + direction_eq = true; + + } + + } + + } + + if ( direction_eq ) { + + // console.log("Warning: lines are a straight sequence"); + v_trans_x = - v_prev_y; + v_trans_y = v_prev_x; + shrink_by = Math.sqrt( v_prev_lensq ); + + } else { + + // console.log("Warning: lines are a straight spike"); + v_trans_x = v_prev_x; + v_trans_y = v_prev_y; + shrink_by = Math.sqrt( v_prev_lensq / 2 ); + + } + + } + + 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) + // console.log('i,j,k', i, j , k) + + contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); + + } + + const holesMovements = []; + let oneHoleMovements, 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) + oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); + + } + + holesMovements.push( oneHoleMovements ); + verticesMovements = verticesMovements.concat( oneHoleMovements ); + + } + + + // Loop bevelSegments, 1 for the front, 1 for the back + + for ( 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 + + 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 + + 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; + + // 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 + + 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 ++ ) { + 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 + + 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 + + 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 { + + v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z ); + + } + + } + + } + + } + + /* Faces */ + + // Top and bottom faces + + buildLidFaces(); + + // Sides faces + + buildSideFaces(); + + + ///// Internal functions + + function buildLidFaces() { + + const start = verticesArray.length / 3; + + if ( bevelEnabled ) { + + let layer = 0; // steps + 1 + let offset = vlen * layer; + + // 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 + + for ( let i = 0; i < flen; i ++ ) { + + const face = faces[ i ]; + f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset ); + + } + + } else { + + // Bottom faces + + for ( let i = 0; i < flen; i ++ ) { + + const face = faces[ i ]; + f3( face[ 2 ], face[ 1 ], face[ 0 ] ); + + } + + // 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 + + 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 + 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); + + 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; + + 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 ); + addVertex( c ); + + const nextIndex = verticesArray.length / 3; + const uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); + + addUV( uvs[ 0 ] ); + addUV( uvs[ 1 ] ); + addUV( uvs[ 2 ] ); + + } + + function f4( a, b, c, d ) { + + addVertex( a ); + addVertex( b ); + addVertex( d ); + + addVertex( b ); + addVertex( c ); + addVertex( d ); + + + const nextIndex = verticesArray.length / 3; + const uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); + + addUV( uvs[ 0 ] ); + addUV( uvs[ 1 ] ); + addUV( uvs[ 3 ] ); + + addUV( uvs[ 1 ] ); + addUV( uvs[ 2 ] ); + addUV( uvs[ 3 ] ); + + } + + function addVertex( index ) { + + verticesArray.push( placeholder[ index * 3 + 0 ] ); + verticesArray.push( placeholder[ index * 3 + 1 ] ); + verticesArray.push( placeholder[ index * 3 + 2 ] ); + + } + + + function addUV( vector2 ) { + + uvArray.push( vector2.x ); + uvArray.push( vector2.y ); + + } + + } + + } + + 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 ]; + const a_y = vertices[ indexA * 3 + 1 ]; + const b_x = vertices[ indexB * 3 ]; + const b_y = vertices[ indexB * 3 + 1 ]; + const c_x = vertices[ indexC * 3 ]; + const c_y = vertices[ indexC * 3 + 1 ]; + + return [ + new Vector2( a_x, a_y ), + new Vector2( b_x, b_y ), + new Vector2( c_x, c_y ) + ]; + + }, + + generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) { + + const a_x = vertices[ indexA * 3 ]; + const a_y = vertices[ indexA * 3 + 1 ]; + const a_z = vertices[ indexA * 3 + 2 ]; + const b_x = vertices[ indexB * 3 ]; + const b_y = vertices[ indexB * 3 + 1 ]; + const b_z = vertices[ indexB * 3 + 2 ]; + const c_x = vertices[ indexC * 3 ]; + const c_y = vertices[ indexC * 3 + 1 ]; + const c_z = vertices[ indexC * 3 + 2 ]; + 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 { + + return [ + new Vector2( a_y, 1 - a_z ), + new Vector2( b_y, 1 - b_z ), + new Vector2( c_y, 1 - c_z ), + new Vector2( d_y, 1 - d_z ) + ]; + + } + + } + +}; + +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 ]; + + data.shapes.push( shape.uuid ); + + } + + } else { + + data.shapes.push( shapes.uuid ); + + } + + data.options = Object.assign( {}, options ); + + if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON(); + + return data; + +} + +class IcosahedronGeometry extends PolyhedronGeometry { + + constructor( radius = 1, detail = 0 ) { + + const t = ( 1 + Math.sqrt( 5 ) ) / 2; + + const vertices = [ + - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0, + 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, + t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1 + ]; + + const indices = [ + 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, + 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, + 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, + 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1 + ]; + + super( vertices, indices, radius, detail ); + + this.type = 'IcosahedronGeometry'; + + this.parameters = { + radius: radius, + detail: detail + }; + + } + + static fromJSON( data ) { + + return new IcosahedronGeometry( data.radius, data.detail ); + + } + +} + +class OctahedronGeometry extends PolyhedronGeometry { + + constructor( radius = 1, detail = 0 ) { + + const vertices = [ + 1, 0, 0, - 1, 0, 0, 0, 1, 0, + 0, - 1, 0, 0, 0, 1, 0, 0, - 1 + ]; + + const indices = [ + 0, 2, 4, 0, 4, 3, 0, 3, 5, + 0, 5, 2, 1, 2, 5, 1, 5, 3, + 1, 3, 4, 1, 4, 2 + ]; + + super( vertices, indices, radius, detail ); + + this.type = 'OctahedronGeometry'; + + this.parameters = { + radius: radius, + detail: detail + }; + + } + + static fromJSON( data ) { + + return new OctahedronGeometry( data.radius, data.detail ); + + } + +} + +class RingGeometry extends BufferGeometry { + + constructor( innerRadius = 0.5, outerRadius = 1, thetaSegments = 32, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2 ) { + + super(); + + this.type = 'RingGeometry'; + + this.parameters = { + innerRadius: innerRadius, + outerRadius: outerRadius, + thetaSegments: thetaSegments, + phiSegments: phiSegments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + + thetaSegments = Math.max( 3, thetaSegments ); + phiSegments = Math.max( 1, phiSegments ); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + 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 + + 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 + + vertex.x = radius * Math.cos( segment ); + vertex.y = radius * Math.sin( segment ); + + vertices.push( vertex.x, vertex.y, vertex.z ); + + // normal + + normals.push( 0, 0, 1 ); + + // 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 + + radius += radiusStep; + + } + + // 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 + + indices.push( a, b, d ); + indices.push( b, c, d ); + + } + + } + + // 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 { + + constructor( shapes = new Shape( [ new Vector2( 0, 0.5 ), new Vector2( - 0.5, - 0.5 ), new Vector2( 0.5, - 0.5 ) ] ), curveSegments = 12 ) { + + super(); + + this.type = 'ShapeGeometry'; + + this.parameters = { + shapes: shapes, + curveSegments: curveSegments + }; + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + + // helper variables + + let groupStart = 0; + let groupCount = 0; + + // allow single and array values for "shapes" parameter + + if ( Array.isArray( shapes ) === false ) { + + addShape( shapes ); + + } else { + + for ( let i = 0; i < shapes.length; i ++ ) { + + addShape( shapes[ i ] ); + + this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support + + groupStart += groupCount; + groupCount = 0; + + } + + } + + // 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 + + 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 + + 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 ); + + // 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 + + 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 + + } + + // indices + + for ( let i = 0, l = faces.length; i < l; i ++ ) { + + const face = faces[ i ]; + + const a = face[ 0 ] + indexOffset; + const b = face[ 1 ] + indexOffset; + const c = face[ 2 ] + indexOffset; + + indices.push( a, b, c ); + groupCount += 3; + + } + + } + + } + + 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 ]; + + data.shapes.push( shape.uuid ); + + } + + } else { + + data.shapes.push( shapes.uuid ); + + } + + return data; + +} + +class SphereGeometry extends BufferGeometry { + + constructor( radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI ) { + + super(); + + this.type = 'SphereGeometry'; + + this.parameters = { + radius: radius, + widthSegments: widthSegments, + heightSegments: heightSegments, + phiStart: phiStart, + phiLength: phiLength, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + + widthSegments = Math.max( 3, Math.floor( widthSegments ) ); + heightSegments = Math.max( 2, Math.floor( heightSegments ) ); + + const thetaEnd = Math.min( thetaStart + thetaLength, Math.PI ); + + let index = 0; + const grid = []; + + const vertex = new Vector3(); + const normal = new Vector3(); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + 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 + + 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 + + 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 + + normal.copy( vertex ).normalize(); + normals.push( normal.x, normal.y, normal.z ); + + // uv + + uvs.push( u + uOffset, 1 - v ); + + verticesRow.push( index ++ ); + + } + + grid.push( verticesRow ); + + } + + // indices + + for ( let iy = 0; iy < heightSegments; iy ++ ) { + + for ( let ix = 0; ix < widthSegments; ix ++ ) { + + const a = grid[ iy ][ ix + 1 ]; + const b = grid[ iy ][ ix ]; + const c = grid[ iy + 1 ][ ix ]; + const d = grid[ iy + 1 ][ ix + 1 ]; + + if ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d ); + if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d ); + + } + + } + + // build geometry + + this.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 { + + constructor( radius = 1, detail = 0 ) { + + const vertices = [ + 1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1 + ]; + + const indices = [ + 2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1 + ]; + + super( vertices, indices, radius, detail ); + + this.type = 'TetrahedronGeometry'; + + this.parameters = { + radius: radius, + detail: detail + }; + + } + + static fromJSON( data ) { + + return new TetrahedronGeometry( data.radius, data.detail ); + + } + +} + +class TorusGeometry extends BufferGeometry { + + constructor( radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48, arc = Math.PI * 2 ) { + + super(); + + this.type = 'TorusGeometry'; + + this.parameters = { + radius: radius, + tube: tube, + radialSegments: radialSegments, + tubularSegments: tubularSegments, + arc: arc + }; + + radialSegments = Math.floor( radialSegments ); + tubularSegments = Math.floor( tubularSegments ); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + + // helper variables + + const center = new Vector3(); + const vertex = new Vector3(); + 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 + + vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u ); + vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u ); + vertex.z = tube * Math.sin( v ); + + vertices.push( vertex.x, vertex.y, vertex.z ); + + // normal + + center.x = radius * Math.cos( u ); + center.y = radius * Math.sin( u ); + normal.subVectors( vertex, center ).normalize(); + + normals.push( normal.x, normal.y, normal.z ); + + // uv + + uvs.push( i / tubularSegments ); + uvs.push( j / radialSegments ); + + } + + } + + // generate indices + + 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 + + indices.push( a, b, d ); + indices.push( b, c, d ); + + } + + } + + // 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 { + + constructor( radius = 1, tube = 0.4, tubularSegments = 64, radialSegments = 8, p = 2, q = 3 ) { + + super(); + + this.type = 'TorusKnotGeometry'; + + this.parameters = { + radius: radius, + tube: tube, + tubularSegments: tubularSegments, + radialSegments: radialSegments, + p: p, + q: q + }; + + tubularSegments = Math.floor( tubularSegments ); + radialSegments = Math.floor( radialSegments ); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + + // helper variables + + const vertex = new Vector3(); + const normal = new Vector3(); + + const P1 = new Vector3(); + const P2 = new Vector3(); + + const B = new Vector3(); + const T = new Vector3(); + 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. + // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions + + calculatePositionOnCurve( u, p, q, radius, P1 ); + calculatePositionOnCurve( u + 0.01, p, q, radius, P2 ); + + // calculate orthonormal basis + + T.subVectors( P2, P1 ); + N.addVectors( P2, P1 ); + B.crossVectors( T, N ); + N.crossVectors( B, T ); + + // normalize B, N. T can be ignored, we don't use it + + B.normalize(); + N.normalize(); + + for ( 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. + // 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) + + normal.subVectors( vertex, P1 ).normalize(); + + normals.push( normal.x, normal.y, normal.z ); + + // uv + + uvs.push( i / tubularSegments ); + uvs.push( j / radialSegments ); + + } + + } + + // 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 + + indices.push( a, b, d ); + indices.push( b, c, d ); + + } + + } + + // 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 + + function calculatePositionOnCurve( u, p, q, radius, position ) { + + const cu = Math.cos( u ); + const su = Math.sin( u ); + const quOverP = q / p * u; + const cs = Math.cos( quOverP ); + + position.x = radius * ( 2 + cs ) * 0.5 * cu; + position.y = radius * ( 2 + cs ) * su * 0.5; + position.z = radius * Math.sin( quOverP ) * 0.5; + + } + + } + + static fromJSON( data ) { + + return new TorusKnotGeometry( data.radius, data.tube, data.tubularSegments, data.radialSegments, data.p, data.q ); + + } + +} + +class TubeGeometry extends BufferGeometry { + + constructor( path = new QuadraticBezierCurve3( new Vector3( - 1, - 1, 0 ), new Vector3( - 1, 1, 0 ), new Vector3( 1, 1, 0 ) ), tubularSegments = 64, radius = 1, radialSegments = 8, closed = false ) { + + super(); + + this.type = 'TubeGeometry'; + + this.parameters = { + path: path, + tubularSegments: tubularSegments, + radius: radius, + radialSegments: radialSegments, + closed: closed + }; + + const frames = path.computeFrenetFrames( tubularSegments, closed ); + + // expose internals + + this.tangents = frames.tangents; + this.normals = frames.normals; + this.binormals = frames.binormals; + + // helper variables + + const vertex = new Vector3(); + const normal = new Vector3(); + const uv = new Vector2(); + let P = new Vector3(); + + // buffer + + const vertices = []; + const normals = []; + const uvs = []; + const indices = []; + + // create buffer data + + generateBufferData(); + + // 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 + + 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 + // 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 ); + + // uvs are generated in a separate function. + // this makes it easy compute correct values for closed geometries + + 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 + + const N = frames.normals[ i ]; + 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 + + 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 + + vertex.x = P.x + radius * normal.x; + vertex.y = P.y + radius * normal.y; + vertex.z = P.z + radius * normal.z; + + vertices.push( vertex.x, vertex.y, vertex.z ); + + } + + } + + 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 + + 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 ++ ) { + + uv.x = i / tubularSegments; + uv.y = j / radialSegments; + + uvs.push( uv.x, uv.y ); + + } + + } + + } + + } + + 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 { + + constructor( geometry = null ) { + + super(); + + this.type = 'WireframeGeometry'; + + this.parameters = { + geometry: geometry + }; + + if ( geometry !== null ) { + + // buffer + + const vertices = []; + 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 + + 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 ); + + } + + } + + } + + } + + } else { + + // non-indexed BufferGeometry + + 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 + + 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 + + if ( edges.has( hash1 ) === true || edges.has( hash2 ) === true ) { + + return false; + + } else { + + edges.add( hash1 ); + edges.add( hash2 ); + return true; + + } + +} + +var Geometries = /*#__PURE__*/Object.freeze({ + __proto__: null, + BoxGeometry: BoxGeometry, + CapsuleGeometry: CapsuleGeometry, + CircleGeometry: CircleGeometry, + ConeGeometry: ConeGeometry, + CylinderGeometry: CylinderGeometry, + DodecahedronGeometry: DodecahedronGeometry, + EdgesGeometry: EdgesGeometry, + ExtrudeGeometry: ExtrudeGeometry, + IcosahedronGeometry: IcosahedronGeometry, + LatheGeometry: LatheGeometry, + OctahedronGeometry: OctahedronGeometry, + PlaneGeometry: PlaneGeometry, + PolyhedronGeometry: PolyhedronGeometry, + RingGeometry: RingGeometry, + ShapeGeometry: ShapeGeometry, + SphereGeometry: SphereGeometry, + TetrahedronGeometry: TetrahedronGeometry, + TorusGeometry: TorusGeometry, + TorusKnotGeometry: TorusKnotGeometry, + TubeGeometry: TubeGeometry, + WireframeGeometry: WireframeGeometry +}); + +class ShadowMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isShadowMaterial = true; + + this.type = 'ShadowMaterial'; + + this.color = new Color( 0x000000 ); + this.transparent = true; + + 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 { + + constructor( parameters ) { + + super( parameters ); + + this.isRawShaderMaterial = true; + + this.type = 'RawShaderMaterial'; + + } + +} + +class MeshStandardMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshStandardMaterial = true; + + this.defines = { 'STANDARD': '' }; + + this.type = 'MeshStandardMaterial'; + + this.color = new Color( 0xffffff ); // diffuse + this.roughness = 1.0; + this.metalness = 0.0; + + this.map = null; + + this.lightMap = null; + this.lightMapIntensity = 1.0; + + this.aoMap = null; + this.aoMapIntensity = 1.0; + + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.roughnessMap = null; + + this.metalnessMap = null; + + this.alphaMap = null; + + this.envMap = null; + this.envMapIntensity = 1.0; + + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + + this.flatShading = false; + + this.fog = true; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.defines = { 'STANDARD': '' }; + + this.color.copy( source.color ); + this.roughness = source.roughness; + this.metalness = source.metalness; + + this.map = source.map; + + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + + this.emissive.copy( source.emissive ); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; + + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.roughnessMap = source.roughnessMap; + + this.metalnessMap = source.metalnessMap; + + this.alphaMap = source.alphaMap; + + this.envMap = source.envMap; + this.envMapIntensity = source.envMapIntensity; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + + this.flatShading = source.flatShading; + + this.fog = source.fog; + + return this; + + } + +} + +class MeshPhysicalMaterial extends MeshStandardMaterial { + + constructor( parameters ) { + + super(); + + this.isMeshPhysicalMaterial = true; + + this.defines = { + + 'STANDARD': '', + 'PHYSICAL': '' + + }; + + this.type = 'MeshPhysicalMaterial'; + + this.clearcoatMap = null; + this.clearcoatRoughness = 0.0; + this.clearcoatRoughnessMap = null; + this.clearcoatNormalScale = new Vector2( 1, 1 ); + this.clearcoatNormalMap = null; + + this.ior = 1.5; + + Object.defineProperty( this, 'reflectivity', { + get: function () { + + return ( clamp( 2.5 * ( this.ior - 1 ) / ( this.ior + 1 ), 0, 1 ) ); + + }, + set: function ( reflectivity ) { + + this.ior = ( 1 + 0.4 * reflectivity ) / ( 1 - 0.4 * reflectivity ); + + } + } ); + + this.iridescenceMap = null; + this.iridescenceIOR = 1.3; + this.iridescenceThicknessRange = [ 100, 400 ]; + this.iridescenceThicknessMap = null; + + this.sheenColor = new Color( 0x000000 ); + this.sheenColorMap = null; + this.sheenRoughness = 1.0; + this.sheenRoughnessMap = null; + + this.transmissionMap = null; + + this.thickness = 0; + this.thicknessMap = null; + this.attenuationDistance = Infinity; + this.attenuationColor = new Color( 1, 1, 1 ); + + this.specularIntensity = 1.0; + this.specularIntensityMap = null; + this.specularColor = new Color( 1, 1, 1 ); + this.specularColorMap = null; + + this._sheen = 0.0; + this._clearcoat = 0; + this._iridescence = 0; + 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 = { + + 'STANDARD': '', + 'PHYSICAL': '' + + }; + + this.clearcoat = source.clearcoat; + this.clearcoatMap = source.clearcoatMap; + this.clearcoatRoughness = source.clearcoatRoughness; + this.clearcoatRoughnessMap = source.clearcoatRoughnessMap; + this.clearcoatNormalMap = source.clearcoatNormalMap; + this.clearcoatNormalScale.copy( source.clearcoatNormalScale ); + + this.ior = source.ior; + + this.iridescence = source.iridescence; + this.iridescenceMap = source.iridescenceMap; + this.iridescenceIOR = source.iridescenceIOR; + this.iridescenceThicknessRange = [ ...source.iridescenceThicknessRange ]; + this.iridescenceThicknessMap = source.iridescenceThicknessMap; + + this.sheen = source.sheen; + this.sheenColor.copy( source.sheenColor ); + this.sheenColorMap = source.sheenColorMap; + this.sheenRoughness = source.sheenRoughness; + this.sheenRoughnessMap = source.sheenRoughnessMap; + + this.transmission = source.transmission; + this.transmissionMap = source.transmissionMap; + + this.thickness = source.thickness; + this.thicknessMap = source.thicknessMap; + this.attenuationDistance = source.attenuationDistance; + this.attenuationColor.copy( source.attenuationColor ); + + this.specularIntensity = source.specularIntensity; + this.specularIntensityMap = source.specularIntensityMap; + this.specularColor.copy( source.specularColor ); + this.specularColorMap = source.specularColorMap; + + return this; + + } + +} + +class MeshPhongMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshPhongMaterial = true; + + this.type = 'MeshPhongMaterial'; + + this.color = new Color( 0xffffff ); // diffuse + this.specular = new Color( 0x111111 ); + this.shininess = 30; + + this.map = null; + + this.lightMap = null; + this.lightMapIntensity = 1.0; + + this.aoMap = null; + this.aoMapIntensity = 1.0; + + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.specularMap = null; + + this.alphaMap = null; + + this.envMap = null; + this.combine = MultiplyOperation; + this.reflectivity = 1; + this.refractionRatio = 0.98; + + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + + this.flatShading = false; + + this.fog = true; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.color.copy( source.color ); + this.specular.copy( source.specular ); + this.shininess = source.shininess; + + this.map = source.map; + + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + + this.emissive.copy( source.emissive ); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; + + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.specularMap = source.specularMap; + + this.alphaMap = source.alphaMap; + + this.envMap = source.envMap; + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + + this.flatShading = source.flatShading; + + this.fog = source.fog; + + return this; + + } + +} + +class MeshToonMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshToonMaterial = true; + + this.defines = { 'TOON': '' }; + + this.type = 'MeshToonMaterial'; + + this.color = new Color( 0xffffff ); + + this.map = null; + this.gradientMap = null; + + this.lightMap = null; + this.lightMapIntensity = 1.0; + + this.aoMap = null; + this.aoMapIntensity = 1.0; + + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.alphaMap = null; + + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + + this.fog = true; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.color.copy( source.color ); + + this.map = source.map; + this.gradientMap = source.gradientMap; + + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + + this.emissive.copy( source.emissive ); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; + + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.alphaMap = source.alphaMap; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + + this.fog = source.fog; + + return this; + + } + +} + +class MeshNormalMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshNormalMaterial = true; + + this.type = 'MeshNormalMaterial'; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.wireframe = false; + this.wireframeLinewidth = 1; + + this.flatShading = false; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + + this.flatShading = source.flatShading; + + return this; + + } + +} + +class MeshLambertMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshLambertMaterial = true; + + this.type = 'MeshLambertMaterial'; + + this.color = new Color( 0xffffff ); // diffuse + + this.map = null; + + this.lightMap = null; + this.lightMapIntensity = 1.0; + + this.aoMap = null; + this.aoMapIntensity = 1.0; + + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.specularMap = null; + + this.alphaMap = null; + + this.envMap = null; + this.combine = MultiplyOperation; + this.reflectivity = 1; + this.refractionRatio = 0.98; + + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + + this.flatShading = false; + + this.fog = true; + + 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.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.specularMap = source.specularMap; + + this.alphaMap = source.alphaMap; + + this.envMap = source.envMap; + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + + this.flatShading = source.flatShading; + + this.fog = source.fog; + + return this; + + } + +} + +class MeshMatcapMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshMatcapMaterial = true; + + this.defines = { 'MATCAP': '' }; + + this.type = 'MeshMatcapMaterial'; + + this.color = new Color( 0xffffff ); // diffuse + + this.matcap = null; + + this.map = null; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.alphaMap = null; + + this.flatShading = false; + + this.fog = true; + + this.setValues( parameters ); + + } + + + copy( source ) { + + super.copy( source ); + + this.defines = { 'MATCAP': '' }; + + this.color.copy( source.color ); + + this.matcap = source.matcap; + + this.map = source.map; + + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.alphaMap = source.alphaMap; + + this.flatShading = source.flatShading; + + this.fog = source.fog; + + return this; + + } + +} + +class LineDashedMaterial extends LineBasicMaterial { + + constructor( parameters ) { + + super(); + + this.isLineDashedMaterial = true; + + this.type = 'LineDashedMaterial'; + + this.scale = 1; + this.dashSize = 3; + this.gapSize = 1; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.scale = source.scale; + this.dashSize = source.dashSize; + 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 +function convertArray( array, type, forceClone ) { + + 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 + + } + + return Array.prototype.slice.call( array ); // create Array + +} + +function isTypedArray( object ) { + + return ArrayBuffer.isView( object ) && + ! ( object instanceof DataView ); + +} + +// 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 +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 flattenJSON( jsonKeys, times, values, valuePropertyName ) { + + let i = 1, key = jsonKeys[ 0 ]; + + while ( key !== undefined && key[ valuePropertyName ] === undefined ) { + + key = jsonKeys[ i ++ ]; + + } + + if ( key === undefined ) return; // no data + + let value = key[ valuePropertyName ]; + if ( value === undefined ) return; // no data + + if ( Array.isArray( value ) ) { + + do { + + value = key[ valuePropertyName ]; + + if ( value !== undefined ) { + + times.push( key.time ); + values.push.apply( values, value ); // push all elements + + } + + key = jsonKeys[ i ++ ]; + + } 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; + + // 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 + + 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 + for ( let i = 0; i < numTracks; ++ i ) { + + const referenceTrack = referenceClip.tracks[ i ]; + const referenceTrackType = referenceTrack.ValueTypeName; + + // 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 + if ( referenceTime <= referenceTrack.times[ 0 ] ) { + + // Reference frame is earlier than the first keyframe, so just use the first keyframe + const startIndex = referenceOffset; + const endIndex = referenceValueSize - referenceOffset; + referenceValue = arraySlice( referenceTrack.values, startIndex, endIndex ); + + } else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) { + + // Reference frame is after the last keyframe, so just use the last keyframe + const startIndex = lastIndex * referenceValueSize + referenceOffset; + const endIndex = startIndex + referenceValueSize - referenceOffset; + referenceValue = arraySlice( referenceTrack.values, startIndex, endIndex ); + + } else { + + // Interpolate to the reference value + const interpolant = referenceTrack.createInterpolant(); + const startIndex = referenceOffset; + const endIndex = referenceValueSize - referenceOffset; + interpolant.evaluate( referenceTime ); + referenceValue = arraySlice( interpolant.resultBuffer, startIndex, endIndex ); + + } + + // 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 + + 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 + for ( let k = 0; k < valueEnd; ++ k ) { + + targetTrack.values[ valueStart + k ] -= referenceValue[ k ]; + + } + + } + + } + + } + + targetClip.blendMode = AdditiveAnimationBlendMode; + + return targetClip; + +} + +var AnimationUtils = /*#__PURE__*/Object.freeze({ + __proto__: null, + arraySlice: arraySlice, + convertArray: convertArray, + flattenJSON: flattenJSON, + getKeyframeOrder: getKeyframeOrder, + isTypedArray: isTypedArray, + makeClipAdditive: makeClipAdditive, + sortedArray: sortedArray, + subclip: subclip +}); + +/** + * Abstract base class of interpolants over parametric samples. + * + * The parameter domain is one dimensional, typically the time or a path + * along a curve defined by the data. + * + * The sample values can have any dimensionality and derived classes may + * apply special interpretations to the data. + * + * This class provides the interval seek in a Template Method, deferring + * the actual interpolation to derived classes. + * + * Time complexity is O(1) for linear access crossing at most two points + * and O(log N) for random access, where N is the number of positions. + * + * References: + * + * http://www.oodesign.com/template-method-pattern.html + * + */ + +class Interpolant { + + constructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) { + + this.parameterPositions = parameterPositions; + this._cachedIndex = 0; + + this.resultBuffer = resultBuffer !== undefined ? + resultBuffer : new sampleValues.constructor( sampleSize ); + this.sampleValues = sampleValues; + this.valueSize = sampleSize; + + this.settings = null; + this.DefaultSettings_ = {}; + + } + + evaluate( t ) { + + const pp = this.parameterPositions; + let i1 = this._cachedIndex, + t1 = pp[ i1 ], + t0 = pp[ i1 - 1 ]; + + validate_interval: { + + seek: { + + let right; + + linear_scan: { + + //- See http://jsperf.com/comparison-to-undefined/3 + //- slower code: + //- + //- if ( t >= t1 || t1 === undefined ) { + forward_scan: if ( ! ( t < t1 ) ) { + + for ( let giveUpAt = i1 + 2; ; ) { + + if ( t1 === undefined ) { + + 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 + right = pp.length; + break linear_scan; + + } + + //- slower code: + //- if ( t < t0 || t0 === undefined ) { + if ( ! ( t >= t0 ) ) { + + // looping? + + const t1global = pp[ 1 ]; + + if ( t < t1global ) { + + i1 = 2; // + 1, using the scan for the details + t0 = t1global; + + } + + // 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 + right = i1; + i1 = 0; + break linear_scan; + + } + + // the interval is valid + + break validate_interval; + + } // linear scan + + // 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 + + if ( t0 === undefined ) { + + this._cachedIndex = 0; + return this.copySampleValue_( 0 ); + + } + + if ( t1 === undefined ) { + + i1 = pp.length; + this._cachedIndex = i1; + return this.copySampleValue_( i1 - 1 ); + + } + + } // 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; + + for ( let i = 0; i !== stride; ++ i ) { + + result[ i ] = values[ offset + i ]; + + } + + return result; + + } + + // Template methods for derived classes: + + interpolate_( /* i1, t0, t, t1 */ ) { + + throw new Error( 'call to abstract method' ); + // implementations shall return this.resultBuffer + + } + + intervalChanged_( /* i1, t0, t1 */ ) { + + // empty + + } + +} + +/** + * Fast and simple cubic spline interpolant. + * + * It was derived from a Hermitian construction setting the first derivative + * at each sample position to the linear slope between neighboring positions + * over their parameter interval. + */ + +class CubicInterpolant extends Interpolant { + + constructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) { + + super( parameterPositions, sampleValues, sampleSize, resultBuffer ); + + this._weightPrev = - 0; + this._offsetPrev = - 0; + this._weightNext = - 0; + this._offsetNext = - 0; + + this.DefaultSettings_ = { + + endingStart: ZeroCurvatureEnding, + endingEnd: ZeroCurvatureEnding + + }; + + } + + intervalChanged_( i1, t0, t1 ) { + + const pp = this.parameterPositions; + let iPrev = i1 - 2, + iNext = i1 + 1, + + tPrev = pp[ iPrev ], + tNext = pp[ iNext ]; + + if ( tPrev === undefined ) { + + switch ( this.getSettings_().endingStart ) { + + case ZeroSlopeEnding: + + // f'(t0) = 0 + iPrev = i1; + tPrev = 2 * t0 - t1; + + break; + + case 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: + + // f'(tN) = 0 + iNext = i1; + tNext = 2 * t1 - t0; + + break; + + case WrapAroundEnding: + + // use the other end of the curve + iNext = 1; + tNext = t1 + pp[ 1 ] - pp[ 0 ]; + + break; + + default: // ZeroCurvatureEnding + + // f''(tN) = 0, a.k.a. Natural Spline + iNext = i1 - 1; + tNext = t0; + + } + + } + + const halfDt = ( t1 - t0 ) * 0.5, + stride = this.valueSize; + + this._weightPrev = halfDt / ( t0 - tPrev ); + this._weightNext = halfDt / ( tNext - t1 ); + this._offsetPrev = iPrev * stride; + this._offsetNext = iNext * stride; + + } + + interpolate_( 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 + + 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 + + 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; + + for ( let i = 0; i !== stride; ++ i ) { + + result[ i ] = + values[ offset0 + i ] * weight0 + + values[ offset1 + i ] * weight1; + + } + + return result; + + } + +} + +/** + * + * Interpolant that evaluates to the sample value at the position preceding + * the parameter. + */ + +class DiscreteInterpolant extends Interpolant { + + constructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) { + + super( parameterPositions, sampleValues, sampleSize, resultBuffer ); + + } + + interpolate_( i1 /*, t0, t, t1 */ ) { + + return this.copySampleValue_( i1 - 1 ); + + } + +} + +class KeyframeTrack { + + constructor( name, times, values, interpolation ) { + + if ( name === undefined ) throw new Error( 'THREE.KeyframeTrack: track name is undefined' ); + if ( times === undefined || times.length === 0 ) throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + name ); + + this.name = name; + + this.times = 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): + + static toJSON( track ) { + + const trackType = track.constructor; + + let json; + + // derived classes can define a static toJSON method + if ( trackType.toJSON !== this.toJSON ) { + + json = trackType.toJSON( track ); + + } else { + + // by default, we assume the data can be serialized as-is + json = { + + 'name': track.name, + 'times': convertArray( track.times, Array ), + '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 ) { + + this.setInterpolation( this.DefaultInterpolation ); + + } else { + + throw new Error( message ); // fatal, in this case + + } + + } + + 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 + 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( 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 + trim( startTime, endTime ) { + + const times = this.times, + nKeys = times.length; + + let from = 0, + 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 ) { + + // empty tracks are forbidden, so keep at least one keyframe + if ( from >= to ) { + + 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 + 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; + + 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; + break; + + } + + } + + } + + } + + return valid; + + } + + // removes equivalent sequential keys as common in morph target sequences + // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0) + optimize() { + + // 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; + + 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 + + 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; + + for ( let j = 0; j !== stride; ++ j ) { + + const value = values[ offset + j ]; + + if ( value !== values[ offsetP + j ] || + value !== values[ offsetN + j ] ) { + + keep = true; + break; + + } + + } + + } else { + + keep = true; + + } + + } + + // in-place compaction + + if ( keep ) { + + if ( i !== writeIndex ) { + + times[ writeIndex ] = times[ i ]; + + const readOffset = i * stride, + writeOffset = writeIndex * stride; + + for ( let j = 0; j !== stride; ++ j ) { + + values[ writeOffset + j ] = values[ readOffset + j ]; + + } + + } + + ++ writeIndex; + + } + + } + + // 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 ); + + } else { + + 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. + track.createInterpolant = this.createInterpolant; + + return track; + + } + +} + +KeyframeTrack.prototype.TimeBufferType = Float32Array; +KeyframeTrack.prototype.ValueBufferType = Float32Array; +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; + +/** + * A Track of keyframe values that represent color. + */ +class ColorKeyframeTrack extends KeyframeTrack {} + +ColorKeyframeTrack.prototype.ValueTypeName = 'color'; + +/** + * A Track of numeric keyframe values. + */ +class NumberKeyframeTrack extends KeyframeTrack {} + +NumberKeyframeTrack.prototype.ValueTypeName = 'number'; + +/** + * Spherical linear unit quaternion interpolant. + */ + +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 ); + + 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.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; +StringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined; +StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; + +/** + * A Track of vectored keyframe values. + */ +class VectorKeyframeTrack extends KeyframeTrack {} + +VectorKeyframeTrack.prototype.ValueTypeName = 'vector'; + +class AnimationClip { + + constructor( name, duration = - 1, tracks, blendMode = NormalAnimationBlendMode ) { + + this.name = name; + this.tracks = tracks; + this.duration = duration; + this.blendMode = blendMode; + + 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 ); + + 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; + + const json = { + + 'name': clip.name, + 'duration': clip.duration, + 'tracks': tracks, + '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 = []; + + times.push( + ( i + numMorphTargets - 1 ) % numMorphTargets, + i, + ( i + 1 ) % numMorphTargets ); + + 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. + 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 + // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 + const pattern = /^([\w-]*?)([\d]+)$/; + + // 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 + 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 + 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. + 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 + 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 + // 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': + case 'double': + case 'float': + 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 = []; + + flattenJSON( json.keys, times, values, 'value' ); + + json.times = times; + json.values = values; + + } + + // derived classes can define a static parse method + if ( trackType.parse !== undefined ) { + + return trackType.parse( json ); + + } else { + + // by default, we assume a constructor compatible with the base + return new trackType( json.name, json.times, json.values, json.interpolation ); + + } + +} + +const Cache = { + + enabled: false, + + files: {}, + + add: function ( key, file ) { + + 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 ); + + return this.files[ key ]; + + }, + + remove: function ( key ) { + + delete this.files[ key ]; + + }, + + clear: function () { + + this.files = {}; + + } + +}; + +class LoadingManager { + + constructor( onLoad, onProgress, onError ) { + + const scope = this; + + let isLoading = false; + let itemsLoaded = 0; + let itemsTotal = 0; + let urlModifier = undefined; + 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 ]; + const loader = handlers[ i + 1 ]; + + if ( regex.global ) regex.lastIndex = 0; // see #17920 + + if ( regex.test( file ) ) { + + return loader; + + } + + } + + return null; + + }; + + } + +} + +const DefaultLoadingManager = /*@__PURE__*/ new LoadingManager(); + +class Loader { + + constructor( manager ) { + + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + + this.crossOrigin = 'anonymous'; + this.withCredentials = false; + this.path = ''; + this.resourcePath = ''; + this.requestHeader = {}; + + } + + load( /* url, onLoad, onProgress, onError */ ) {} + + loadAsync( url, onProgress ) { + + const scope = this; + + return new Promise( function ( resolve, reject ) { + + scope.load( url, resolve, onProgress, reject ); + + } ); + + } + + parse( /* data */ ) {} + + 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( () => { + + if ( onLoad ) onLoad( cached ); + + this.manager.itemEnd( url ); + + }, 0 ); + + return cached; + + } + + // Check if request is duplicate + + if ( loading[ url ] !== undefined ) { + + loading[ url ].push( { + + onLoad: onLoad, + onProgress: onProgress, + onError: onError + + } ); + + return; + + } + + // Initialise array for duplicate requests + loading[ url ] = []; + + loading[ url ].push( { + onLoad: onLoad, + onProgress: onProgress, + onError: onError, + } ); + + // 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 ) + const mimeType = this.mimeType; + 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 + + if ( typeof ReadableStream === 'undefined' || response.body === undefined || response.body.getReader === undefined ) { + + return response; + + } + + const callbacks = loading[ url ]; + const reader = response.body.getReader(); + + // 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 + const stream = new ReadableStream( { + start( controller ) { + + readData(); + + function readData() { + + reader.read().then( ( { done, value } ) => { + + if ( done ) { + + controller.close(); + + } else { + + loaded += value.byteLength; + + const event = new ProgressEvent( 'progress', { lengthComputable, 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 { + + throw new HttpError( `fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`, response ); + + } + + } ) + .then( response => { + + 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(); + + } else { + + // sniff encoding + const re = /charset="?([^;"\s]*)"?/i; + const exec = re.exec( mimeType ); + const label = exec && exec[ 1 ] ? exec[ 1 ].toLowerCase() : undefined; + 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 + // error response bodies as proper responses to requests. + 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 ]; + + 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 ); + loader.setPath( this.path ); + loader.setRequestHeader( this.requestHeader ); + loader.setWithCredentials( this.withCredentials ); + loader.load( url, function ( text ) { + + try { + + onLoad( scope.parse( JSON.parse( text ) ) ); + + } catch ( e ) { + + if ( onError ) { + + onError( e ); + + } else { + + console.error( e ); + + } + + scope.manager.itemError( url ); + + } + + }, onProgress, onError ); + + } + + parse( json ) { + + const animations = []; + + for ( let i = 0; i < json.length; i ++ ) { + + const clip = AnimationClip.parse( json[ i ] ); + + animations.push( clip ); + + } + + return animations; + + } + +} + +/** + * Abstract Base class to block based textures loader (dds, pvr, ...) + * + * Sub classes have to implement the parse() method which will be used in load(). + */ + +class CompressedTextureLoader extends Loader { + + constructor( manager ) { + + super( manager ); + + } + + load( url, onLoad, onProgress, onError ) { + + const scope = this; + + const images = []; + + const texture = new CompressedTexture(); + + const loader = new FileLoader( this.manager ); + loader.setPath( this.path ); + loader.setResponseType( 'arraybuffer' ); + 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 ); + + images[ i ] = { + width: texDatas.width, + height: texDatas.height, + format: texDatas.format, + mipmaps: texDatas.mipmaps + }; + + loaded += 1; + + if ( loaded === 6 ) { + + if ( texDatas.mipmapCount === 1 ) texture.minFilter = LinearFilter; + + texture.image = images; + texture.format = texDatas.format; + texture.needsUpdate = true; + + if ( onLoad ) onLoad( texture ); + + } + + }, 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; + images[ f ].width = texDatas.width; + 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 () { + + if ( onLoad ) onLoad( cached ); + + scope.manager.itemEnd( url ); + + }, 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; + + } + +} + +/** + * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...) + * + * Sub classes have to implement the parse() method which will be used in load(). + */ + +class DataTextureLoader extends Loader { + + constructor( manager ) { + + super( manager ); + + } + + load( url, onLoad, onProgress, onError ) { + + const scope = this; + + const texture = new DataTexture(); + + const loader = new FileLoader( this.manager ); + loader.setResponseType( 'arraybuffer' ); + loader.setRequestHeader( this.requestHeader ); + loader.setPath( this.path ); + loader.setWithCredentials( scope.withCredentials ); + loader.load( url, function ( buffer ) { + + const texData = scope.parse( buffer ); + + if ( ! texData ) return; + + if ( texData.image !== undefined ) { + + texture.image = texData.image; + + } else if ( texData.data !== undefined ) { + + texture.image.width = texData.width; + texture.image.height = texData.height; + texture.image.data = texData.data; + + } + + 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... + + } + + 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 ); + loader.setCrossOrigin( this.crossOrigin ); + loader.setPath( this.path ); + + loader.load( url, function ( image ) { + + texture.image = image; + texture.needsUpdate = true; + + if ( onLoad !== undefined ) { + + onLoad( texture ); + + } + + }, onProgress, onError ); + + return texture; + + } + +} + +class Light extends Object3D { + + constructor( color, intensity = 1 ) { + + super(); + + this.isLight = true; + + this.type = 'Light'; + + this.color = new Color( color ); + this.intensity = intensity; + + } + + dispose() { + + // 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(); + data.object.intensity = this.intensity; + + if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex(); + + if ( this.distance !== undefined ) data.object.distance = this.distance; + if ( this.angle !== undefined ) data.object.angle = this.angle; + if ( this.decay !== undefined ) data.object.decay = this.decay; + if ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra; + + if ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON(); + + return data; + + } + +} + +class HemisphereLight extends Light { + + constructor( skyColor, groundColor, intensity ) { + + super( skyColor, intensity ); + + this.isHemisphereLight = true; + + this.type = 'HemisphereLight'; + + this.position.copy( Object3D.DEFAULT_UP ); + 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; + + this.bias = 0; + this.normalBias = 0; + this.radius = 1; + this.blurSamples = 8; + + this.mapSize = new Vector2( 512, 512 ); + + this.map = null; + this.mapPass = null; + this.matrix = new Matrix4(); + + this.autoUpdate = true; + this.needsUpdate = false; + + this._frustum = new Frustum(); + this._frameExtents = new Vector2( 1, 1 ); + + this._viewportCount = 1; + + this._viewports = [ + + new Vector4( 0, 0, 1, 1 ) + + ]; + + } + + 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( _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; + this.radius = source.radius; + + 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; + if ( this.normalBias !== 0 ) object.normalBias = this.normalBias; + if ( this.radius !== 1 ) object.radius = this.radius; + if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray(); + + object.camera = this.camera.toJSON( false ).object; + delete object.camera.matrix; + + return object; + + } + +} + +class SpotLightShadow extends LightShadow { + + constructor() { + + super( new PerspectiveCamera( 50, 1, 0.5, 500 ) ); + + 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 = 2 ) { + + super( color, intensity ); + + this.isSpotLight = true; + + this.type = 'SpotLight'; + + this.position.copy( Object3D.DEFAULT_UP ); + this.updateMatrix(); + + this.target = new Object3D(); + + this.distance = distance; + this.angle = angle; + this.penumbra = penumbra; + 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; + this.angle = source.angle; + this.penumbra = source.penumbra; + this.decay = source.decay; + + this.target = source.target.clone(); + + 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 + // following orientation: + // + // xzXZ + // y Y + // + // X - Positive x direction + // x - Negative x direction + // Y - Positive y direction + // y - Negative y direction + // Z - Positive z direction + // z - Negative z direction + + // positive X + new Vector4( 2, 1, 1, 1 ), + // negative X + new Vector4( 0, 1, 1, 1 ), + // positive Z + new Vector4( 3, 1, 1, 1 ), + // negative Z + new Vector4( 1, 1, 1, 1 ), + // positive Y + new Vector4( 3, 0, 1, 1 ), + // negative Y + new Vector4( 1, 0, 1, 1 ) + ]; + + this._cubeDirections = [ + new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ), + new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 ) + ]; + + this._cubeUps = [ + new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), + new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 ) + ]; + + } + + 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 = 2 ) { + + super( color, intensity ); + + this.isPointLight = true; + + this.type = 'PointLight'; + + this.distance = distance; + 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; + this.decay = source.decay; + + this.shadow = source.shadow.clone(); + + return this; + + } + +} + +class DirectionalLightShadow extends LightShadow { + + constructor() { + + super( new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) ); + + this.isDirectionalLightShadow = true; + + } + +} + +class DirectionalLight extends Light { + + constructor( color, intensity ) { + + super( color, intensity ); + + this.isDirectionalLight = true; + + this.type = 'DirectionalLight'; + + this.position.copy( Object3D.DEFAULT_UP ); + this.updateMatrix(); + + 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 { + + constructor( color, intensity ) { + + super( color, intensity ); + + this.isAmbientLight = true; + + this.type = 'AmbientLight'; + + } + +} + +class RectAreaLight extends Light { + + constructor( color, intensity, width = 10, height = 10 ) { + + super( color, intensity ); + + this.isRectAreaLight = true; + + this.type = 'RectAreaLight'; + + 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; + + } + +} + +/** + * Primary reference: + * https://graphics.stanford.edu/papers/envmap/envmap.pdf + * + * Secondary reference: + * https://www.ppsloan.org/publications/StupidSH36.pdf + */ + +// 3-band SH defined by 9 coefficients + +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 + 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 + target.copy( coeff[ 0 ] ).multiplyScalar( 0.282095 ); + + // band 1 + target.addScaledVector( coeff[ 1 ], 0.488603 * y ); + target.addScaledVector( coeff[ 2 ], 0.488603 * z ); + target.addScaledVector( coeff[ 3 ], 0.488603 * x ); + + // band 2 + target.addScaledVector( coeff[ 4 ], 1.092548 * ( x * y ) ); + target.addScaledVector( coeff[ 5 ], 1.092548 * ( y * z ) ); + target.addScaledVector( coeff[ 6 ], 0.315392 * ( 3.0 * z * z - 1.0 ) ); + target.addScaledVector( coeff[ 7 ], 1.092548 * ( x * z ) ); + target.addScaledVector( coeff[ 8 ], 0.546274 * ( x * x - y * y ) ); + + return target; + + } + + // get the irradiance (radiance convolved with cosine lobe) in the direction of the normal + // target is a Vector3 + // https://graphics.stanford.edu/papers/envmap/envmap.pdf + 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 + target.copy( coeff[ 0 ] ).multiplyScalar( 0.886227 ); // π * 0.282095 + + // band 1 + target.addScaledVector( coeff[ 1 ], 2.0 * 0.511664 * y ); // ( 2 * π / 3 ) * 0.488603 + target.addScaledVector( coeff[ 2 ], 2.0 * 0.511664 * z ); + target.addScaledVector( coeff[ 3 ], 2.0 * 0.511664 * x ); + + // band 2 + target.addScaledVector( coeff[ 4 ], 2.0 * 0.429043 * x * y ); // ( π / 4 ) * 1.092548 + target.addScaledVector( coeff[ 5 ], 2.0 * 0.429043 * y * z ); + target.addScaledVector( coeff[ 6 ], 0.743125 * z * z - 0.247708 ); // ( π / 4 ) * 0.315392 * 3 + target.addScaledVector( coeff[ 7 ], 2.0 * 0.429043 * x * z ); + target.addScaledVector( coeff[ 8 ], 0.429043 * ( x * x - y * y ) ); // ( π / 4 ) * 0.546274 + + return target; + + } + + 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 ] + static getBasisAt( normal, shBasis ) { + + // normal is assumed to be unit length + + const x = normal.x, y = normal.y, z = normal.z; + + // band 0 + shBasis[ 0 ] = 0.282095; + + // band 1 + shBasis[ 1 ] = 0.488603 * y; + shBasis[ 2 ] = 0.488603 * z; + shBasis[ 3 ] = 0.488603 * x; + + // band 2 + shBasis[ 4 ] = 1.092548 * x * y; + shBasis[ 5 ] = 1.092548 * y * z; + shBasis[ 6 ] = 0.315392 * ( 3 * z * z - 1 ); + shBasis[ 7 ] = 1.092548 * x * z; + shBasis[ 8 ] = 0.546274 * ( x * x - y * y ); + + } + +} + +class LightProbe extends Light { + + constructor( sh = new SphericalHarmonics3(), intensity = 1 ) { + + super( undefined, intensity ); + + 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 { + + constructor( manager ) { + + super( manager ); + this.textures = {}; + + } + + load( url, onLoad, onProgress, onError ) { + + const scope = this; + + const loader = new FileLoader( scope.manager ); + loader.setPath( scope.path ); + loader.setRequestHeader( scope.requestHeader ); + loader.setWithCredentials( scope.withCredentials ); + loader.load( url, function ( text ) { + + try { + + onLoad( scope.parse( JSON.parse( text ) ) ); + + } catch ( e ) { + + if ( onError ) { + + onError( e ); + + } else { + + console.error( e ); + + } + + scope.manager.itemError( url ); + + } + + }, onProgress, onError ); + + } + + parse( 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; + if ( json.color !== undefined && material.color !== undefined ) material.color.setHex( json.color ); + if ( json.roughness !== undefined ) material.roughness = json.roughness; + if ( json.metalness !== undefined ) material.metalness = json.metalness; + if ( json.sheen !== undefined ) material.sheen = json.sheen; + if ( json.sheenColor !== undefined ) material.sheenColor = new Color().setHex( json.sheenColor ); + if ( json.sheenRoughness !== undefined ) material.sheenRoughness = json.sheenRoughness; + if ( json.emissive !== undefined && material.emissive !== undefined ) material.emissive.setHex( json.emissive ); + if ( json.specular !== undefined && material.specular !== undefined ) material.specular.setHex( json.specular ); + if ( json.specularIntensity !== undefined ) material.specularIntensity = json.specularIntensity; + if ( json.specularColor !== undefined && material.specularColor !== undefined ) material.specularColor.setHex( json.specularColor ); + if ( json.shininess !== undefined ) material.shininess = json.shininess; + if ( json.clearcoat !== undefined ) material.clearcoat = json.clearcoat; + if ( json.clearcoatRoughness !== undefined ) material.clearcoatRoughness = json.clearcoatRoughness; + if ( json.iridescence !== undefined ) material.iridescence = json.iridescence; + if ( json.iridescenceIOR !== undefined ) material.iridescenceIOR = json.iridescenceIOR; + if ( json.iridescenceThicknessRange !== undefined ) material.iridescenceThicknessRange = json.iridescenceThicknessRange; + if ( json.transmission !== undefined ) material.transmission = json.transmission; + if ( json.thickness !== undefined ) material.thickness = json.thickness; + if ( json.attenuationDistance !== undefined ) material.attenuationDistance = json.attenuationDistance; + if ( json.attenuationColor !== undefined && material.attenuationColor !== undefined ) material.attenuationColor.setHex( json.attenuationColor ); + if ( json.fog !== undefined ) material.fog = json.fog; + if ( json.flatShading !== undefined ) material.flatShading = json.flatShading; + if ( json.blending !== undefined ) material.blending = json.blending; + if ( json.combine !== undefined ) material.combine = json.combine; + if ( json.side !== undefined ) material.side = json.side; + if ( json.shadowSide !== undefined ) material.shadowSide = json.shadowSide; + if ( json.opacity !== undefined ) material.opacity = json.opacity; + if ( json.transparent !== undefined ) material.transparent = json.transparent; + if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest; + if ( json.depthTest !== undefined ) material.depthTest = json.depthTest; + if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite; + if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite; + + if ( json.stencilWrite !== undefined ) material.stencilWrite = json.stencilWrite; + if ( json.stencilWriteMask !== undefined ) material.stencilWriteMask = json.stencilWriteMask; + if ( json.stencilFunc !== undefined ) material.stencilFunc = json.stencilFunc; + if ( json.stencilRef !== undefined ) material.stencilRef = json.stencilRef; + if ( json.stencilFuncMask !== undefined ) material.stencilFuncMask = json.stencilFuncMask; + if ( json.stencilFail !== undefined ) material.stencilFail = json.stencilFail; + if ( json.stencilZFail !== undefined ) material.stencilZFail = json.stencilZFail; + if ( json.stencilZPass !== undefined ) material.stencilZPass = json.stencilZPass; + + if ( json.wireframe !== undefined ) material.wireframe = json.wireframe; + if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth; + if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap; + if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin; + + if ( json.rotation !== undefined ) material.rotation = json.rotation; + + if ( json.linewidth !== 1 ) material.linewidth = json.linewidth; + if ( json.dashSize !== undefined ) material.dashSize = json.dashSize; + if ( json.gapSize !== undefined ) material.gapSize = json.gapSize; + if ( json.scale !== undefined ) material.scale = json.scale; + + if ( json.polygonOffset !== undefined ) material.polygonOffset = json.polygonOffset; + if ( json.polygonOffsetFactor !== undefined ) material.polygonOffsetFactor = json.polygonOffsetFactor; + if ( json.polygonOffsetUnits !== undefined ) material.polygonOffsetUnits = json.polygonOffsetUnits; + + if ( json.dithering !== undefined ) material.dithering = json.dithering; + + if ( json.alphaToCoverage !== undefined ) material.alphaToCoverage = json.alphaToCoverage; + if ( json.premultipliedAlpha !== undefined ) material.premultipliedAlpha = json.premultipliedAlpha; + if ( json.forceSinglePass !== undefined ) material.forceSinglePass = json.forceSinglePass; + + 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 + + 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 ]; + + } + + } + + // for PointsMaterial + + if ( json.size !== undefined ) material.size = json.size; + 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 ); + + if ( json.alphaMap !== undefined ) material.alphaMap = getTexture( json.alphaMap ); + + if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap ); + if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale; + + if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap ); + if ( json.normalMapType !== undefined ) material.normalMapType = json.normalMapType; + 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; + + if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap ); + if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap ); + + if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap ); + if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity; + + if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap ); + if ( json.specularIntensityMap !== undefined ) material.specularIntensityMap = getTexture( json.specularIntensityMap ); + if ( json.specularColorMap !== undefined ) material.specularColorMap = getTexture( json.specularColorMap ); + + if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap ); + if ( json.envMapIntensity !== undefined ) material.envMapIntensity = json.envMapIntensity; + + if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity; + if ( json.refractionRatio !== undefined ) material.refractionRatio = json.refractionRatio; + + if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap ); + if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity; + + if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap ); + if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity; + + if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap ); + + if ( json.clearcoatMap !== undefined ) material.clearcoatMap = getTexture( json.clearcoatMap ); + if ( json.clearcoatRoughnessMap !== undefined ) material.clearcoatRoughnessMap = getTexture( json.clearcoatRoughnessMap ); + if ( json.clearcoatNormalMap !== undefined ) material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap ); + if ( json.clearcoatNormalScale !== undefined ) material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale ); + + if ( json.iridescenceMap !== undefined ) material.iridescenceMap = getTexture( json.iridescenceMap ); + if ( json.iridescenceThicknessMap !== undefined ) material.iridescenceThicknessMap = getTexture( json.iridescenceThicknessMap ); + + if ( json.transmissionMap !== undefined ) material.transmissionMap = getTexture( json.transmissionMap ); + if ( json.thicknessMap !== undefined ) material.thicknessMap = getTexture( json.thicknessMap ); + + if ( json.sheenColorMap !== undefined ) material.sheenColorMap = getTexture( json.sheenColorMap ); + if ( json.sheenRoughnessMap !== undefined ) material.sheenRoughnessMap = getTexture( json.sheenRoughnessMap ); + + return material; + + } + + setTextures( value ) { + + this.textures = value; + return this; + + } + + static createMaterialFromType( type ) { + + const materialLib = { + ShadowMaterial, + SpriteMaterial, + RawShaderMaterial, + ShaderMaterial, + PointsMaterial, + MeshPhysicalMaterial, + MeshStandardMaterial, + MeshPhongMaterial, + MeshToonMaterial, + MeshNormalMaterial, + MeshLambertMaterial, + MeshDepthMaterial, + MeshDistanceMaterial, + MeshBasicMaterial, + MeshMatcapMaterial, + LineDashedMaterial, + LineBasicMaterial, + Material + }; + + 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. + + 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 ( /^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 + if ( /^data:.*,.*$/i.test( url ) ) return url; + + // Blob URL + if ( /^blob:.*$/i.test( url ) ) return url; + + // Relative URL + return path + url; + + } + +} + +class InstancedBufferGeometry extends BufferGeometry { + + constructor() { + + super(); + + this.isInstancedBufferGeometry = true; + + this.type = 'InstancedBufferGeometry'; + this.instanceCount = Infinity; + + } + + copy( source ) { + + super.copy( source ); + + this.instanceCount = source.instanceCount; + + return this; + + } + + toJSON() { + + 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 ); + loader.setPath( scope.path ); + loader.setRequestHeader( scope.requestHeader ); + loader.setWithCredentials( scope.withCredentials ); + loader.load( url, function ( text ) { + + try { + + onLoad( scope.parse( JSON.parse( text ) ) ); + + } catch ( e ) { + + if ( onError ) { + + onError( e ); + + } else { + + console.error( e ); + + } + + scope.manager.itemError( url ); + + } + + }, onProgress, onError ); + + } + + parse( json ) { + + const interleavedBufferMap = {}; + const arrayBufferMap = {}; + + function getInterleavedBuffer( json, uuid ) { + + if ( interleavedBufferMap[ uuid ] !== undefined ) return interleavedBufferMap[ uuid ]; + + const interleavedBuffers = json.interleavedBuffers; + const interleavedBuffer = interleavedBuffers[ uuid ]; + + const buffer = getArrayBuffer( json, interleavedBuffer.buffer ); + + const array = getTypedArray( interleavedBuffer.type, buffer ); + const ib = new InterleavedBuffer( array, interleavedBuffer.stride ); + ib.uuid = interleavedBuffer.uuid; + + interleavedBufferMap[ uuid ] = ib; + + return ib; + + } + + function getArrayBuffer( json, uuid ) { + + if ( arrayBufferMap[ uuid ] !== undefined ) return arrayBufferMap[ uuid ]; + + const arrayBuffers = json.arrayBuffers; + const arrayBuffer = arrayBuffers[ uuid ]; + + const ab = new Uint32Array( arrayBuffer ).buffer; + + 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 ); + + } else { + + const typedArray = getTypedArray( attribute.type, attribute.array ); + 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 ); + + } else { + + 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; + this.resourcePath = this.resourcePath || path; + + const loader = new FileLoader( this.manager ); + loader.setPath( this.path ); + loader.setRequestHeader( this.requestHeader ); + loader.setWithCredentials( this.withCredentials ); + loader.load( url, function ( text ) { + + let json = null; + + try { + + json = JSON.parse( text ); + + } catch ( error ) { + + if ( onError !== undefined ) onError( error ); + + console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message ); + + return; + + } + + 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; + this.resourcePath = this.resourcePath || path; + + const loader = new FileLoader( this.manager ); + loader.setPath( this.path ); + loader.setRequestHeader( this.requestHeader ); + loader.setWithCredentials( this.withCredentials ); + + 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 ); + const geometries = this.parseGeometries( json.geometries, shapes ); + + const images = this.parseImages( json.images, function () { + + if ( onLoad !== undefined ) onLoad( object ); + + } ); + + const textures = this.parseTextures( json.textures, images ); + 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 ); + + // + + 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 ); + const geometries = this.parseGeometries( json.geometries, shapes ); + + const images = await this.parseImagesAsync( json.images ); + + const textures = this.parseTextures( json.textures, images ); + 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 ); + + 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 + + object.traverse( function ( child ) { + + if ( child.isBone ) bones[ child.uuid ] = child; + + } ); + + // create skeletons + + if ( json !== undefined ) { + + for ( let i = 0, l = json.length; i < l; i ++ ) { + + const skeleton = new Skeleton().fromJSON( json[ i ], bones ); + + 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; + + 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 ( 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 ]; + + const clip = AnimationClip.parse( data ); + + 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 () { + + scope.manager.itemEnd( url ); + + }, undefined, function () { + + scope.manager.itemError( url ); + scope.manager.itemEnd( url ); + + } ); + + } + + function deserializeImage( image ) { + + if ( typeof image === 'string' ) { + + const url = image; + + const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url; + + return loadImage( path ); + + } else { + + if ( image.data ) { + + return { + data: getTypedArray( image.type, image.data ), + width: image.width, + height: image.height + }; + + } else { + + return null; + + } + + } + + } + + 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 = []; + + 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; + + const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url; + + return await loader.loadAsync( path ); + + } else { + + if ( image.data ) { + + return { + data: getTypedArray( image.type, image.data ), + width: image.width, + height: image.height + }; + + } else { + + return null; + + } + + } + + } + + 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 = []; + + 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; + + } else { + + if ( image && image.data ) { + + texture = new DataTexture(); + + } else { + + texture = new Texture(); + + } + + if ( image ) texture.needsUpdate = true; // textures can have undefined image data + + } + + texture.source = source; + + texture.uuid = data.uuid; + + if ( data.name !== undefined ) texture.name = data.name; + + if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING ); + + if ( data.offset !== undefined ) texture.offset.fromArray( data.offset ); + if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat ); + if ( data.center !== undefined ) texture.center.fromArray( data.center ); + if ( data.rotation !== undefined ) texture.rotation = data.rotation; + + if ( data.wrap !== undefined ) { + + texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING ); + texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING ); + + } + + if ( data.format !== undefined ) texture.format = data.format; + if ( data.type !== undefined ) texture.type = data.type; + if ( data.encoding !== undefined ) texture.encoding = data.encoding; + + if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER ); + if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER ); + if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy; + + if ( data.flipY !== undefined ) texture.flipY = data.flipY; + + if ( data.generateMipmaps !== undefined ) texture.generateMipmaps = data.generateMipmaps; + if ( data.premultiplyAlpha !== undefined ) texture.premultiplyAlpha = data.premultiplyAlpha; + if ( data.unpackAlignment !== undefined ) texture.unpackAlignment = data.unpackAlignment; + + if ( data.userData !== undefined ) texture.userData = data.userData; + + 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 ); + + } else { + + 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 ); + + } else if ( data.fog.type === 'FogExp2' ) { + + object.fog = new FogExp2( data.fog.color, data.fog.density ); + + } + + } + + if ( data.backgroundBlurriness !== undefined ) object.backgroundBlurriness = data.backgroundBlurriness; + if ( data.backgroundIntensity !== undefined ) object.backgroundIntensity = data.backgroundIntensity; + + break; + + case 'PerspectiveCamera': + + object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far ); + + if ( data.focus !== undefined ) object.focus = data.focus; + if ( data.zoom !== undefined ) object.zoom = data.zoom; + if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge; + if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset; + if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); + + break; + + 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 ); + + object = new SkinnedMesh( geometry, material ); + + if ( data.bindMode !== undefined ) object.bindMode = data.bindMode; + 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 ); + const count = data.count; + const instanceMatrix = data.instanceMatrix; + const instanceColor = data.instanceColor; + + object = new InstancedMesh( geometry, material, count ); + 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; + if ( object.matrixAutoUpdate ) object.matrix.decompose( object.position, object.quaternion, object.scale ); + + } else { + + if ( data.position !== undefined ) object.position.fromArray( data.position ); + if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation ); + if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion ); + if ( data.scale !== undefined ) object.scale.fromArray( data.scale ); + + } + + 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; + if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius; + if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize ); + if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera ); + + } + + 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, 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 { + + child.bind( skeleton, child.bindMatrix ); + + } + + } + + } ); + + } + +} + +const TEXTURE_MAPPING = { + UVMapping: UVMapping, + CubeReflectionMapping: CubeReflectionMapping, + CubeRefractionMapping: CubeRefractionMapping, + EquirectangularReflectionMapping: EquirectangularReflectionMapping, + EquirectangularRefractionMapping: EquirectangularRefractionMapping, + CubeUVReflectionMapping: CubeUVReflectionMapping +}; + +const TEXTURE_WRAPPING = { + RepeatWrapping: RepeatWrapping, + ClampToEdgeWrapping: ClampToEdgeWrapping, + MirroredRepeatWrapping: MirroredRepeatWrapping +}; + +const TEXTURE_FILTER = { + NearestFilter: NearestFilter, + NearestMipmapNearestFilter: NearestMipmapNearestFilter, + NearestMipmapLinearFilter: NearestMipmapLinearFilter, + LinearFilter: LinearFilter, + LinearMipmapNearestFilter: LinearMipmapNearestFilter, + LinearMipmapLinearFilter: LinearMipmapLinearFilter +}; + +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 () { + + if ( onLoad ) onLoad( cached ); + + scope.manager.itemEnd( url ); + + }, 0 ); + + return cached; + + } + + const fetchOptions = {}; + fetchOptions.credentials = ( this.crossOrigin === 'anonymous' ) ? 'same-origin' : 'include'; + fetchOptions.headers = this.requestHeader; + + fetch( url, fetchOptions ).then( function ( res ) { + + return res.blob(); + + } ).then( function ( blob ) { + + return createImageBitmap( blob, Object.assign( scope.options, { colorSpaceConversion: 'none' } ) ); + + } ).then( function ( imageBitmap ) { + + Cache.add( url, imageBitmap ); + + if ( onLoad ) onLoad( imageBitmap ); + + scope.manager.itemEnd( url ); + + } ).catch( function ( e ) { + + if ( onError ) onError( e ); + + scope.manager.itemError( url ); + scope.manager.itemEnd( url ); + + } ); + + scope.manager.itemStart( url ); + + } + +} + +let _context; + +class AudioContext { + + static getContext() { + + if ( _context === undefined ) { + + _context = new ( window.AudioContext || window.webkitAudioContext )(); + + } + + return _context; + + } + + 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 ); + loader.setResponseType( 'arraybuffer' ); + loader.setPath( this.path ); + loader.setRequestHeader( this.requestHeader ); + loader.setWithCredentials( this.withCredentials ); + loader.load( url, function ( buffer ) { + + try { + + // Create a copy of the buffer. The `decodeAudioData` method + // detaches the buffer when complete, preventing reuse. + const bufferCopy = buffer.slice( 0 ); + + const context = AudioContext.getContext(); + context.decodeAudioData( bufferCopy, function ( audioBuffer ) { + + onLoad( audioBuffer ); + + } ); + + } catch ( e ) { + + if ( onError ) { + + onError( e ); + + } else { + + console.error( e ); + + } + + scope.manager.itemError( url ); + + } + + }, onProgress, onError ); + + } + +} + +class HemisphereLightProbe extends LightProbe { + + constructor( skyColor, groundColor, intensity = 1 ) { + + super( undefined, intensity ); + + this.isHemisphereLightProbe = true; + + 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 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 ); + 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'; + + this.aspect = 1; + + this.eyeSep = 0.064; + + this.cameraL = new PerspectiveCamera(); + this.cameraL.layers.enable( 1 ); + this.cameraL.matrixAutoUpdate = false; + + this.cameraR = new PerspectiveCamera(); + this.cameraR.layers.enable( 2 ); + this.cameraR.matrixAutoUpdate = false; + + this._cache = { + focus: null, + fov: null, + aspect: null, + near: null, + far: null, + zoom: null, + eyeSep: null + }; + + } + + 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; + cache.aspect = camera.aspect * this.aspect; + cache.near = camera.near; + cache.far = camera.far; + cache.zoom = camera.zoom; + cache.eyeSep = this.eyeSep; + + // Off-axis stereoscopic effect based on + // http://paulbourke.net/stereographics/stereorender/ + + _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 + + _eyeLeft.elements[ 12 ] = - eyeSepHalf; + _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 + + xmin = - ymax * cache.aspect - eyeSepOnProjection; + xmax = ymax * cache.aspect - eyeSepOnProjection; + + _projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin ); + _projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); + + this.cameraR.projectionMatrix.copy( _projectionMatrix ); + + } + + this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeLeft ); + this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeRight ); + + } + +} + +class Clock { + + constructor( autoStart = true ) { + + this.autoStart = autoStart; + + this.startTime = 0; + this.oldTime = 0; + 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(); + + this.type = 'AudioListener'; + + this.context = AudioContext.getContext(); + + this.gain = this.context.createGain(); + this.gain.connect( this.context.destination ); + + this.filter = null; + + this.timeDelta = 0; + + // private + + this._clock = new Clock(); + + } + + getInput() { + + return this.gain; + + } + + removeFilter() { + + if ( this.filter !== null ) { + + this.gain.disconnect( this.filter ); + this.filter.disconnect( this.context.destination ); + this.gain.connect( this.context.destination ); + this.filter = null; + + } + + return this; + + } + + getFilter() { + + return this.filter; + + } + + setFilter( value ) { + + if ( this.filter !== null ) { + + this.gain.disconnect( this.filter ); + this.filter.disconnect( this.context.destination ); + + } else { + + this.gain.disconnect( this.context.destination ); + + } + + this.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 ); + listener.positionZ.linearRampToValueAtTime( _position$1.z, endTime ); + listener.forwardX.linearRampToValueAtTime( _orientation$1.x, endTime ); + listener.forwardY.linearRampToValueAtTime( _orientation$1.y, endTime ); + listener.forwardZ.linearRampToValueAtTime( _orientation$1.z, endTime ); + listener.upX.linearRampToValueAtTime( up.x, endTime ); + listener.upY.linearRampToValueAtTime( up.y, endTime ); + listener.upZ.linearRampToValueAtTime( up.z, endTime ); + + } else { + + listener.setPosition( _position$1.x, _position$1.y, _position$1.z ); + listener.setOrientation( _orientation$1.x, _orientation$1.y, _orientation$1.z, up.x, up.y, up.z ); + + } + + } + +} + +class Audio extends Object3D { + + constructor( listener ) { + + super(); + + this.type = 'Audio'; + + this.listener = listener; + this.context = listener.context; + + this.gain = this.context.createGain(); + this.gain.connect( listener.getInput() ); + + this.autoplay = false; + + this.buffer = null; + this.detune = 0; + this.loop = false; + this.loopStart = 0; + this.loopEnd = 0; + this.offset = 0; + this.duration = undefined; + this.playbackRate = 1; + this.isPlaying = false; + this.hasPlaybackControl = true; + this.source = null; + this.sourceType = 'empty'; + + this._startedAt = 0; + this._progress = 0; + this._connected = false; + + this.filters = []; + + } + + getOutput() { + + return this.gain; + + } + + setNodeSource( audioNode ) { + + this.hasPlaybackControl = false; + this.sourceType = 'audioNode'; + this.source = audioNode; + this.connect(); + + return this; + + } + + setMediaElementSource( mediaElement ) { + + this.hasPlaybackControl = false; + this.sourceType = 'mediaNode'; + this.source = this.context.createMediaElementSource( mediaElement ); + this.connect(); + + return this; + + } + + setMediaStreamSource( mediaStream ) { + + this.hasPlaybackControl = false; + this.sourceType = 'mediaStreamNode'; + this.source = this.context.createMediaStreamSource( mediaStream ); + 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; + source.loop = this.loop; + source.loopStart = this.loopStart; + source.loopEnd = this.loopEnd; + source.onended = this.onEnded.bind( this ); + source.start( this._startedAt, this._progress + this.offset, this.duration ); + + this.isPlaying = true; + + this.source = source; + + this.setDetune( this.detune ); + this.setPlaybackRate( this.playbackRate ); + + return this.connect(); + + } + + 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; + + 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; + + if ( this.source !== null ) { + + 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(); + this.connect(); + + } else { + + this.filters = value.slice(); + + } + + return this; + + } + + setDetune( value ) { + + this.detune = value; + + if ( this.source.detune === undefined ) return; // only set detune when available + + 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 ); + + this.panner = this.context.createPanner(); + 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 ); + panner.positionZ.linearRampToValueAtTime( _position.z, endTime ); + panner.orientationX.linearRampToValueAtTime( _orientation.x, endTime ); + panner.orientationY.linearRampToValueAtTime( _orientation.y, endTime ); + panner.orientationZ.linearRampToValueAtTime( _orientation.z, endTime ); + + } else { + + panner.setPosition( _position.x, _position.y, _position.z ); + panner.setOrientation( _orientation.x, _orientation.y, _orientation.z ); + + } + + } + +} + +class AudioAnalyser { + + constructor( audio, fftSize = 2048 ) { + + this.analyser = audio.context.createAnalyser(); + this.analyser.fftSize = fftSize; + + 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) ] + // + // interpolators can use .buffer as their .result + // the data then goes to 'incoming' + // + // 'accu0' and 'accu1' are used frame-interleaved for + // the cumulative result and are compared to detect + // changes + // + // 'orig' stores the original state of the property + // + // 'add' is used for additive cumulative results + // + // 'work' is optional and is only present for quaternion types. It is used + // to store intermediate quaternion multiplication results + + switch ( typeName ) { + + case 'quaternion': + mixFunction = this._slerp; + mixFunctionAdditive = this._slerpAdditive; + setIdentity = this._setAdditiveIdentityQuaternion; + + this.buffer = new Float64Array( valueSize * 6 ); + this._workIndex = 5; + break; + + 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 + 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; + this._origIndex = 3; + this._addIndex = 4; + + this.cumulativeWeight = 0; + this.cumulativeWeightAdditive = 0; + + this.useCount = 0; + this.referenceCount = 0; + + } + + // 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; + + 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' + accumulateAdditive( weight ) { + + const buffer = this.buffer, + stride = this.valueSize, + offset = stride * this._addIndex; + + if ( this.cumulativeWeightAdditive === 0 ) { + + // add = identity + + this._setIdentity(); + + } + + // 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( accuIndex ) { + + const stride = this.valueSize, + buffer = this.buffer, + offset = accuIndex * stride + stride, + + weight = this.cumulativeWeight, + weightAdditive = this.cumulativeWeightAdditive, + + binding = this.binding; + + this.cumulativeWeight = 0; + this.cumulativeWeightAdditive = 0; + + if ( weight < 1 ) { + + // accuN := accuN + original * ( 1 - cumulativeWeight ) + + 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 + 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 + for ( let i = stride, e = originalValueOffset; i !== e; ++ i ) { + + buffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ]; + + } + + // Add to identity for additive + this._setIdentity(); + + this.cumulativeWeight = 0; + this.cumulativeWeightAdditive = 0; + + } + + // 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 + + _select( buffer, dstOffset, srcOffset, t, stride ) { + + if ( t >= 0.5 ) { + + for ( let i = 0; i !== stride; ++ i ) { + + buffer[ dstOffset + i ] = buffer[ srcOffset + i ]; + + } + + } + + } + + _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 + 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' ); + +// 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( '\\.', '' ) + ']'; + +// 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 ); + +// 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 ); + +// 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', '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 + 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: +// '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 ); + + 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 ); + + } else { + + return new PropertyBinding.Composite( root, path, parsedPath ); + + } + + } + + /** + * Replaces spaces with underscores and removes unsupported characters from + * node names, to ensure compatibility with parseTrackName(). + * + * @param {string} name Node name to be sanitized. + * @return {string} + */ + 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 ], + objectName: matches[ 3 ], + objectIndex: matches[ 4 ], + propertyName: matches[ 5 ], // required + propertyIndex: matches[ 6 ] }; - this.type = 'MeshToonMaterial'; - this.color = new Color(0xffffff); - this.map = null; - this.gradientMap = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; - this.emissive = new Color(0x000000); - this.emissiveIntensity = 1.0; - this.emissiveMap = null; - this.bumpMap = null; - this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2(1, 1); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.alphaMap = null; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; - this.fog = true; - this.setValues(parameters); + + 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 + // 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. + if ( root.skeleton ) { + + const bone = root.skeleton.getBoneByName( nodeName ); + + if ( bone !== undefined ) { + + return bone; + + } + + } + + // 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 + _getValue_unavailable() {} + _setValue_unavailable() {} + + // 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 + + _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 + + _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 + + _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 + + _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 ); + } - copy(source) { - super.copy(source); - this.color.copy(source.color); - this.map = source.map; - this.gradientMap = source.gradientMap; - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; - this.emissive.copy(source.emissive); - this.emissiveMap = source.emissiveMap; - this.emissiveIntensity = source.emissiveIntensity; - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy(source.normalScale); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.alphaMap = source.alphaMap; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; - this.fog = source.fog; - return this; - } + // 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.node = targetObject; + + } + + // 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 + 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.... + 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. + + 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 + 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 + 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 + 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 ) ) { -} + bindingType = this.BindingType.EntireArray; -class MeshNormalMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshNormalMaterial = true; - this.type = 'MeshNormalMaterial'; - this.bumpMap = null; - this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2(1, 1); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.flatShading = false; - this.setValues(parameters); - } + this.resolvedProperty = nodeProperty; - copy(source) { - super.copy(source); - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy(source.normalScale); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.flatShading = source.flatShading; - return this; - } + } else { -} + this.propertyName = propertyName; -class MeshLambertMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshLambertMaterial = true; - this.type = 'MeshLambertMaterial'; - this.color = new Color(0xffffff); // diffuse + } + + // select getter / setter + this.getValue = this.GetterByBindingType[ bindingType ]; + this.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ]; - this.map = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; - this.emissive = new Color(0x000000); - this.emissiveIntensity = 1.0; - this.emissiveMap = null; - this.specularMap = null; - this.alphaMap = null; - this.envMap = null; - this.combine = MultiplyOperation; - this.reflectivity = 1; - this.refractionRatio = 0.98; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; - this.fog = true; - 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; + unbind() { + + 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; + } } -class MeshMatcapMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshMatcapMaterial = true; - this.defines = { - 'MATCAP': '' - }; - this.type = 'MeshMatcapMaterial'; - this.color = new Color(0xffffff); // diffuse +PropertyBinding.Composite = Composite; - this.matcap = null; - this.map = null; - this.bumpMap = null; - this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2(1, 1); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.alphaMap = null; - this.flatShading = false; - this.fog = true; - this.setValues(parameters); - } +PropertyBinding.prototype.BindingType = { + Direct: 0, + EntireArray: 1, + ArrayElement: 2, + HasFromToArray: 3 +}; + +PropertyBinding.prototype.Versioning = { + None: 0, + NeedsUpdate: 1, + 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._setValue_fromArray, + PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate, + PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate, + + ] + +]; + +/** + * + * A group of objects that receives a shared animation state. + * + * Usage: + * + * - Add objects you would otherwise pass as 'root' to the + * constructor or the .clipAction method of AnimationMixer. + * + * - Instead pass this object as 'root'. + * + * - You can also add and remove objects later when the mixer + * is running. + * + * Note: + * + * Objects of this class appear as one object to the mixer, + * so cache control of the individual objects must be done + * on the group. + * + * Limitation: + * + * - The animated properties must be compatible among the + * all objects in the group. + * + * - A single property can either be controlled through a + * target group or directly, but not both. + */ + +class AnimationObjectGroup { + + constructor() { + + this.isAnimationObjectGroup = true; + + 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 + + const indices = {}; + this._indicesByUUID = indices; // for bookkeeping + + 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; + + this.stats = { + + objects: { + get total() { + + return scope._objects.length; + + }, + get inUse() { + + return this.total - scope.nCachedObjects_; + + } + }, + get bindingsPerObject() { + + return scope._bindings.length; + + } - copy(source) { - super.copy(source); - this.defines = { - 'MATCAP': '' }; - this.color.copy(source.color); - this.matcap = source.matcap; - this.map = source.map; - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy(source.normalScale); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.alphaMap = source.alphaMap; - this.flatShading = source.flatShading; - this.fog = source.fog; - return this; + } -} + add() { + + const objects = this._objects, + indicesByUUID = this._indicesByUUID, + paths = this._paths, + parsedPaths = this._parsedPaths, + bindings = this._bindings, + nBindings = bindings.length; + + let knownObject = undefined, + nObjects = objects.length, + nCachedObjects = this.nCachedObjects_; + + for ( let i = 0, n = arguments.length; i !== n; ++ i ) { + + const object = arguments[ i ], + 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 + + 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 + + const firstActiveIndex = -- nCachedObjects, + lastCachedObject = objects[ firstActiveIndex ]; + + indicesByUUID[ lastCachedObject.uuid ] = index; + objects[ index ] = lastCachedObject; + + indicesByUUID[ uuid ] = firstActiveIndex; + objects[ firstActiveIndex ] = object; + + // accounting is done, now do the same for all bindings + + for ( let j = 0, m = nBindings; j !== m; ++ j ) { + + const bindingsForPath = bindings[ j ], + lastCached = bindingsForPath[ firstActiveIndex ]; -class LineDashedMaterial extends LineBasicMaterial { - constructor(parameters) { - super(); - this.isLineDashedMaterial = true; - this.type = 'LineDashedMaterial'; - this.scale = 1; - this.dashSize = 3; - this.gapSize = 1; - this.setValues(parameters); - } + let binding = bindingsForPath[ index ]; - copy(source) { - super.copy(source); - this.scale = source.scale; - this.dashSize = source.dashSize; - this.gapSize = source.gapSize; - return this; - } + bindingsForPath[ index ] = lastCached; -} + if ( binding === undefined ) { -const materialLib = { - ShadowMaterial, - SpriteMaterial, - RawShaderMaterial, - ShaderMaterial, - PointsMaterial, - MeshPhysicalMaterial, - MeshStandardMaterial, - MeshPhongMaterial, - MeshToonMaterial, - MeshNormalMaterial, - MeshLambertMaterial, - MeshDepthMaterial, - MeshDistanceMaterial, - MeshBasicMaterial, - MeshMatcapMaterial, - LineDashedMaterial, - LineBasicMaterial, - Material -}; + // since we do not bother to create new bindings + // for objects that are cached, the binding may + // or may not exist -Material.fromType = function (type) { - return new materialLib[type](); -}; + binding = new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ); -const AnimationUtils = { - // same as Array.prototype.slice, but also works on typed arrays - arraySlice: function (array, from, to) { - if (AnimationUtils.isTypedArray(array)) { - // in ios9 array.subarray(from, undefined) will return empty array - // but array.subarray(from) or array.subarray(from, len) is correct - return new array.constructor(array.subarray(from, to !== undefined ? to : array.length)); - } + } - return array.slice(from, to); - }, - // converts an array to a specific type - convertArray: function (array, type, forceClone) { - if (!array || // let 'undefined' and 'null' pass - !forceClone && array.constructor === type) return array; + bindingsForPath[ firstActiveIndex ] = binding; - if (typeof type.BYTES_PER_ELEMENT === 'number') { - return new type(array); // create typed array - } + } - return Array.prototype.slice.call(array); // create Array - }, - isTypedArray: function (object) { - return ArrayBuffer.isView(object) && !(object instanceof DataView); - }, - // returns an array by which times and values can be sorted - getKeyframeOrder: function (times) { - function compareTime(i, j) { - return times[i] - times[j]; - } + } else if ( objects[ index ] !== knownObject ) { - const n = times.length; - const result = new Array(n); + console.error( 'THREE.AnimationObjectGroup: Different objects with the same UUID ' + + 'detected. Clean the caches or recreate your infrastructure when reloading scenes.' ); - for (let i = 0; i !== n; ++i) result[i] = i; + } // else the object is already where we want it to be - result.sort(compareTime); - return result; - }, - // uses the array previously returned by 'getKeyframeOrder' to sort data - sortedArray: function (values, stride, order) { - const nValues = values.length; - const result = new values.constructor(nValues); + } // for arguments - for (let i = 0, dstOffset = 0; dstOffset !== nValues; ++i) { - const srcOffset = order[i] * stride; + this.nCachedObjects_ = nCachedObjects; - for (let j = 0; j !== stride; ++j) { - result[dstOffset++] = values[srcOffset + j]; - } - } + } - return result; - }, - // function for parsing AOS keyframe formats - flattenJSON: function (jsonKeys, times, values, valuePropertyName) { - let i = 1, - key = jsonKeys[0]; + remove() { - while (key !== undefined && key[valuePropertyName] === undefined) { - key = jsonKeys[i++]; - } + const objects = this._objects, + indicesByUUID = this._indicesByUUID, + bindings = this._bindings, + nBindings = bindings.length; - if (key === undefined) return; // no data + let nCachedObjects = this.nCachedObjects_; - let value = key[valuePropertyName]; - if (value === undefined) return; // no data + for ( let i = 0, n = arguments.length; i !== n; ++ i ) { - if (Array.isArray(value)) { - do { - value = key[valuePropertyName]; + const object = arguments[ i ], + uuid = object.uuid, + index = indicesByUUID[ uuid ]; - if (value !== undefined) { - times.push(key.time); - values.push.apply(values, value); // push all elements - } + if ( index !== undefined && index >= nCachedObjects ) { - key = jsonKeys[i++]; - } while (key !== undefined); - } else if (value.toArray !== undefined) { - // ...assume THREE.Math-ish - do { - value = key[valuePropertyName]; + // move existing object into the CACHED region - if (value !== undefined) { - times.push(key.time); - value.toArray(values, values.length); - } + const lastCachedIndex = nCachedObjects ++, + firstActiveObject = objects[ lastCachedIndex ]; - key = jsonKeys[i++]; - } while (key !== undefined); - } else { - // otherwise push as-is - do { - value = key[valuePropertyName]; + indicesByUUID[ firstActiveObject.uuid ] = index; + objects[ index ] = firstActiveObject; - if (value !== undefined) { - times.push(key.time); - values.push(value); - } + indicesByUUID[ uuid ] = lastCachedIndex; + objects[ lastCachedIndex ] = object; - key = jsonKeys[i++]; - } while (key !== undefined); - } - }, - subclip: function (sourceClip, name, startFrame, endFrame, fps = 30) { - const clip = sourceClip.clone(); - clip.name = name; - const tracks = []; + // accounting is done, now do the same for all bindings - 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, m = nBindings; j !== m; ++ j ) { + + const bindingsForPath = bindings[ j ], + firstActive = bindingsForPath[ lastCachedIndex ], + binding = bindingsForPath[ index ]; - 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]); + bindingsForPath[ index ] = firstActive; + bindingsForPath[ lastCachedIndex ] = binding; - for (let k = 0; k < valueSize; ++k) { - values.push(track.values[j * valueSize + k]); } + } - if (times.length === 0) continue; - track.times = AnimationUtils.convertArray(times, track.times.constructor); - track.values = AnimationUtils.convertArray(values, track.values.constructor); - tracks.push(track); - } + } // for arguments - clip.tracks = tracks; // find minimum .times value across all tracks in the trimmed clip + this.nCachedObjects_ = nCachedObjects; - 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 + // remove & forget + uncache() { + const objects = this._objects, + indicesByUUID = this._indicesByUUID, + bindings = this._bindings, + nBindings = bindings.length; - for (let i = 0; i < clip.tracks.length; ++i) { - clip.tracks[i].shift(-1 * minStartTime); - } + let nCachedObjects = this.nCachedObjects_, + nObjects = objects.length; - clip.resetDuration(); - return clip; - }, - makeClipAdditive: function (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 + for ( let i = 0, n = arguments.length; i !== n; ++ i ) { - 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 object = arguments[ i ], + uuid = object.uuid, + index = indicesByUUID[ uuid ]; - if (referenceTrackType === 'bool' || referenceTrackType === 'string') continue; // Find the track in the target clip whose name and type matches the reference track + if ( index !== undefined ) { - 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(); + delete indicesByUUID[ uuid ]; - if (referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { - referenceOffset = referenceValueSize / 3; - } + if ( index < nCachedObjects ) { - let targetOffset = 0; - const targetValueSize = targetTrack.getValueSize(); + // object is cached, shrink the CACHED region - if (targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { - targetOffset = targetValueSize / 3; - } + const firstActiveIndex = -- nCachedObjects, + lastCachedObject = objects[ firstActiveIndex ], + lastIndex = -- nObjects, + lastObject = objects[ lastIndex ]; - const lastIndex = referenceTrack.times.length - 1; - let referenceValue; // Find the value to subtract out of the track + // last cached object takes this object's place + indicesByUUID[ lastCachedObject.uuid ] = index; + objects[ index ] = lastCachedObject; - if (referenceTime <= referenceTrack.times[0]) { - // Reference frame is earlier than the first keyframe, so just use the first keyframe - const startIndex = referenceOffset; - const endIndex = referenceValueSize - referenceOffset; - referenceValue = AnimationUtils.arraySlice(referenceTrack.values, startIndex, endIndex); - } else if (referenceTime >= referenceTrack.times[lastIndex]) { - // Reference frame is after the last keyframe, so just use the last keyframe - const startIndex = lastIndex * referenceValueSize + referenceOffset; - const endIndex = startIndex + referenceValueSize - referenceOffset; - referenceValue = AnimationUtils.arraySlice(referenceTrack.values, startIndex, endIndex); - } else { - // Interpolate to the reference value - const interpolant = referenceTrack.createInterpolant(); - const startIndex = referenceOffset; - const endIndex = referenceValueSize - referenceOffset; - interpolant.evaluate(referenceTime); - referenceValue = AnimationUtils.arraySlice(interpolant.resultBuffer, startIndex, endIndex); - } // Conjugate the quaternion + // 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 - if (referenceTrackType === 'quaternion') { - const referenceQuat = new Quaternion().fromArray(referenceValue).normalize().conjugate(); - referenceQuat.toArray(referenceValue); - } // Subtract the reference value from all of the track values + for ( let j = 0, m = nBindings; j !== m; ++ j ) { + const bindingsForPath = bindings[ j ], + lastCached = bindingsForPath[ firstActiveIndex ], + last = bindingsForPath[ lastIndex ]; - const numTimes = targetTrack.times.length; + bindingsForPath[ index ] = lastCached; + bindingsForPath[ firstActiveIndex ] = last; + bindingsForPath.pop(); - 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 - - for (let k = 0; k < valueEnd; ++k) { - targetTrack.values[valueStart + k] -= referenceValue[k]; - } - } - } - } - targetClip.blendMode = AdditiveAnimationBlendMode; - return targetClip; - } -}; + // object is active, just swap with the last and pop -/** - * Abstract base class of interpolants over parametric samples. - * - * The parameter domain is one dimensional, typically the time or a path - * along a curve defined by the data. - * - * The sample values can have any dimensionality and derived classes may - * apply special interpretations to the data. - * - * This class provides the interval seek in a Template Method, deferring - * the actual interpolation to derived classes. - * - * Time complexity is O(1) for linear access crossing at most two points - * and O(log N) for random access, where N is the number of positions. - * - * References: - * - * http://www.oodesign.com/template-method-pattern.html - * - */ -class Interpolant { - constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { - this.parameterPositions = parameterPositions; - this._cachedIndex = 0; - this.resultBuffer = resultBuffer !== undefined ? resultBuffer : new sampleValues.constructor(sampleSize); - this.sampleValues = sampleValues; - this.valueSize = sampleSize; - this.settings = null; - this.DefaultSettings_ = {}; - } + const lastIndex = -- nObjects, + lastObject = objects[ lastIndex ]; - evaluate(t) { - const pp = this.parameterPositions; - let i1 = this._cachedIndex, - t1 = pp[i1], - t0 = pp[i1 - 1]; + if ( lastIndex > 0 ) { - validate_interval: { - seek: { - let right; + indicesByUUID[ lastObject.uuid ] = index; - linear_scan: { - //- See http://jsperf.com/comparison-to-undefined/3 - //- slower code: - //- - //- if ( t >= t1 || t1 === undefined ) { - forward_scan: if (!(t < t1)) { - for (let giveUpAt = i1 + 2;;) { - if (t1 === undefined) { - if (t < t0) break forward_scan; // after end + } - i1 = pp.length; - this._cachedIndex = i1; - return this.copySampleValue_(i1 - 1); - } + objects[ index ] = lastObject; + objects.pop(); - if (i1 === giveUpAt) break; // this loop + // accounting is done, now do the same for all bindings - t0 = t1; - t1 = pp[++i1]; + for ( let j = 0, m = nBindings; j !== m; ++ j ) { - if (t < t1) { - // we have arrived at the sought interval - break seek; - } - } // prepare binary search on the right side of the index + const bindingsForPath = bindings[ j ]; + bindingsForPath[ index ] = bindingsForPath[ lastIndex ]; + bindingsForPath.pop(); - right = pp.length; - break linear_scan; - } //- slower code: - //- if ( t < t0 || t0 === undefined ) { + } + } // cached or active - if (!(t >= t0)) { - // looping? - const t1global = pp[1]; + } // if object is known - if (t < t1global) { - i1 = 2; // + 1, using the scan for the details + } // for arguments - t0 = t1global; - } // linear reverse scan + this.nCachedObjects_ = nCachedObjects; + } - for (let giveUpAt = i1 - 2;;) { - if (t0 === undefined) { - // before start - this._cachedIndex = 0; - return this.copySampleValue_(0); - } + // Internal interface used by befriended PropertyBinding.Composite: - if (i1 === giveUpAt) break; // this loop + subscribe_( path, parsedPath ) { - t1 = t0; - t0 = pp[--i1 - 1]; + // returns an array of bindings for the given path that is changed + // according to the contained objects in the group - if (t >= t0) { - // we have arrived at the sought interval - break seek; - } - } // prepare binary search on the left side of the index + const indicesByPath = this._bindingsIndicesByPath; + let index = indicesByPath[ path ]; + const bindings = this._bindings; + if ( index !== undefined ) return bindings[ index ]; - right = i1; - i1 = 0; - break linear_scan; - } // the interval is valid + const paths = this._paths, + parsedPaths = this._parsedPaths, + objects = this._objects, + nObjects = objects.length, + nCachedObjects = this.nCachedObjects_, + bindingsForPath = new Array( nObjects ); + index = bindings.length; - break validate_interval; - } // linear scan - // binary search + indicesByPath[ path ] = index; + paths.push( path ); + parsedPaths.push( parsedPath ); + bindings.push( bindingsForPath ); - while (i1 < right) { - const mid = i1 + right >>> 1; + for ( let i = nCachedObjects, n = objects.length; i !== n; ++ i ) { - if (t < pp[mid]) { - right = mid; - } else { - i1 = mid + 1; - } - } + const object = objects[ i ]; + bindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath ); - t1 = pp[i1]; - t0 = pp[i1 - 1]; // check boundary cases, again + } - if (t0 === undefined) { - this._cachedIndex = 0; - return this.copySampleValue_(0); - } + return bindingsForPath; - if (t1 === undefined) { - i1 = pp.length; - this._cachedIndex = i1; - return this.copySampleValue_(i1 - 1); - } - } // seek + } + unsubscribe_( path ) { - this._cachedIndex = i1; - this.intervalChanged_(i1, t0, t1); - } // validate_interval + // 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 ]; - return this.interpolate_(i1, t0, t, t1); - } + if ( index !== undefined ) { - getSettings_() { - return this.settings || this.DefaultSettings_; - } + const paths = this._paths, + parsedPaths = this._parsedPaths, + bindings = this._bindings, + lastBindingsIndex = bindings.length - 1, + lastBindings = bindings[ lastBindingsIndex ], + lastBindingsPath = path[ lastBindingsIndex ]; - copySampleValue_(index) { - // copies a sample value to the result buffer - const result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, - offset = index * stride; + indicesByPath[ lastBindingsPath ] = index; - for (let i = 0; i !== stride; ++i) { - result[i] = values[offset + i]; - } + bindings[ index ] = lastBindings; + bindings.pop(); - return result; - } // Template methods for derived classes: + parsedPaths[ index ] = parsedPaths[ lastBindingsIndex ]; + parsedPaths.pop(); + paths[ index ] = paths[ lastBindingsIndex ]; + paths.pop(); - interpolate_() { - throw new Error('call to abstract method'); // implementations shall return this.resultBuffer - } + } - intervalChanged_() {// empty } } -/** - * Fast and simple cubic spline interpolant. - * - * It was derived from a Hermitian construction setting the first derivative - * at each sample position to the linear slope between neighboring positions - * over their parameter interval. - */ +class AnimationAction { -class CubicInterpolant extends Interpolant { - constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { - super(parameterPositions, sampleValues, sampleSize, resultBuffer); - this._weightPrev = -0; - this._offsetPrev = -0; - this._weightNext = -0; - this._offsetNext = -0; - this.DefaultSettings_ = { + constructor( mixer, clip, localRoot = null, blendMode = clip.blendMode ) { + + this._mixer = mixer; + this._clip = clip; + this._localRoot = localRoot; + this.blendMode = blendMode; + + const tracks = clip.tracks, + nTracks = tracks.length, + interpolants = new Array( nTracks ); + + const interpolantSettings = { endingStart: ZeroCurvatureEnding, endingEnd: ZeroCurvatureEnding }; - } - - intervalChanged_(i1, t0, t1) { - const pp = this.parameterPositions; - let iPrev = i1 - 2, - iNext = i1 + 1, - tPrev = pp[iPrev], - tNext = pp[iNext]; - if (tPrev === undefined) { - switch (this.getSettings_().endingStart) { - case ZeroSlopeEnding: - // f'(t0) = 0 - iPrev = i1; - tPrev = 2 * t0 - t1; - break; + for ( let i = 0; i !== nTracks; ++ i ) { - case WrapAroundEnding: - // use the other end of the curve - iPrev = pp.length - 2; - tPrev = t0 + pp[iPrev] - pp[iPrev + 1]; - break; + const interpolant = tracks[ i ].createInterpolant( null ); + interpolants[ i ] = interpolant; + interpolant.settings = interpolantSettings; - default: - // ZeroCurvatureEnding - // f''(t0) = 0 a.k.a. Natural Spline - iPrev = i1; - tPrev = t1; - } } - if (tNext === undefined) { - switch (this.getSettings_().endingEnd) { - case ZeroSlopeEnding: - // f'(tN) = 0 - iNext = i1; - tNext = 2 * t1 - t0; - break; + this._interpolantSettings = interpolantSettings; + + this._interpolants = interpolants; // bound by the mixer + + // inside: PropertyMixer (managed by the mixer) + this._propertyBindings = new Array( nTracks ); + + this._cacheIndex = null; // for the memory manager + 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 + // it's set back to 'null' upon start of the action + this._startTime = null; + + // 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; + + this.weight = 1; + this._effectiveWeight = 1; - case WrapAroundEnding: - // use the other end of the curve - iNext = 1; - tNext = t1 + pp[1] - pp[0]; - break; + this.repetitions = Infinity; // no. of repetitions when looping - default: - // ZeroCurvatureEnding - // f''(tN) = 0, a.k.a. Natural Spline - iNext = i1 - 1; - tNext = t0; - } - } + this.paused = false; // true -> zero effective time scale + this.enabled = true; // false -> zero effective weight - const halfDt = (t1 - t0) * 0.5, - stride = this.valueSize; - this._weightPrev = halfDt / (t0 - tPrev); - this._weightNext = halfDt / (tNext - t1); - this._offsetPrev = iPrev * stride; - this._offsetNext = iNext * stride; - } + this.clampWhenFinished = false;// keep feeding the last frame? - 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 - - 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 - - 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]; - } + this.zeroSlopeAtStart = true;// for smooth interpolation w/o separate + this.zeroSlopeAtEnd = true;// clips for start, loop and end - return result; } -} + // State & Scheduling -class LinearInterpolant extends Interpolant { - constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { - super(parameterPositions, sampleValues, sampleSize, resultBuffer); - } + play() { - 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; + this._mixer._activateAction( this ); - for (let i = 0; i !== stride; ++i) { - result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1; - } + return this; - return result; } -} + stop() { -/** - * - * Interpolant that evaluates to the sample value at the position preceding - * the parameter. - */ + this._mixer._deactivateAction( this ); -class DiscreteInterpolant extends Interpolant { - constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { - super(parameterPositions, sampleValues, sampleSize, resultBuffer); - } + return this.reset(); - interpolate_(i1 - /*, t0, t, t1 */ - ) { - return this.copySampleValue_(i1 - 1); } -} + reset() { -class KeyframeTrack { - constructor(name, times, values, interpolation) { - if (name === undefined) throw new Error('THREE.KeyframeTrack: track name is undefined'); - if (times === undefined || times.length === 0) throw new Error('THREE.KeyframeTrack: no keyframes in track named ' + name); - this.name = name; - this.times = AnimationUtils.convertArray(times, this.TimeBufferType); - this.values = AnimationUtils.convertArray(values, this.ValueBufferType); - this.setInterpolation(interpolation || this.DefaultInterpolation); - } // Serialization (in static context, because of constructor invocation - // and automatic invocation of .toJSON): + this.paused = false; + this.enabled = true; + this.time = 0; // restart clip + this._loopCount = - 1;// forget previous loops + this._startTime = null;// forget scheduling - static toJSON(track) { - const trackType = track.constructor; - let json; // derived classes can define a static toJSON method + return this.stopFading().stopWarping(); - if (trackType.toJSON !== this.toJSON) { - json = trackType.toJSON(track); - } else { - // by default, we assume the data can be serialized as-is - json = { - 'name': track.name, - 'times': AnimationUtils.convertArray(track.times, Array), - 'values': AnimationUtils.convertArray(track.values, Array) - }; - const interpolation = track.getInterpolation(); + } - if (interpolation !== track.DefaultInterpolation) { - json.interpolation = interpolation; - } - } + isRunning() { - json.type = track.ValueTypeName; // mandatory + return this.enabled && ! this.paused && this.timeScale !== 0 && + this._startTime === null && this._mixer._isActiveAction( this ); - return json; } - InterpolantFactoryMethodDiscrete(result) { - return new DiscreteInterpolant(this.times, this.values, this.getValueSize(), result); - } + // return true when play has been called + isScheduled() { - InterpolantFactoryMethodLinear(result) { - return new LinearInterpolant(this.times, this.values, this.getValueSize(), result); - } + return this._mixer._isActiveAction( this ); - InterpolantFactoryMethodSmooth(result) { - return new CubicInterpolant(this.times, this.values, this.getValueSize(), result); } - setInterpolation(interpolation) { - let factoryMethod; - - switch (interpolation) { - case InterpolateDiscrete: - factoryMethod = this.InterpolantFactoryMethodDiscrete; - break; + startAt( time ) { - case InterpolateLinear: - factoryMethod = this.InterpolantFactoryMethodLinear; - break; + this._startTime = time; - case InterpolateSmooth: - factoryMethod = this.InterpolantFactoryMethodSmooth; - break; - } + return this; - 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) { - this.setInterpolation(this.DefaultInterpolation); - } else { - throw new Error(message); // fatal, in this case - } - } + setLoop( mode, repetitions ) { - console.warn('THREE.KeyframeTrack:', message); - return this; - } + this.loop = mode; + this.repetitions = repetitions; - this.createInterpolant = factoryMethod; return this; + } - getInterpolation() { - switch (this.createInterpolant) { - case this.InterpolantFactoryMethodDiscrete: - return InterpolateDiscrete; + // Weight - case this.InterpolantFactoryMethodLinear: - return InterpolateLinear; + // 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._effectiveWeight = this.enabled ? weight : 0; + + return this.stopFading(); - case this.InterpolantFactoryMethodSmooth: - return InterpolateSmooth; - } } - getValueSize() { - return this.values.length / this.times.length; - } // move all keyframes either forwards or backwards in time + // return the weight considering fading and .enabled + getEffectiveWeight() { + return this._effectiveWeight; - shift(timeOffset) { - if (timeOffset !== 0.0) { - const times = this.times; + } - for (let i = 0, n = times.length; i !== n; ++i) { - times[i] += timeOffset; - } - } + fadeIn( duration ) { - return this; - } // scale all keyframe times by a factor (useful for frame <-> seconds conversions) + return this._scheduleFading( duration, 0, 1 ); + } - scale(timeScale) { - if (timeScale !== 1.0) { - const times = this.times; + fadeOut( duration ) { - for (let i = 0, n = times.length; i !== n; ++i) { - times[i] *= timeScale; - } - } + return this._scheduleFading( duration, 1, 0 ); - 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 + } + crossFadeFrom( fadeOutAction, duration, warp ) { - trim(startTime, endTime) { - const times = this.times, - nKeys = times.length; - let from = 0, - to = nKeys - 1; + fadeOutAction.fadeOut( duration ); + this.fadeIn( duration ); - while (from !== nKeys && times[from] < startTime) { - ++from; - } + if ( warp ) { - while (to !== -1 && times[to] > endTime) { - --to; - } + const fadeInDuration = this._clip.duration, + fadeOutDuration = fadeOutAction._clip.duration, - ++to; // inclusive -> exclusive bound + startEndRatio = fadeOutDuration / fadeInDuration, + endStartRatio = fadeInDuration / fadeOutDuration; - if (from !== 0 || to !== nKeys) { - // empty tracks are forbidden, so keep at least one keyframe - if (from >= to) { - to = Math.max(to, 1); - from = to - 1; - } + fadeOutAction.warp( 1.0, startEndRatio, duration ); + this.warp( endStartRatio, 1.0, duration ); - const stride = this.getValueSize(); - this.times = AnimationUtils.arraySlice(times, from, to); - this.values = AnimationUtils.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 - - 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; - } + crossFadeTo( fadeInAction, duration, warp ) { - const times = this.times, - values = this.values, - nKeys = times.length; + return fadeInAction.crossFadeFrom( this, duration, warp ); - if (nKeys === 0) { - console.error('THREE.KeyframeTrack: Track is empty.', this); - valid = false; - } + } - let prevTime = null; + stopFading() { - for (let i = 0; i !== nKeys; i++) { - const currTime = times[i]; + const weightInterpolant = this._weightInterpolant; - if (typeof currTime === 'number' && isNaN(currTime)) { - console.error('THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime); - valid = false; - break; - } + if ( weightInterpolant !== null ) { - if (prevTime !== null && prevTime > currTime) { - console.error('THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime); - valid = false; - break; - } + this._weightInterpolant = null; + this._mixer._takeBackControlInterpolant( weightInterpolant ); - prevTime = currTime; } - if (values !== undefined) { - if (AnimationUtils.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; - break; - } - } - } - } + return this; - 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) + } + // Time Scale Control - optimize() { - // times or values may be shared with other tracks, so overwriting is unsafe - const times = AnimationUtils.arraySlice(this.times), - values = AnimationUtils.arraySlice(this.values), - stride = this.getValueSize(), - smoothInterpolation = this.getInterpolation() === InterpolateSmooth, - lastIndex = times.length - 1; - let writeIndex = 1; + // 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 ) { - 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 + this.timeScale = timeScale; + this._effectiveTimeScale = this.paused ? 0 : timeScale; - 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; + return this.stopWarping(); - for (let j = 0; j !== stride; ++j) { - const value = values[offset + j]; + } - if (value !== values[offsetP + j] || value !== values[offsetN + j]) { - keep = true; - break; - } - } - } else { - keep = true; - } - } // in-place compaction + // return the time scale considering warping and .paused + getEffectiveTimeScale() { + return this._effectiveTimeScale; - if (keep) { - if (i !== writeIndex) { - times[writeIndex] = times[i]; - const readOffset = i * stride, - writeOffset = writeIndex * stride; + } - for (let j = 0; j !== stride; ++j) { - values[writeOffset + j] = values[readOffset + j]; - } - } + setDuration( duration ) { - ++writeIndex; - } - } // flush last keyframe (compaction looks ahead) + this.timeScale = this._clip.duration / duration; + return this.stopWarping(); - 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]; - } + syncWith( action ) { - ++writeIndex; - } + this.time = action.time; + this.timeScale = action.timeScale; - if (writeIndex !== times.length) { - this.times = AnimationUtils.arraySlice(times, 0, writeIndex); - this.values = AnimationUtils.arraySlice(values, 0, writeIndex * stride); - } else { - this.times = times; - this.values = values; - } + return this.stopWarping(); - return this; } - clone() { - const times = AnimationUtils.arraySlice(this.times, 0); - const values = AnimationUtils.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. + halt( duration ) { + + return this.warp( this._effectiveTimeScale, 0, duration ); - track.createInterpolant = this.createInterpolant; - return track; } -} + warp( startTimeScale, endTimeScale, duration ) { -KeyframeTrack.prototype.TimeBufferType = Float32Array; -KeyframeTrack.prototype.ValueBufferType = Float32Array; -KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; + const mixer = this._mixer, + now = mixer.time, + timeScale = this.timeScale; -/** - * A Track of Boolean keyframe values. - */ + let interpolant = this._timeScaleInterpolant; -class BooleanKeyframeTrack extends KeyframeTrack {} + if ( interpolant === null ) { -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 + interpolant = mixer._lendControlInterpolant(); + this._timeScaleInterpolant = interpolant; -/** - * A Track of keyframe values that represent color. - */ + } -class ColorKeyframeTrack extends KeyframeTrack {} + const times = interpolant.parameterPositions, + values = interpolant.sampleValues; -ColorKeyframeTrack.prototype.ValueTypeName = 'color'; // ValueBufferType is inherited + times[ 0 ] = now; + times[ 1 ] = now + duration; -/** - * A Track of numeric keyframe values. - */ + values[ 0 ] = startTimeScale / timeScale; + values[ 1 ] = endTimeScale / timeScale; -class NumberKeyframeTrack extends KeyframeTrack {} + return this; -NumberKeyframeTrack.prototype.ValueTypeName = 'number'; // ValueBufferType is inherited + } -/** - * Spherical linear unit quaternion interpolant. - */ + stopWarping() { -class QuaternionLinearInterpolant extends Interpolant { - constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { - super(parameterPositions, sampleValues, sampleSize, resultBuffer); - } + const timeScaleInterpolant = this._timeScaleInterpolant; - interpolate_(i1, t0, t, t1) { - const result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, - alpha = (t - t0) / (t1 - t0); - let offset = i1 * stride; + if ( timeScaleInterpolant !== null ) { + + this._timeScaleInterpolant = null; + this._mixer._takeBackControlInterpolant( timeScaleInterpolant ); - for (let end = offset + stride; offset !== end; offset += 4) { - Quaternion.slerpFlat(result, 0, values, offset - stride, values, offset, alpha); } - return result; + return this; + + } + + // Object Accessors + + getMixer() { + + return this._mixer; + } -} + getClip() { -/** - * A Track of quaternion keyframe values. - */ + return this._clip; -class QuaternionKeyframeTrack extends KeyframeTrack { - InterpolantFactoryMethodLinear(result) { - return new QuaternionLinearInterpolant(this.times, this.values, this.getValueSize(), result); } -} - -QuaternionKeyframeTrack.prototype.ValueTypeName = 'quaternion'; // ValueBufferType is inherited + getRoot() { -QuaternionKeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; -QuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; + return this._localRoot || this._mixer._root; -/** - * A Track that interpolates Strings - */ + } -class StringKeyframeTrack extends KeyframeTrack {} + // Interna -StringKeyframeTrack.prototype.ValueTypeName = 'string'; -StringKeyframeTrack.prototype.ValueBufferType = Array; -StringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete; -StringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined; -StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; + _update( time, deltaTime, timeDirection, accuIndex ) { -/** - * A Track of vectored keyframe values. - */ + // called by the mixer -class VectorKeyframeTrack extends KeyframeTrack {} + if ( ! this.enabled ) { -VectorKeyframeTrack.prototype.ValueTypeName = 'vector'; // ValueBufferType is inherited + // call ._updateWeight() to update ._effectiveWeight -class AnimationClip { - constructor(name, duration = -1, tracks, blendMode = NormalAnimationBlendMode) { - this.name = name; - 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._updateWeight( time ); + return; - if (this.duration < 0) { - this.resetDuration(); } - } - static parse(json) { - const tracks = [], - jsonTracks = json.tracks, - frameTime = 1.0 / (json.fps || 1.0); + const startTime = this._startTime; - for (let i = 0, n = jsonTracks.length; i !== n; ++i) { - tracks.push(parseKeyframeTrack(jsonTracks[i]).scale(frameTime)); - } + if ( startTime !== null ) { - const clip = new this(json.name, json.duration, tracks, json.blendMode); - clip.uuid = json.uuid; - return clip; - } + // check for scheduled start of action - static toJSON(clip) { - const tracks = [], - clipTracks = clip.tracks; - const json = { - 'name': clip.name, - 'duration': clip.duration, - 'tracks': tracks, - 'uuid': clip.uuid, - 'blendMode': clip.blendMode - }; + const timeRunning = ( time - startTime ) * timeDirection; + if ( timeRunning < 0 || timeDirection === 0 ) { - for (let i = 0, n = clipTracks.length; i !== n; ++i) { - tracks.push(KeyframeTrack.toJSON(clipTracks[i])); - } + deltaTime = 0; - return json; - } + } else { - static CreateFromMorphTargetSequence(name, morphTargetSequence, fps, noLoop) { - const numMorphTargets = morphTargetSequence.length; - const tracks = []; - for (let i = 0; i < numMorphTargets; i++) { - let times = []; - let values = []; - times.push((i + numMorphTargets - 1) % numMorphTargets, i, (i + 1) % numMorphTargets); - values.push(0, 1, 0); - const order = AnimationUtils.getKeyframeOrder(times); - times = AnimationUtils.sortedArray(times, 1, order); - values = AnimationUtils.sortedArray(values, 1, order); // if there is a key at the first frame, duplicate it as the - // last frame as well for perfect loop. + this._startTime = null; // unschedule + deltaTime = timeDirection * timeRunning; - 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); - } + // apply time scale and advance time - static findByName(objectOrClipArray, name) { - let clipArray = objectOrClipArray; + deltaTime *= this._updateTimeScale( time ); + const clipTime = this._updateTime( deltaTime ); - if (!Array.isArray(objectOrClipArray)) { - const o = objectOrClipArray; - clipArray = o.geometry && o.geometry.animations || o.animations; - } + // note: _updateTime may disable the action resulting in + // an effective weight of 0 - for (let i = 0; i < clipArray.length; i++) { - if (clipArray[i].name === name) { - return clipArray[i]; - } - } + const weight = this._updateWeight( time ); - return null; - } + if ( weight > 0 ) { - static CreateClipsFromMorphTargetSequences(morphTargets, fps, noLoop) { - const animationToMorphTargets = {}; // tested with https://regex101.com/ on trick sequences - // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 + const interpolants = this._interpolants; + const propertyMixers = this._propertyBindings; - const pattern = /^([\w-]*?)([\d]+)$/; // sort morph target names into animation groups based - // patterns like Walk_001, Walk_002, Run_001, Run_002 + switch ( this.blendMode ) { - for (let i = 0, il = morphTargets.length; i < il; i++) { - const morphTarget = morphTargets[i]; - const parts = morphTarget.name.match(pattern); + case AdditiveAnimationBlendMode: - if (parts && parts.length > 1) { - const name = parts[1]; - let animationMorphTargets = animationToMorphTargets[name]; + for ( let j = 0, m = interpolants.length; j !== m; ++ j ) { - if (!animationMorphTargets) { - animationToMorphTargets[name] = animationMorphTargets = []; - } + interpolants[ j ].evaluate( clipTime ); + propertyMixers[ j ].accumulateAdditive( weight ); - animationMorphTargets.push(morphTarget); - } - } + } - const clips = []; + break; - for (const name in animationToMorphTargets) { - clips.push(this.CreateFromMorphTargetSequence(name, animationToMorphTargets[name], fps, noLoop)); - } + case NormalAnimationBlendMode: + default: - return clips; - } // parse the animation.hierarchy format + for ( let j = 0, m = interpolants.length; j !== m; ++ j ) { + interpolants[ j ].evaluate( clipTime ); + propertyMixers[ j ].accumulate( accuIndex, weight ); + + } + + } - 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 = []; - AnimationUtils.flattenJSON(animationKeys, times, values, propertyName); // empty keys are filtered out, so check again + } - if (times.length !== 0) { - destTracks.push(new trackType(trackName, times, values)); - } - } - }; + _updateWeight( time ) { - const tracks = []; - const clipName = animation.name || 'default'; - const fps = animation.fps || 30; - const blendMode = animation.blendMode; // automatic length determination in AnimationClip. + let weight = 0; - let duration = animation.length || -1; - const hierarchyTracks = animation.hierarchy || []; + if ( this.enabled ) { - for (let h = 0; h < hierarchyTracks.length; h++) { - const animationKeys = hierarchyTracks[h].keys; // skip empty tracks + weight = this.weight; + const interpolant = this._weightInterpolant; - if (!animationKeys || animationKeys.length === 0) continue; // process morph targets + if ( interpolant !== null ) { - if (animationKeys[0].morphTargets) { - // figure out all morph targets used in this track - const morphTargetNames = {}; - let k; + const interpolantValue = interpolant.evaluate( time )[ 0 ]; - 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 - // morphTargetInfluences except for the keys in which - // the morphTarget is named. + weight *= interpolantValue; + if ( time > interpolant.parameterPositions[ 1 ] ) { - for (const morphTargetName in morphTargetNames) { - const times = []; - const values = []; + this.stopFading(); + + if ( interpolantValue === 0 ) { + + // faded out, disable + this.enabled = false; - 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._effectiveWeight = weight; + return weight; - this.duration = duration; - return this; } - trim() { - for (let i = 0; i < this.tracks.length; i++) { - this.tracks[i].trim(0, this.duration); - } + _updateTimeScale( time ) { - return this; - } + let timeScale = 0; - validate() { - let valid = true; + if ( ! this.paused ) { - for (let i = 0; i < this.tracks.length; i++) { - valid = valid && this.tracks[i].validate(); - } + timeScale = this.timeScale; - return valid; - } + const interpolant = this._timeScaleInterpolant; - optimize() { - for (let i = 0; i < this.tracks.length; i++) { - this.tracks[i].optimize(); - } + if ( interpolant !== null ) { - return this; - } + const interpolantValue = interpolant.evaluate( time )[ 0 ]; - clone() { - const tracks = []; + timeScale *= interpolantValue; - for (let i = 0; i < this.tracks.length; i++) { - tracks.push(this.tracks[i].clone()); - } + if ( time > interpolant.parameterPositions[ 1 ] ) { - return new this.constructor(this.name, this.duration, tracks, this.blendMode); - } + this.stopWarping(); - toJSON() { - return this.constructor.toJSON(this); - } + if ( timeScale === 0 ) { -} + // motion has halted, pause + this.paused = true; -function getTrackTypeForValueTypeName(typeName) { - switch (typeName.toLowerCase()) { - case 'scalar': - case 'double': - case 'float': - case 'number': - case 'integer': - return NumberKeyframeTrack; + } else { - case 'vector': - case 'vector2': - case 'vector3': - case 'vector4': - return VectorKeyframeTrack; + // warp done - apply final time scale + this.timeScale = timeScale; - 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); -} + this._effectiveTimeScale = timeScale; + return timeScale; -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 = []; - AnimationUtils.flattenJSON(json.keys, times, values, 'value'); - json.times = times; - json.values = values; - } // derived classes can define a static parse method + _updateTime( deltaTime ) { + const duration = this._clip.duration; + const loop = this.loop; - if (trackType.parse !== undefined) { - return trackType.parse(json); - } else { - // by default, we assume a constructor compatible with the base - return new trackType(json.name, json.times, json.values, json.interpolation); - } -} + let time = this.time + deltaTime; + let loopCount = this._loopCount; -const Cache = { - enabled: false, - files: {}, - add: function (key, file) { - if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Adding key:', key ); + const pingPong = ( loop === LoopPingPong ); - this.files[key] = file; - }, - get: function (key) { - if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Checking key:', key ); + if ( deltaTime === 0 ) { - return this.files[key]; - }, - remove: function (key) { - delete this.files[key]; - }, - clear: function () { - this.files = {}; - } -}; + if ( loopCount === - 1 ) return time; -class LoadingManager { - constructor(onLoad, onProgress, onError) { - const scope = this; - let isLoading = false; - let itemsLoaded = 0; - let itemsTotal = 0; - let urlModifier = undefined; - const handlers = []; // Refer to #5689 for the reason why we don't set .onStart - // in the constructor + return ( pingPong && ( loopCount & 1 ) === 1 ) ? duration - time : time; - this.onStart = undefined; - this.onLoad = onLoad; - this.onProgress = onProgress; - this.onError = onError; + } - this.itemStart = function (url) { - itemsTotal++; + if ( loop === LoopOnce ) { - if (isLoading === false) { - if (scope.onStart !== undefined) { - scope.onStart(url, itemsLoaded, itemsTotal); - } - } + if ( loopCount === - 1 ) { - isLoading = true; - }; + // just started - this.itemEnd = function (url) { - itemsLoaded++; + this._loopCount = 0; + this._setEndings( true, true, false ); - if (scope.onProgress !== undefined) { - scope.onProgress(url, itemsLoaded, itemsTotal); } - if (itemsLoaded === itemsTotal) { - isLoading = false; + handle_stop: { - if (scope.onLoad !== undefined) { - scope.onLoad(); - } - } - }; + if ( time >= duration ) { - this.itemError = function (url) { - if (scope.onError !== undefined) { - scope.onError(url); - } - }; + time = duration; - this.resolveURL = function (url) { - if (urlModifier) { - return urlModifier(url); - } + } else if ( time < 0 ) { - return url; - }; + time = 0; - this.setURLModifier = function (transform) { - urlModifier = transform; - return this; - }; + } else { - this.addHandler = function (regex, loader) { - handlers.push(regex, loader); - return this; - }; + this.time = time; + + break handle_stop; - this.removeHandler = function (regex) { - const index = handlers.indexOf(regex); + } - if (index !== -1) { - handlers.splice(index, 2); - } + if ( this.clampWhenFinished ) this.paused = true; + else this.enabled = false; - return this; - }; + this.time = time; - this.getHandler = function (file) { - for (let i = 0, l = handlers.length; i < l; i += 2) { - const regex = handlers[i]; - const loader = handlers[i + 1]; - if (regex.global) regex.lastIndex = 0; // see #17920 + this._mixer.dispatchEvent( { + type: 'finished', action: this, + direction: deltaTime < 0 ? - 1 : 1 + } ); - if (regex.test(file)) { - return loader; - } } - return null; - }; - } + } else { // repetitive Repeat or PingPong -} + if ( loopCount === - 1 ) { -const DefaultLoadingManager = new LoadingManager(); + // just started -class Loader { - constructor(manager) { - this.manager = manager !== undefined ? manager : DefaultLoadingManager; - this.crossOrigin = 'anonymous'; - this.withCredentials = false; - this.path = ''; - this.resourcePath = ''; - this.requestHeader = {}; - } + if ( deltaTime >= 0 ) { - load() {} + loopCount = 0; - loadAsync(url, onProgress) { - const scope = this; - return new Promise(function (resolve, reject) { - scope.load(url, resolve, onProgress, reject); - }); - } + this._setEndings( true, this.repetitions === 0, pingPong ); - parse() {} + } else { - setCrossOrigin(crossOrigin) { - this.crossOrigin = crossOrigin; - return this; - } + // when looping in reverse direction, the initial + // transition through zero counts as a repetition, + // so leave loopCount at -1 - setWithCredentials(value) { - this.withCredentials = value; - return this; - } + this._setEndings( this.repetitions === 0, true, pingPong ); - setPath(path) { - this.path = path; - return this; - } + } - setResourcePath(resourcePath) { - this.resourcePath = resourcePath; - return this; - } + } - setRequestHeader(requestHeader) { - this.requestHeader = requestHeader; - return this; - } + if ( time >= duration || time < 0 ) { -} + // wrap around -const loading = {}; + const loopDelta = Math.floor( time / duration ); // signed + time -= duration * loopDelta; -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(() => { - if (onLoad) onLoad(cached); - this.manager.itemEnd(url); - }, 0); - return cached; - } // Check if request is duplicate + loopCount += Math.abs( loopDelta ); + const pending = this.repetitions - loopCount; - if (loading[url] !== undefined) { - loading[url].push({ - onLoad: onLoad, - onProgress: onProgress, - onError: onError - }); - return; - } // Initialise array for duplicate requests + if ( pending <= 0 ) { + // have to stop (switch state, clamp time, fire event) - loading[url] = []; - loading[url].push({ - onLoad: onLoad, - onProgress: onProgress, - onError: onError - }); // create request + if ( this.clampWhenFinished ) this.paused = true; + else this.enabled = false; - 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 + time = deltaTime > 0 ? duration : 0; - }); // record states ( avoid data race ) + this.time = time; - const mimeType = this.mimeType; - 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 - - - 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'); - const total = contentLength ? parseInt(contentLength) : 0; - const lengthComputable = total !== 0; - 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, - value - }) => { - if (done) { - controller.close(); - } else { - loaded += value.byteLength; - const event = new ProgressEvent('progress', { - lengthComputable, - loaded, - total - }); - - for (let i = 0, il = callbacks.length; i < il; i++) { - const callback = callbacks[i]; - if (callback.onProgress) callback.onProgress(event); - } + this._mixer.dispatchEvent( { + type: 'finished', action: this, + direction: deltaTime > 0 ? 1 : - 1 + } ); - controller.enqueue(value); - readData(); - } - }); - } - } + } else { - }); - return new Response(stream); - } else { - throw Error(`fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`); - } - }).then(response => { - switch (responseType) { - case 'arraybuffer': - return response.arrayBuffer(); + // keep running - case 'blob': - return response.blob(); + if ( pending === 1 ) { - case 'document': - return response.text().then(text => { - const parser = new DOMParser(); - return parser.parseFromString(text, mimeType); - }); + // entering the last round - case 'json': - return response.json(); + const atStart = deltaTime < 0; + this._setEndings( atStart, ! atStart, pingPong ); - default: - if (mimeType === undefined) { - return response.text(); } else { - // sniff encoding - const re = /charset="?([^;"\s]*)"?/i; - const exec = re.exec(mimeType); - const label = exec && exec[1] ? exec[1].toLowerCase() : undefined; - const decoder = new TextDecoder(label); - return response.arrayBuffer().then(ab => decoder.decode(ab)); + + this._setEndings( false, false, pingPong ); + } - } - }).then(data => { - // Add to cache only on HTTP success, so that we do not cache - // error response bodies as proper responses to requests. - Cache.add(url, data); - const callbacks = loading[url]; - delete loading[url]; + this._loopCount = loopCount; - 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]; + this.time = time; - if (callbacks === undefined) { - // When onLoad was called and url was deleted in `loading` - this.manager.itemError(url); - throw err; - } + this._mixer.dispatchEvent( { + type: 'loop', action: this, loopDelta: loopDelta + } ); - delete loading[url]; + } + + } else { + + this.time = time; - 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); - } + if ( pingPong && ( loopCount & 1 ) === 1 ) { - setResponseType(value) { - this.responseType = value; - return this; - } + // invert time for the "pong round" - setMimeType(value) { - this.mimeType = value; - return this; - } + return duration - time; -} + } -class AnimationLoader extends Loader { - constructor(manager) { - super(manager); - } + } - load(url, onLoad, onProgress, onError) { - const scope = this; - const loader = new FileLoader(this.manager); - loader.setPath(this.path); - loader.setRequestHeader(this.requestHeader); - loader.setWithCredentials(this.withCredentials); - loader.load(url, function (text) { - try { - onLoad(scope.parse(JSON.parse(text))); - } catch (e) { - if (onError) { - onError(e); - } else { - console.error(e); - } + return time; - scope.manager.itemError(url); - } - }, onProgress, onError); } - parse(json) { - const animations = []; + _setEndings( atStart, atEnd, pingPong ) { - for (let i = 0; i < json.length; i++) { - const clip = AnimationClip.parse(json[i]); - animations.push(clip); - } + const settings = this._interpolantSettings; - return animations; - } + if ( pingPong ) { -} + settings.endingStart = ZeroSlopeEnding; + settings.endingEnd = ZeroSlopeEnding; -/** - * Abstract Base class to block based textures loader (dds, pvr, ...) - * - * Sub classes have to implement the parse() method which will be used in load(). - */ + } else { -class CompressedTextureLoader extends Loader { - constructor(manager) { - super(manager); - } + // assuming for LoopOnce atStart == atEnd == true - load(url, onLoad, onProgress, onError) { - const scope = this; - const images = []; - const texture = new CompressedTexture(); - const loader = new FileLoader(this.manager); - loader.setPath(this.path); - loader.setResponseType('arraybuffer'); - loader.setRequestHeader(this.requestHeader); - loader.setWithCredentials(scope.withCredentials); - let loaded = 0; + if ( atStart ) { - function loadTexture(i) { - loader.load(url[i], function (buffer) { - const texDatas = scope.parse(buffer, true); - images[i] = { - width: texDatas.width, - height: texDatas.height, - format: texDatas.format, - mipmaps: texDatas.mipmaps - }; - loaded += 1; + settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding; - if (loaded === 6) { - if (texDatas.mipmapCount === 1) texture.minFilter = LinearFilter; - texture.image = images; - texture.format = texDatas.format; - texture.needsUpdate = true; - if (onLoad) onLoad(texture); - } - }, onProgress, onError); - } + } else { + + settings.endingStart = WrapAroundEnding; - 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; + if ( atEnd ) { - for (let f = 0; f < faces; f++) { - images[f] = { - mipmaps: [] - }; + settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; - for (let i = 0; i < texDatas.mipmapCount; i++) { - images[f].mipmaps.push(texDatas.mipmaps[f * texDatas.mipmapCount + i]); - images[f].format = texDatas.format; - images[f].width = texDatas.width; - images[f].height = texDatas.height; - } - } + } else { - texture.image = images; - } else { - texture.image.width = texDatas.width; - texture.image.height = texDatas.height; - texture.mipmaps = texDatas.mipmaps; - } + settings.endingEnd = WrapAroundEnding; - 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); - } + _scheduleFading( duration, weightNow, weightThen ) { - 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 () { - if (onLoad) onLoad(cached); - scope.manager.itemEnd(url); - }, 0); - return cached; - } + const mixer = this._mixer, now = mixer.time; + let interpolant = this._weightInterpolant; - const image = createElementNS('img'); + if ( interpolant === null ) { - function onImageLoad() { - removeEventListeners(); - Cache.add(url, this); - if (onLoad) onLoad(this); - scope.manager.itemEnd(url); - } + interpolant = mixer._lendControlInterpolant(); + this._weightInterpolant = interpolant; - 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); - } + const times = interpolant.parameterPositions, + values = interpolant.sampleValues; - image.addEventListener('load', onImageLoad, false); - image.addEventListener('error', onImageError, false); + times[ 0 ] = now; + values[ 0 ] = weightNow; + times[ 1 ] = now + duration; + values[ 1 ] = weightThen; - if (url.slice(0, 5) !== 'data:') { - if (this.crossOrigin !== undefined) image.crossOrigin = this.crossOrigin; - } + return this; - scope.manager.itemStart(url); - image.src = url; - return image; } } -class CubeTextureLoader extends Loader { - constructor(manager) { - super(manager); - } +const _controlInterpolantsResultBuffer = new Float32Array( 1 ); - 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++; +class AnimationMixer extends EventDispatcher { - if (loaded === 6) { - texture.needsUpdate = true; - if (onLoad) onLoad(texture); - } - }, undefined, onError); - } + constructor( root ) { - for (let i = 0; i < urls.length; ++i) { - loadTexture(i); - } + super(); + + this._root = root; + this._initMemoryManager(); + this._accuIndex = 0; + this.time = 0; + this.timeScale = 1.0; - return texture; } -} + _bindAction( action, prototypeAction ) { -/** - * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...) - * - * Sub classes have to implement the parse() method which will be used in load(). - */ + 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; -class DataTextureLoader extends Loader { - constructor(manager) { - super(manager); - } + let bindingsByName = bindingsByRoot[ rootUuid ]; - load(url, onLoad, onProgress, onError) { - const scope = this; - const texture = new DataTexture(); - const loader = new FileLoader(this.manager); - loader.setResponseType('arraybuffer'); - loader.setRequestHeader(this.requestHeader); - loader.setPath(this.path); - loader.setWithCredentials(scope.withCredentials); - loader.load(url, function (buffer) { - const texData = scope.parse(buffer); - if (!texData) return; - - if (texData.image !== undefined) { - texture.image = texData.image; - } else if (texData.data !== undefined) { - texture.image.width = texData.width; - texture.image.height = texData.height; - texture.image.data = texData.data; - } + if ( bindingsByName === undefined ) { - 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; + bindingsByName = {}; + bindingsByRoot[ rootUuid ] = bindingsByName; - if (texData.encoding !== undefined) { - texture.encoding = texData.encoding; - } + } - if (texData.flipY !== undefined) { - texture.flipY = texData.flipY; - } + for ( let i = 0; i !== nTracks; ++ i ) { - if (texData.format !== undefined) { - texture.format = texData.format; - } + const track = tracks[ i ], + trackName = track.name; - if (texData.type !== undefined) { - texture.type = texData.type; - } + let binding = bindingsByName[ trackName ]; - if (texData.mipmaps !== undefined) { - texture.mipmaps = texData.mipmaps; - texture.minFilter = LinearMipmapLinearFilter; // presumably... - } + if ( binding !== undefined ) { - if (texData.mipmapCount === 1) { - texture.minFilter = LinearFilter; - } + ++ binding.referenceCount; + bindings[ i ] = binding; - if (texData.generateMipmaps !== undefined) { - texture.generateMipmaps = texData.generateMipmaps; - } + } else { - texture.needsUpdate = true; - if (onLoad) onLoad(texture, texData); - }, onProgress, onError); - return texture; - } + binding = bindings[ i ]; -} + if ( binding !== undefined ) { -class TextureLoader extends Loader { - constructor(manager) { - super(manager); - } + // existing binding, make sure the cache knows - load(url, onLoad, onProgress, onError) { - const texture = new Texture(); - const loader = new ImageLoader(this.manager); - loader.setCrossOrigin(this.crossOrigin); - loader.setPath(this.path); - loader.load(url, function (image) { - texture.image = image; - texture.needsUpdate = true; + if ( binding._cacheIndex === null ) { - if (onLoad !== undefined) { - onLoad(texture); - } - }, onProgress, onError); - return texture; - } + ++ binding.referenceCount; + this._addInactiveBinding( binding, rootUuid, trackName ); + + } + + continue; + + } -} + const path = prototypeAction && prototypeAction. + _propertyBindings[ i ].binding.parsedPath; -class Light extends Object3D { - constructor(color, intensity = 1) { - super(); - this.isLight = true; - this.type = 'Light'; - this.color = new Color(color); - this.intensity = intensity; - } + binding = new PropertyMixer( + PropertyBinding.create( root, trackName, path ), + track.ValueTypeName, track.getValueSize() ); - dispose() {// Empty here in base class; some subclasses override. - } + ++ binding.referenceCount; + this._addInactiveBinding( binding, rootUuid, trackName ); - copy(source, recursive) { - super.copy(source, recursive); - this.color.copy(source.color); - this.intensity = source.intensity; - return this; - } + bindings[ i ] = binding; - toJSON(meta) { - const data = super.toJSON(meta); - data.object.color = this.color.getHex(); - data.object.intensity = this.intensity; - if (this.groundColor !== undefined) data.object.groundColor = this.groundColor.getHex(); - if (this.distance !== undefined) data.object.distance = this.distance; - if (this.angle !== undefined) data.object.angle = this.angle; - if (this.decay !== undefined) data.object.decay = this.decay; - if (this.penumbra !== undefined) data.object.penumbra = this.penumbra; - if (this.shadow !== undefined) data.object.shadow = this.shadow.toJSON(); - return data; - } + } -} + interpolants[ i ].resultBuffer = binding.buffer; -class HemisphereLight extends Light { - constructor(skyColor, groundColor, intensity) { - super(skyColor, intensity); - this.isHemisphereLight = true; - this.type = 'HemisphereLight'; - this.position.copy(Object3D.DefaultUp); - 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(); + _activateAction( action ) { -const _lightPositionWorld$1 = /*@__PURE__*/new Vector3(); + if ( ! this._isActiveAction( action ) ) { -const _lookTarget$1 = /*@__PURE__*/new Vector3(); + if ( action._cacheIndex === null ) { -class LightShadow { - constructor(camera) { - this.camera = camera; - this.bias = 0; - this.normalBias = 0; - this.radius = 1; - this.blurSamples = 8; - this.mapSize = new Vector2(512, 512); - this.map = null; - this.mapPass = null; - this.matrix = new Matrix4(); - this.autoUpdate = true; - this.needsUpdate = false; - this._frustum = new Frustum(); - this._frameExtents = new Vector2(1, 1); - this._viewportCount = 1; - this._viewports = [new Vector4(0, 0, 1, 1)]; - } + // this action has been forgotten by the cache, but the user + // appears to be still using it -> rebind - getViewportCount() { - return this._viewportCount; - } + const rootUuid = ( action._localRoot || this._root ).uuid, + clipUuid = action._clip.uuid, + actionsForClip = this._actionsByClip[ clipUuid ]; - getFrustum() { - return this._frustum; - } + this._bindAction( action, + actionsForClip && actionsForClip.knownActions[ 0 ] ); - updateMatrices(light) { - const shadowCamera = this.camera; - const shadowMatrix = this.matrix; + this._addInactiveAction( action, clipUuid, rootUuid ); - _lightPositionWorld$1.setFromMatrixPosition(light.matrixWorld); + } - shadowCamera.position.copy(_lightPositionWorld$1); + const bindings = action._propertyBindings; - _lookTarget$1.setFromMatrixPosition(light.target.matrixWorld); + // increment reference counts / sort out state + for ( let i = 0, n = bindings.length; i !== n; ++ i ) { - shadowCamera.lookAt(_lookTarget$1); - shadowCamera.updateMatrixWorld(); + const binding = bindings[ i ]; - _projScreenMatrix$1.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse); + if ( binding.useCount ++ === 0 ) { - this._frustum.setFromProjectionMatrix(_projScreenMatrix$1); + this._lendBinding( binding ); + binding.saveOriginalState(); - shadowMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0); - shadowMatrix.multiply(shadowCamera.projectionMatrix); - shadowMatrix.multiply(shadowCamera.matrixWorldInverse); - } + } - getViewport(viewportIndex) { - return this._viewports[viewportIndex]; - } + } - getFrameExtents() { - return this._frameExtents; - } + this._lendAction( action ); - dispose() { - if (this.map) { - this.map.dispose(); } - if (this.mapPass) { - this.mapPass.dispose(); - } } - copy(source) { - this.camera = source.camera.clone(); - this.bias = source.bias; - this.radius = source.radius; - this.mapSize.copy(source.mapSize); - return this; - } + _deactivateAction( action ) { - clone() { - return new this.constructor().copy(this); - } + if ( this._isActiveAction( action ) ) { - toJSON() { - const object = {}; - if (this.bias !== 0) object.bias = this.bias; - if (this.normalBias !== 0) object.normalBias = this.normalBias; - if (this.radius !== 1) object.radius = this.radius; - if (this.mapSize.x !== 512 || this.mapSize.y !== 512) object.mapSize = this.mapSize.toArray(); - object.camera = this.camera.toJSON(false).object; - delete object.camera.matrix; - return object; - } + const bindings = action._propertyBindings; -} + // decrement reference counts / sort out state + for ( let i = 0, n = bindings.length; i !== n; ++ i ) { -class SpotLightShadow extends LightShadow { - constructor() { - super(new PerspectiveCamera(50, 1, 0.5, 500)); - this.isSpotLightShadow = true; - this.focus = 1; - } + const binding = bindings[ i ]; - 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 ( -- binding.useCount === 0 ) { - if (fov !== camera.fov || aspect !== camera.aspect || far !== camera.far) { - camera.fov = fov; - camera.aspect = aspect; - camera.far = far; - camera.updateProjectionMatrix(); - } + binding.restoreOriginalState(); + this._takeBackBinding( binding ); - super.updateMatrices(light); - } + } - copy(source) { - super.copy(source); - this.focus = source.focus; - return this; - } + } -} + this._takeBackAction( action ); -class SpotLight extends Light { - constructor(color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 1) { - super(color, intensity); - this.isSpotLight = true; - this.type = 'SpotLight'; - this.position.copy(Object3D.DefaultUp); - this.updateMatrix(); - this.target = new Object3D(); - this.distance = distance; - this.angle = angle; - this.penumbra = penumbra; - this.decay = decay; // for physically correct lights, should be 2. + } - 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; - } + // Memory manager - set power(power) { - // set the light's intensity (in candela) from the desired luminous power (in lumens) - this.intensity = power / Math.PI; - } + _initMemoryManager() { - dispose() { - this.shadow.dispose(); - } + this._actions = []; // 'nActiveActions' followed by inactive ones + this._nActiveActions = 0; - copy(source, recursive) { - super.copy(source, recursive); - this.distance = source.distance; - this.angle = source.angle; - this.penumbra = source.penumbra; - this.decay = source.decay; - this.target = source.target.clone(); - this.shadow = source.shadow.clone(); - return this; - } + this._actionsByClip = {}; + // inside: + // { + // knownActions: Array< AnimationAction > - used as prototypes + // actionByRoot: AnimationAction - lookup + // } -} -const _projScreenMatrix = /*@__PURE__*/new Matrix4(); + this._bindings = []; // 'nActiveBindings' followed by inactive ones + this._nActiveBindings = 0; -const _lightPositionWorld = /*@__PURE__*/new Vector3(); + this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer > -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 - // following orientation: - // - // xzXZ - // y Y - // - // X - Positive x direction - // x - Negative x direction - // Y - Positive y direction - // y - Negative y direction - // Z - Positive z direction - // z - Negative z direction - // positive X - new Vector4(2, 1, 1, 1), // negative X - new Vector4(0, 1, 1, 1), // positive Z - new Vector4(3, 1, 1, 1), // negative Z - new Vector4(1, 1, 1, 1), // positive Y - new Vector4(3, 0, 1, 1), // negative Y - new Vector4(1, 0, 1, 1)]; - this._cubeDirections = [new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1), new Vector3(0, 1, 0), new Vector3(0, -1, 0)]; - this._cubeUps = [new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1)]; - } - - updateMatrices(light, viewportIndex = 0) { - const camera = this.camera; - const shadowMatrix = this.matrix; - const far = light.distance || camera.far; + this._controlInterpolants = []; // same game as above + this._nActiveControlInterpolants = 0; - if (far !== camera.far) { - camera.far = far; - camera.updateProjectionMatrix(); - } + const scope = this; - _lightPositionWorld.setFromMatrixPosition(light.matrixWorld); + this.stats = { - camera.position.copy(_lightPositionWorld); + actions: { + get total() { - _lookTarget.copy(camera.position); + return scope._actions.length; - _lookTarget.add(this._cubeDirections[viewportIndex]); + }, + get inUse() { - camera.up.copy(this._cubeUps[viewportIndex]); - camera.lookAt(_lookTarget); - camera.updateMatrixWorld(); - shadowMatrix.makeTranslation(-_lightPositionWorld.x, -_lightPositionWorld.y, -_lightPositionWorld.z); + return scope._nActiveActions; - _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); + } + }, + bindings: { + get total() { - this._frustum.setFromProjectionMatrix(_projScreenMatrix); - } + return scope._bindings.length; -} + }, + get inUse() { -class PointLight extends Light { - constructor(color, intensity, distance = 0, decay = 1) { - super(color, intensity); - this.isPointLight = true; - this.type = 'PointLight'; - this.distance = distance; - this.decay = decay; // for physically correct lights, should be 2. + return scope._nActiveBindings; - this.shadow = new PointLightShadow(); - } + } + }, + controlInterpolants: { + get total() { - 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; - } + return scope._controlInterpolants.length; - set power(power) { - // set the light's intensity (in candela) from the desired luminous power (in lumens) - this.intensity = power / (4 * Math.PI); - } + }, + get inUse() { - dispose() { - this.shadow.dispose(); - } + return scope._nActiveControlInterpolants; - copy(source, recursive) { - super.copy(source, recursive); - this.distance = source.distance; - this.decay = source.decay; - this.shadow = source.shadow.clone(); - return this; - } + } + } -} + }; -class DirectionalLightShadow extends LightShadow { - constructor() { - super(new OrthographicCamera(-5, 5, 5, -5, 0.5, 500)); - this.isDirectionalLightShadow = true; } -} + // Memory management for AnimationAction objects -class DirectionalLight extends Light { - constructor(color, intensity) { - super(color, intensity); - this.isDirectionalLight = true; - this.type = 'DirectionalLight'; - this.position.copy(Object3D.DefaultUp); - this.updateMatrix(); - this.target = new Object3D(); - this.shadow = new DirectionalLightShadow(); - } + _isActiveAction( action ) { - dispose() { - this.shadow.dispose(); - } + const index = action._cacheIndex; + return index !== null && index < this._nActiveActions; - copy(source) { - super.copy(source); - this.target = source.target.clone(); - this.shadow = source.shadow.clone(); - return this; } -} + _addInactiveAction( action, clipUuid, rootUuid ) { -class AmbientLight extends Light { - constructor(color, intensity) { - super(color, intensity); - this.isAmbientLight = true; - this.type = 'AmbientLight'; - } + const actions = this._actions, + actionsByClip = this._actionsByClip; -} + let actionsForClip = actionsByClip[ clipUuid ]; -class RectAreaLight extends Light { - constructor(color, intensity, width = 10, height = 10) { - super(color, intensity); - this.isRectAreaLight = true; - this.type = 'RectAreaLight'; - this.width = width; - this.height = height; - } + if ( actionsForClip === undefined ) { - get power() { - // compute the light's luminous power (in lumens) from its intensity (in nits) - return this.intensity * this.width * this.height * Math.PI; - } + actionsForClip = { - 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); - } + knownActions: [ action ], + actionByRoot: {} - 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; - } + action._byClipCacheIndex = 0; -} + actionsByClip[ clipUuid ] = actionsForClip; -/** - * Primary reference: - * https://graphics.stanford.edu/papers/envmap/envmap.pdf - * - * Secondary reference: - * https://www.ppsloan.org/publications/StupidSH36.pdf - */ -// 3-band SH defined by 9 coefficients + } else { -class SphericalHarmonics3 { - constructor() { - this.isSphericalHarmonics3 = true; - this.coefficients = []; + const knownActions = actionsForClip.knownActions; - for (let i = 0; i < 9; i++) { - this.coefficients.push(new Vector3()); - } - } + action._byClipCacheIndex = knownActions.length; + knownActions.push( action ); - set(coefficients) { - for (let i = 0; i < 9; i++) { - this.coefficients[i].copy(coefficients[i]); } - return this; - } + action._cacheIndex = actions.length; + actions.push( action ); - zero() { - for (let i = 0; i < 9; i++) { - this.coefficients[i].set(0, 0, 0); - } + actionsForClip.actionByRoot[ rootUuid ] = action; - return this; - } // get the radiance in the direction of the normal - // target is a Vector3 + } + _removeInactiveAction( action ) { - 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 - - target.copy(coeff[0]).multiplyScalar(0.282095); // band 1 - - target.addScaledVector(coeff[1], 0.488603 * y); - target.addScaledVector(coeff[2], 0.488603 * z); - target.addScaledVector(coeff[3], 0.488603 * x); // band 2 - - target.addScaledVector(coeff[4], 1.092548 * (x * y)); - target.addScaledVector(coeff[5], 1.092548 * (y * z)); - target.addScaledVector(coeff[6], 0.315392 * (3.0 * z * z - 1.0)); - target.addScaledVector(coeff[7], 1.092548 * (x * z)); - target.addScaledVector(coeff[8], 0.546274 * (x * x - y * y)); - return target; - } // get the irradiance (radiance convolved with cosine lobe) in the direction of the normal - // target is a Vector3 - // https://graphics.stanford.edu/papers/envmap/envmap.pdf + const actions = this._actions, + lastInactiveAction = actions[ actions.length - 1 ], + cacheIndex = action._cacheIndex; + lastInactiveAction._cacheIndex = cacheIndex; + actions[ cacheIndex ] = lastInactiveAction; + actions.pop(); - 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 + action._cacheIndex = null; - target.copy(coeff[0]).multiplyScalar(0.886227); // π * 0.282095 - // band 1 - target.addScaledVector(coeff[1], 2.0 * 0.511664 * y); // ( 2 * π / 3 ) * 0.488603 + const clipUuid = action._clip.uuid, + actionsByClip = this._actionsByClip, + actionsForClip = actionsByClip[ clipUuid ], + knownActionsForClip = actionsForClip.knownActions, - target.addScaledVector(coeff[2], 2.0 * 0.511664 * z); - target.addScaledVector(coeff[3], 2.0 * 0.511664 * x); // band 2 + lastKnownAction = + knownActionsForClip[ knownActionsForClip.length - 1 ], - target.addScaledVector(coeff[4], 2.0 * 0.429043 * x * y); // ( π / 4 ) * 1.092548 + byClipCacheIndex = action._byClipCacheIndex; - target.addScaledVector(coeff[5], 2.0 * 0.429043 * y * z); - target.addScaledVector(coeff[6], 0.743125 * z * z - 0.247708); // ( π / 4 ) * 0.315392 * 3 + lastKnownAction._byClipCacheIndex = byClipCacheIndex; + knownActionsForClip[ byClipCacheIndex ] = lastKnownAction; + knownActionsForClip.pop(); - target.addScaledVector(coeff[7], 2.0 * 0.429043 * x * z); - target.addScaledVector(coeff[8], 0.429043 * (x * x - y * y)); // ( π / 4 ) * 0.546274 + action._byClipCacheIndex = null; - return target; - } - add(sh) { - for (let i = 0; i < 9; i++) { - this.coefficients[i].add(sh.coefficients[i]); - } + const actionByRoot = actionsForClip.actionByRoot, + rootUuid = ( action._localRoot || this._root ).uuid; - return this; - } + delete actionByRoot[ rootUuid ]; - addScaledSH(sh, s) { - for (let i = 0; i < 9; i++) { - this.coefficients[i].addScaledVector(sh.coefficients[i], s); - } + if ( knownActionsForClip.length === 0 ) { - return this; - } + delete actionsByClip[ clipUuid ]; - scale(s) { - for (let i = 0; i < 9; i++) { - this.coefficients[i].multiplyScalar(s); } - return this; + this._removeInactiveBindingsForAction( action ); + } - lerp(sh, alpha) { - for (let i = 0; i < 9; i++) { - this.coefficients[i].lerp(sh.coefficients[i], alpha); - } + _removeInactiveBindingsForAction( action ) { - return this; - } + const bindings = action._propertyBindings; - equals(sh) { - for (let i = 0; i < 9; i++) { - if (!this.coefficients[i].equals(sh.coefficients[i])) { - return false; - } - } + for ( let i = 0, n = bindings.length; i !== n; ++ i ) { - return true; - } + const binding = bindings[ i ]; - copy(sh) { - return this.set(sh.coefficients); - } + if ( -- binding.referenceCount === 0 ) { - clone() { - return new this.constructor().copy(this); - } + this._removeInactiveBinding( binding ); - 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; + _lendAction( action ) { - for (let i = 0; i < 9; i++) { - coefficients[i].toArray(array, offset + i * 3); - } + // [ active actions | inactive actions ] + // [ active actions >| inactive actions ] + // s a + // <-swap-> + // a s - return array; - } // evaluate the basis functions - // shBasis is an Array[ 9 ] + const actions = this._actions, + prevIndex = action._cacheIndex, + lastActiveIndex = this._nActiveActions ++, - static getBasisAt(normal, shBasis) { - // normal is assumed to be unit length - const x = normal.x, - y = normal.y, - z = normal.z; // band 0 + firstInactiveAction = actions[ lastActiveIndex ]; - shBasis[0] = 0.282095; // band 1 + action._cacheIndex = lastActiveIndex; + actions[ lastActiveIndex ] = action; - shBasis[1] = 0.488603 * y; - shBasis[2] = 0.488603 * z; - shBasis[3] = 0.488603 * x; // band 2 + firstInactiveAction._cacheIndex = prevIndex; + actions[ prevIndex ] = firstInactiveAction; - 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); } -} + _takeBackAction( action ) { -class LightProbe extends Light { - constructor(sh = new SphericalHarmonics3(), intensity = 1) { - super(undefined, intensity); - this.isLightProbe = true; - this.sh = sh; - } + // [ active actions | inactive actions ] + // [ active actions |< inactive actions ] + // a s + // <-swap-> + // s a - copy(source) { - super.copy(source); - this.sh.copy(source.sh); - return this; - } + const actions = this._actions, + prevIndex = action._cacheIndex, - fromJSON(json) { - this.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON(); + firstInactiveIndex = -- this._nActiveActions, - this.sh.fromArray(json.sh); - return this; - } + lastActiveAction = actions[ firstInactiveIndex ]; - toJSON(meta) { - const data = super.toJSON(meta); - data.object.sh = this.sh.toArray(); - return data; - } + action._cacheIndex = firstInactiveIndex; + actions[ firstInactiveIndex ] = action; -} + lastActiveAction._cacheIndex = prevIndex; + actions[ prevIndex ] = lastActiveAction; -class MaterialLoader extends Loader { - constructor(manager) { - super(manager); - this.textures = {}; } - load(url, onLoad, onProgress, onError) { - const scope = this; - const loader = new FileLoader(scope.manager); - loader.setPath(scope.path); - loader.setRequestHeader(scope.requestHeader); - loader.setWithCredentials(scope.withCredentials); - loader.load(url, function (text) { - try { - onLoad(scope.parse(JSON.parse(text))); - } catch (e) { - if (onError) { - onError(e); - } else { - console.error(e); - } + // Memory management for PropertyMixer objects - scope.manager.itemError(url); - } - }, onProgress, onError); - } + _addInactiveBinding( binding, rootUuid, trackName ) { - parse(json) { - const textures = this.textures; + const bindingsByRoot = this._bindingsByRootAndName, + bindings = this._bindings; - function getTexture(name) { - if (textures[name] === undefined) { - console.warn('THREE.MaterialLoader: Undefined texture', name); - } - - return textures[name]; - } - - const material = Material.fromType(json.type); - if (json.uuid !== undefined) material.uuid = json.uuid; - if (json.name !== undefined) material.name = json.name; - if (json.color !== undefined && material.color !== undefined) material.color.setHex(json.color); - if (json.roughness !== undefined) material.roughness = json.roughness; - if (json.metalness !== undefined) material.metalness = json.metalness; - if (json.sheen !== undefined) material.sheen = json.sheen; - if (json.sheenColor !== undefined) material.sheenColor = new Color().setHex(json.sheenColor); - if (json.sheenRoughness !== undefined) material.sheenRoughness = json.sheenRoughness; - if (json.emissive !== undefined && material.emissive !== undefined) material.emissive.setHex(json.emissive); - if (json.specular !== undefined && material.specular !== undefined) material.specular.setHex(json.specular); - if (json.specularIntensity !== undefined) material.specularIntensity = json.specularIntensity; - if (json.specularColor !== undefined && material.specularColor !== undefined) material.specularColor.setHex(json.specularColor); - if (json.shininess !== undefined) material.shininess = json.shininess; - if (json.clearcoat !== undefined) material.clearcoat = json.clearcoat; - if (json.clearcoatRoughness !== undefined) material.clearcoatRoughness = json.clearcoatRoughness; - if (json.iridescence !== undefined) material.iridescence = json.iridescence; - if (json.iridescenceIOR !== undefined) material.iridescenceIOR = json.iridescenceIOR; - if (json.iridescenceThicknessRange !== undefined) material.iridescenceThicknessRange = json.iridescenceThicknessRange; - if (json.transmission !== undefined) material.transmission = json.transmission; - if (json.thickness !== undefined) material.thickness = json.thickness; - if (json.attenuationDistance !== undefined) material.attenuationDistance = json.attenuationDistance; - if (json.attenuationColor !== undefined && material.attenuationColor !== undefined) material.attenuationColor.setHex(json.attenuationColor); - if (json.fog !== undefined) material.fog = json.fog; - if (json.flatShading !== undefined) material.flatShading = json.flatShading; - if (json.blending !== undefined) material.blending = json.blending; - if (json.combine !== undefined) material.combine = json.combine; - if (json.side !== undefined) material.side = json.side; - if (json.shadowSide !== undefined) material.shadowSide = json.shadowSide; - if (json.opacity !== undefined) material.opacity = json.opacity; - if (json.transparent !== undefined) material.transparent = json.transparent; - if (json.alphaTest !== undefined) material.alphaTest = json.alphaTest; - if (json.depthTest !== undefined) material.depthTest = json.depthTest; - if (json.depthWrite !== undefined) material.depthWrite = json.depthWrite; - if (json.colorWrite !== undefined) material.colorWrite = json.colorWrite; - if (json.stencilWrite !== undefined) material.stencilWrite = json.stencilWrite; - if (json.stencilWriteMask !== undefined) material.stencilWriteMask = json.stencilWriteMask; - if (json.stencilFunc !== undefined) material.stencilFunc = json.stencilFunc; - if (json.stencilRef !== undefined) material.stencilRef = json.stencilRef; - if (json.stencilFuncMask !== undefined) material.stencilFuncMask = json.stencilFuncMask; - if (json.stencilFail !== undefined) material.stencilFail = json.stencilFail; - if (json.stencilZFail !== undefined) material.stencilZFail = json.stencilZFail; - if (json.stencilZPass !== undefined) material.stencilZPass = json.stencilZPass; - if (json.wireframe !== undefined) material.wireframe = json.wireframe; - if (json.wireframeLinewidth !== undefined) material.wireframeLinewidth = json.wireframeLinewidth; - if (json.wireframeLinecap !== undefined) material.wireframeLinecap = json.wireframeLinecap; - if (json.wireframeLinejoin !== undefined) material.wireframeLinejoin = json.wireframeLinejoin; - if (json.rotation !== undefined) material.rotation = json.rotation; - if (json.linewidth !== 1) material.linewidth = json.linewidth; - if (json.dashSize !== undefined) material.dashSize = json.dashSize; - if (json.gapSize !== undefined) material.gapSize = json.gapSize; - if (json.scale !== undefined) material.scale = json.scale; - if (json.polygonOffset !== undefined) material.polygonOffset = json.polygonOffset; - if (json.polygonOffsetFactor !== undefined) material.polygonOffsetFactor = json.polygonOffsetFactor; - if (json.polygonOffsetUnits !== undefined) material.polygonOffsetUnits = json.polygonOffsetUnits; - if (json.dithering !== undefined) material.dithering = json.dithering; - if (json.alphaToCoverage !== undefined) material.alphaToCoverage = json.alphaToCoverage; - if (json.premultipliedAlpha !== undefined) material.premultipliedAlpha = json.premultipliedAlpha; - 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 + let bindingByName = bindingsByRoot[ rootUuid ]; + if ( bindingByName === undefined ) { - if (json.uniforms !== undefined) { - for (const name in json.uniforms) { - const uniform = json.uniforms[name]; - material.uniforms[name] = {}; + bindingByName = {}; + bindingsByRoot[ rootUuid ] = bindingByName; - 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; + bindingByName[ trackName ] = binding; - case 'v2': - material.uniforms[name].value = new Vector2().fromArray(uniform.value); - break; + binding._cacheIndex = bindings.length; + bindings.push( binding ); - case 'v3': - material.uniforms[name].value = new Vector3().fromArray(uniform.value); - break; + } - case 'v4': - material.uniforms[name].value = new Vector4().fromArray(uniform.value); - break; + _removeInactiveBinding( binding ) { - case 'm3': - material.uniforms[name].value = new Matrix3().fromArray(uniform.value); - break; + const bindings = this._bindings, + propBinding = binding.binding, + rootUuid = propBinding.rootNode.uuid, + trackName = propBinding.path, + bindingsByRoot = this._bindingsByRootAndName, + bindingByName = bindingsByRoot[ rootUuid ], - case 'm4': - material.uniforms[name].value = new Matrix4().fromArray(uniform.value); - break; + 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 ]; - 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.extensions !== undefined) { - for (const key in json.extensions) { - material.extensions[key] = json.extensions[key]; - } - } // Deprecated + _lendBinding( binding ) { + const bindings = this._bindings, + prevIndex = binding._cacheIndex, - if (json.shading !== undefined) material.flatShading = json.shading === 1; // THREE.FlatShading - // for PointsMaterial + lastActiveIndex = this._nActiveBindings ++, - if (json.size !== undefined) material.size = json.size; - if (json.sizeAttenuation !== undefined) material.sizeAttenuation = json.sizeAttenuation; // maps + firstInactiveBinding = bindings[ lastActiveIndex ]; - if (json.map !== undefined) material.map = getTexture(json.map); - if (json.matcap !== undefined) material.matcap = getTexture(json.matcap); - if (json.alphaMap !== undefined) material.alphaMap = getTexture(json.alphaMap); - if (json.bumpMap !== undefined) material.bumpMap = getTexture(json.bumpMap); - if (json.bumpScale !== undefined) material.bumpScale = json.bumpScale; - if (json.normalMap !== undefined) material.normalMap = getTexture(json.normalMap); - if (json.normalMapType !== undefined) material.normalMapType = json.normalMapType; + binding._cacheIndex = lastActiveIndex; + bindings[ lastActiveIndex ] = binding; - if (json.normalScale !== undefined) { - let normalScale = json.normalScale; + firstInactiveBinding._cacheIndex = prevIndex; + bindings[ prevIndex ] = firstInactiveBinding; - 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; - if (json.roughnessMap !== undefined) material.roughnessMap = getTexture(json.roughnessMap); - if (json.metalnessMap !== undefined) material.metalnessMap = getTexture(json.metalnessMap); - if (json.emissiveMap !== undefined) material.emissiveMap = getTexture(json.emissiveMap); - if (json.emissiveIntensity !== undefined) material.emissiveIntensity = json.emissiveIntensity; - if (json.specularMap !== undefined) material.specularMap = getTexture(json.specularMap); - if (json.specularIntensityMap !== undefined) material.specularIntensityMap = getTexture(json.specularIntensityMap); - if (json.specularColorMap !== undefined) material.specularColorMap = getTexture(json.specularColorMap); - if (json.envMap !== undefined) material.envMap = getTexture(json.envMap); - if (json.envMapIntensity !== undefined) material.envMapIntensity = json.envMapIntensity; - if (json.reflectivity !== undefined) material.reflectivity = json.reflectivity; - if (json.refractionRatio !== undefined) material.refractionRatio = json.refractionRatio; - if (json.lightMap !== undefined) material.lightMap = getTexture(json.lightMap); - if (json.lightMapIntensity !== undefined) material.lightMapIntensity = json.lightMapIntensity; - if (json.aoMap !== undefined) material.aoMap = getTexture(json.aoMap); - if (json.aoMapIntensity !== undefined) material.aoMapIntensity = json.aoMapIntensity; - if (json.gradientMap !== undefined) material.gradientMap = getTexture(json.gradientMap); - if (json.clearcoatMap !== undefined) material.clearcoatMap = getTexture(json.clearcoatMap); - if (json.clearcoatRoughnessMap !== undefined) material.clearcoatRoughnessMap = getTexture(json.clearcoatRoughnessMap); - if (json.clearcoatNormalMap !== undefined) material.clearcoatNormalMap = getTexture(json.clearcoatNormalMap); - if (json.clearcoatNormalScale !== undefined) material.clearcoatNormalScale = new Vector2().fromArray(json.clearcoatNormalScale); - if (json.iridescenceMap !== undefined) material.iridescenceMap = getTexture(json.iridescenceMap); - if (json.iridescenceThicknessMap !== undefined) material.iridescenceThicknessMap = getTexture(json.iridescenceThicknessMap); - if (json.transmissionMap !== undefined) material.transmissionMap = getTexture(json.transmissionMap); - if (json.thicknessMap !== undefined) material.thicknessMap = getTexture(json.thicknessMap); - if (json.sheenColorMap !== undefined) material.sheenColorMap = getTexture(json.sheenColorMap); - if (json.sheenRoughnessMap !== undefined) material.sheenRoughnessMap = getTexture(json.sheenRoughnessMap); - return material; } - setTextures(value) { - this.textures = value; - return this; - } + _takeBackBinding( binding ) { -} + const bindings = this._bindings, + prevIndex = binding._cacheIndex, -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. + firstInactiveIndex = -- this._nActiveBindings, + lastActiveBinding = bindings[ firstInactiveIndex ]; - let s = ''; + binding._cacheIndex = firstInactiveIndex; + bindings[ firstInactiveIndex ] = binding; - for (let i = 0, il = array.length; i < il; i++) { - // Implicitly assumes little-endian. - s += String.fromCharCode(array[i]); - } + lastActiveBinding._cacheIndex = prevIndex; + bindings[ prevIndex ] = lastActiveBinding; - 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 + // Memory management of Interpolants for weight and time scale - if (/^https?:\/\//i.test(path) && /^\//.test(url)) { - path = path.replace(/(^https?:\/\/[^\/]+).*/i, '$1'); - } // Absolute URL http://,https://,// + _lendControlInterpolant() { + const interpolants = this._controlInterpolants, + lastActiveIndex = this._nActiveControlInterpolants ++; - if (/^(https?:)?\/\//i.test(url)) return url; // Data URI + let interpolant = interpolants[ lastActiveIndex ]; - if (/^data:.*,.*$/i.test(url)) return url; // Blob URL + if ( interpolant === undefined ) { - if (/^blob:.*$/i.test(url)) return url; // Relative URL + interpolant = new LinearInterpolant( + new Float32Array( 2 ), new Float32Array( 2 ), + 1, _controlInterpolantsResultBuffer ); - return path + url; - } + interpolant.__cacheIndex = lastActiveIndex; + interpolants[ lastActiveIndex ] = interpolant; -} + } -class InstancedBufferGeometry extends BufferGeometry { - constructor() { - super(); - this.isInstancedBufferGeometry = true; - this.type = 'InstancedBufferGeometry'; - this.instanceCount = Infinity; - } + return interpolant; - copy(source) { - super.copy(source); - this.instanceCount = source.instanceCount; - return this; } - clone() { - return new this.constructor().copy(this); - } + _takeBackControlInterpolant( interpolant ) { - toJSON() { - const data = super.toJSON(this); - data.instanceCount = this.instanceCount; - data.isInstancedBufferGeometry = true; - return data; - } + const interpolants = this._controlInterpolants, + prevIndex = interpolant.__cacheIndex, -} + firstInactiveIndex = -- this._nActiveControlInterpolants, -class BufferGeometryLoader extends Loader { - constructor(manager) { - super(manager); - } + lastActiveInterpolant = interpolants[ firstInactiveIndex ]; - load(url, onLoad, onProgress, onError) { - const scope = this; - const loader = new FileLoader(scope.manager); - loader.setPath(scope.path); - loader.setRequestHeader(scope.requestHeader); - loader.setWithCredentials(scope.withCredentials); - loader.load(url, function (text) { - try { - onLoad(scope.parse(JSON.parse(text))); - } catch (e) { - if (onError) { - onError(e); - } else { - console.error(e); - } + interpolant.__cacheIndex = firstInactiveIndex; + interpolants[ firstInactiveIndex ] = interpolant; + + lastActiveInterpolant.__cacheIndex = prevIndex; + interpolants[ prevIndex ] = lastActiveInterpolant; - scope.manager.itemError(url); - } - }, onProgress, onError); } - parse(json) { - const interleavedBufferMap = {}; - const arrayBufferMap = {}; + // 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 ) { - function getInterleavedBuffer(json, uuid) { - if (interleavedBufferMap[uuid] !== undefined) return interleavedBufferMap[uuid]; - const interleavedBuffers = json.interleavedBuffers; - const interleavedBuffer = interleavedBuffers[uuid]; - const buffer = getArrayBuffer(json, interleavedBuffer.buffer); - const array = getTypedArray(interleavedBuffer.type, buffer); - const ib = new InterleavedBuffer(array, interleavedBuffer.stride); - ib.uuid = interleavedBuffer.uuid; - interleavedBufferMap[uuid] = ib; - return ib; - } + const root = optionalRoot || this._root, + rootUuid = root.uuid; - function getArrayBuffer(json, uuid) { - if (arrayBufferMap[uuid] !== undefined) return arrayBufferMap[uuid]; - const arrayBuffers = json.arrayBuffers; - const arrayBuffer = arrayBuffers[uuid]; - const ab = new Uint32Array(arrayBuffer).buffer; - arrayBufferMap[uuid] = ab; - return ab; - } + let clipObject = typeof clip === 'string' ? AnimationClip.findByName( root, clip ) : clip; - const geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry(); - const index = json.data.index; + const clipUuid = clipObject !== null ? clipObject.uuid : clip; - if (index !== undefined) { - const typedArray = getTypedArray(index.type, index.array); - geometry.setIndex(new BufferAttribute(typedArray, 1)); - } + const actionsForClip = this._actionsByClip[ clipUuid ]; + let prototypeAction = null; - const attributes = json.data.attributes; + if ( blendMode === undefined ) { - for (const key in attributes) { - const attribute = attributes[key]; - let bufferAttribute; + if ( clipObject !== null ) { + + blendMode = clipObject.blendMode; - if (attribute.isInterleavedBufferAttribute) { - const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data); - bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized); } else { - const typedArray = getTypedArray(attribute.type, attribute.array); - 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); + blendMode = NormalAnimationBlendMode; - 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 = []; + if ( actionsForClip !== undefined ) { - for (let i = 0, il = attributeArray.length; i < il; i++) { - const attribute = attributeArray[i]; - let bufferAttribute; + const existingAction = actionsForClip.actionByRoot[ rootUuid ]; - if (attribute.isInterleavedBufferAttribute) { - const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data); - bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized); - } else { - const typedArray = getTypedArray(attribute.type, attribute.array); - bufferAttribute = new BufferAttribute(typedArray, attribute.itemSize, attribute.normalized); - } + if ( existingAction !== undefined && existingAction.blendMode === blendMode ) { - if (attribute.name !== undefined) bufferAttribute.name = attribute.name; - array.push(bufferAttribute); - } + return existingAction; - geometry.morphAttributes[key] = array; } - } - const morphTargetsRelative = json.data.morphTargetsRelative; - - if (morphTargetsRelative) { - geometry.morphTargetsRelative = true; - } + // we know the clip, so we don't have to parse all + // the bindings again but can just copy + prototypeAction = actionsForClip.knownActions[ 0 ]; - const groups = json.data.groups || json.data.drawcalls || json.data.offsets; + // also, take the clip from the prototype action + if ( clipObject === null ) + clipObject = prototypeAction._clip; - 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(); + // clip must be known when specified via string + if ( clipObject === null ) return null; - if (boundingSphere.center !== undefined) { - center.fromArray(boundingSphere.center); - } + // allocate all resources required to run it + const newAction = new AnimationAction( this, clipObject, optionalRoot, blendMode ); - geometry.boundingSphere = new Sphere(center, boundingSphere.radius); - } + this._bindAction( newAction, prototypeAction ); - if (json.name) geometry.name = json.name; - if (json.userData) geometry.userData = json.userData; - return geometry; - } + // and make the action known to the memory manager + this._addInactiveAction( newAction, clipUuid, rootUuid ); -} + return newAction; -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; - this.resourcePath = this.resourcePath || path; - const loader = new FileLoader(this.manager); - loader.setPath(this.path); - loader.setRequestHeader(this.requestHeader); - loader.setWithCredentials(this.withCredentials); - loader.load(url, function (text) { - let json = null; + // get an existing action + existingAction( clip, optionalRoot ) { - try { - json = JSON.parse(text); - } catch (error) { - if (onError !== undefined) onError(error); - console.error('THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message); - return; - } + const root = optionalRoot || this._root, + rootUuid = root.uuid, - const metadata = json.metadata; + clipObject = typeof clip === 'string' ? + AnimationClip.findByName( root, clip ) : clip, - if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') { - console.error('THREE.ObjectLoader: Can\'t load ' + url); - return; - } + clipUuid = clipObject ? clipObject.uuid : clip, + + actionsForClip = this._actionsByClip[ clipUuid ]; - scope.parse(json, onLoad); - }, onProgress, onError); - } + if ( actionsForClip !== undefined ) { - async loadAsync(url, onProgress) { - const scope = this; - const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path; - this.resourcePath = this.resourcePath || path; - const loader = new FileLoader(this.manager); - loader.setPath(this.path); - loader.setRequestHeader(this.requestHeader); - loader.setWithCredentials(this.withCredentials); - const text = await loader.loadAsync(url, onProgress); - const json = JSON.parse(text); - const metadata = json.metadata; + return actionsForClip.actionByRoot[ rootUuid ] || null; - if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') { - throw new Error('THREE.ObjectLoader: Can\'t load ' + url); } - return await scope.parseAsync(json); + return null; + } - parse(json, onLoad) { - const animations = this.parseAnimations(json.animations); - const shapes = this.parseShapes(json.shapes); - const geometries = this.parseGeometries(json.geometries, shapes); - const images = this.parseImages(json.images, function () { - if (onLoad !== undefined) onLoad(object); - }); - const textures = this.parseTextures(json.textures, images); - 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); // + // deactivates all previously scheduled actions + stopAllAction() { - if (onLoad !== undefined) { - let hasImages = false; + const actions = this._actions, + nActions = this._nActiveActions; - for (const uuid in images) { - if (images[uuid].data instanceof HTMLImageElement) { - hasImages = true; - break; - } - } + for ( let i = nActions - 1; i >= 0; -- i ) { + + actions[ i ].stop(); - if (hasImages === false) onLoad(object); } - return object; - } + return this; - async parseAsync(json) { - const animations = this.parseAnimations(json.animations); - const shapes = this.parseShapes(json.shapes); - const geometries = this.parseGeometries(json.geometries, shapes); - const images = await this.parseImagesAsync(json.images); - const textures = this.parseTextures(json.textures, images); - 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); - return object; } - parseShapes(json) { - const shapes = {}; + // 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 + + for ( let i = 0; i !== nActions; ++ i ) { + + const action = actions[ i ]; + + action._update( time, deltaTime, timeDirection, accuIndex ); - 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; - } + // update scene graph - parseSkeletons(json, object) { - const skeletons = {}; - const bones = {}; // generate bone lookup table + const bindings = this._bindings, + nBindings = this._nActiveBindings; - object.traverse(function (child) { - if (child.isBone) bones[child.uuid] = child; - }); // create skeletons + for ( let i = 0; i !== nBindings; ++ i ) { + + bindings[ i ].apply( accuIndex ); - if (json !== undefined) { - for (let i = 0, l = json.length; i < l; i++) { - const skeleton = new Skeleton().fromJSON(json[i], bones); - skeletons[skeleton.uuid] = skeleton; - } } - return skeletons; + return this; + } - parseGeometries(json, shapes) { - const geometries = {}; + // Allows you to seek to a specific time in an animation. + setTime( timeInSeconds ) { - if (json !== undefined) { - const bufferGeometryLoader = new BufferGeometryLoader(); + this.time = 0; // Zero out time attribute for AnimationMixer object; + for ( let i = 0; i < this._actions.length; i ++ ) { - for (let i = 0, l = json.length; i < l; i++) { - let geometry; - const data = json[i]; + this._actions[ i ].time = 0; // Zero out time attribute for all associated AnimationAction objects. - 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; + return this.update( timeInSeconds ); // Update used to set exact time. Returns "this" AnimationMixer object. - default: - if (data.type in Geometries) { - geometry = Geometries[data.type].fromJSON(data, shapes); - } else { - console.warn(`THREE.ObjectLoader: Unsupported geometry type "${data.type}"`); - } + } - } + // return this mixer's root target object + getRoot() { - 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 this._root; - return geometries; } - parseMaterials(json, textures) { - const cache = {}; // MultiMaterial + // free all resources specific to a particular clip + uncacheClip( clip ) { - const materials = {}; + const actions = this._actions, + clipUuid = clip.uuid, + actionsByClip = this._actionsByClip, + actionsForClip = actionsByClip[ clipUuid ]; - if (json !== undefined) { - const loader = new MaterialLoader(); - loader.setTextures(textures); + if ( actionsForClip !== undefined ) { - for (let i = 0, l = json.length; i < l; i++) { - const data = json[i]; + // note: just calling _removeInactiveAction would mess up the + // iteration state and also require updating the state we can + // just throw away - if (data.type === 'MultiMaterial') { - // Deprecated - const array = []; + const actionsToRemove = actionsForClip.knownActions; - for (let j = 0; j < data.materials.length; j++) { - const material = data.materials[j]; + for ( let i = 0, n = actionsToRemove.length; i !== n; ++ i ) { - if (cache[material.uuid] === undefined) { - cache[material.uuid] = loader.parse(material); - } + const action = actionsToRemove[ i ]; - array.push(cache[material.uuid]); - } + this._deactivateAction( action ); - materials[data.uuid] = array; - } else { - if (cache[data.uuid] === undefined) { - cache[data.uuid] = loader.parse(data); - } + const cacheIndex = action._cacheIndex, + lastInactiveAction = actions[ actions.length - 1 ]; - materials[data.uuid] = cache[data.uuid]; - } - } - } + action._cacheIndex = null; + action._byClipCacheIndex = null; - return materials; - } + lastInactiveAction._cacheIndex = cacheIndex; + actions[ cacheIndex ] = lastInactiveAction; + actions.pop(); - parseAnimations(json) { - const animations = {}; + this._removeInactiveBindingsForAction( action ); - if (json !== undefined) { - for (let i = 0; i < json.length; i++) { - const data = json[i]; - const clip = AnimationClip.parse(data); - animations[clip.uuid] = clip; } - } - - return animations; - } - parseImages(json, onLoad) { - const scope = this; - const images = {}; - let loader; + delete actionsByClip[ clipUuid ]; - function loadImage(url) { - scope.manager.itemStart(url); - return loader.load(url, function () { - scope.manager.itemEnd(url); - }, undefined, function () { - scope.manager.itemError(url); - scope.manager.itemEnd(url); - }); } - function deserializeImage(image) { - if (typeof image === 'string') { - const url = image; - const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test(url) ? url : scope.resourcePath + url; - return loadImage(path); - } else { - if (image.data) { - return { - data: getTypedArray(image.type, image.data), - width: image.width, - height: image.height - }; - } else { - return null; - } - } - } + } - if (json !== undefined && json.length > 0) { - const manager = new LoadingManager(onLoad); - loader = new ImageLoader(manager); - loader.setCrossOrigin(this.crossOrigin); + // free all resources specific to a particular root target object + uncacheRoot( root ) { - for (let i = 0, il = json.length; i < il; i++) { - const image = json[i]; - const url = image.url; + const rootUuid = root.uuid, + actionsByClip = this._actionsByClip; - if (Array.isArray(url)) { - // load array of images e.g CubeTexture - const imageArray = []; + for ( const clipUuid in actionsByClip ) { - for (let j = 0, jl = url.length; j < jl; j++) { - const currentUrl = url[j]; - const deserializedImage = deserializeImage(currentUrl); + const actionByRoot = actionsByClip[ clipUuid ].actionByRoot, + action = actionByRoot[ rootUuid ]; - 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)); - } - } - } + if ( action !== undefined ) { + + this._deactivateAction( action ); + this._removeInactiveAction( action ); - images[image.uuid] = new Source(imageArray); - } else { - // load single image - const deserializedImage = deserializeImage(image.url); - images[image.uuid] = new Source(deserializedImage); - } } + } - return images; - } + const bindingsByRoot = this._bindingsByRootAndName, + bindingByName = bindingsByRoot[ rootUuid ]; - async parseImagesAsync(json) { - const scope = this; - const images = {}; - let loader; + if ( bindingByName !== undefined ) { + + for ( const trackName in bindingByName ) { + + const binding = bindingByName[ trackName ]; + binding.restoreOriginalState(); + this._removeInactiveBinding( binding ); - async function deserializeImage(image) { - if (typeof image === 'string') { - const url = image; - const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test(url) ? url : scope.resourcePath + url; - return await loader.loadAsync(path); - } else { - if (image.data) { - return { - data: getTypedArray(image.type, image.data), - width: image.width, - height: image.height - }; - } else { - return null; - } } + } - 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; + // remove a targeted clip from the cache + uncacheAction( clip, optionalRoot ) { - if (Array.isArray(url)) { - // load array of images e.g CubeTexture - const imageArray = []; + const action = this.existingAction( clip, optionalRoot ); - for (let j = 0, jl = url.length; j < jl; j++) { - const currentUrl = url[j]; - const deserializedImage = await deserializeImage(currentUrl); + if ( action !== null ) { - 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)); - } - } - } + this._deactivateAction( action ); + this._removeInactiveAction( action ); - 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 = {}; +class Uniform { - if (json !== undefined) { - for (let i = 0, l = json.length; i < l; i++) { - const data = json[i]; + constructor( value ) { - if (data.image === undefined) { - console.warn('THREE.ObjectLoader: No "image" specified for', data.uuid); - } + this.value = value; - if (images[data.image] === undefined) { - console.warn('THREE.ObjectLoader: Undefined image', data.image); - } + } - const source = images[data.image]; - const image = source.data; - let texture; + clone() { - if (Array.isArray(image)) { - texture = new CubeTexture(); - if (image.length === 6) texture.needsUpdate = true; - } else { - if (image && image.data) { - texture = new DataTexture(); - } else { - texture = new Texture(); - } + return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() ); - if (image) texture.needsUpdate = true; // textures can have undefined image data - } + } - texture.source = source; - texture.uuid = data.uuid; - if (data.name !== undefined) texture.name = data.name; - if (data.mapping !== undefined) texture.mapping = parseConstant(data.mapping, TEXTURE_MAPPING); - if (data.offset !== undefined) texture.offset.fromArray(data.offset); - if (data.repeat !== undefined) texture.repeat.fromArray(data.repeat); - if (data.center !== undefined) texture.center.fromArray(data.center); - if (data.rotation !== undefined) texture.rotation = data.rotation; +} - if (data.wrap !== undefined) { - texture.wrapS = parseConstant(data.wrap[0], TEXTURE_WRAPPING); - texture.wrapT = parseConstant(data.wrap[1], TEXTURE_WRAPPING); - } +let id = 0; - if (data.format !== undefined) texture.format = data.format; - if (data.type !== undefined) texture.type = data.type; - if (data.encoding !== undefined) texture.encoding = data.encoding; - if (data.minFilter !== undefined) texture.minFilter = parseConstant(data.minFilter, TEXTURE_FILTER); - if (data.magFilter !== undefined) texture.magFilter = parseConstant(data.magFilter, TEXTURE_FILTER); - if (data.anisotropy !== undefined) texture.anisotropy = data.anisotropy; - if (data.flipY !== undefined) texture.flipY = data.flipY; - if (data.premultiplyAlpha !== undefined) texture.premultiplyAlpha = data.premultiplyAlpha; - if (data.unpackAlignment !== undefined) texture.unpackAlignment = data.unpackAlignment; - if (data.userData !== undefined) texture.userData = data.userData; - textures[data.uuid] = texture; - } - } +class UniformsGroup extends EventDispatcher { - return textures; - } + constructor() { - parseObject(data, geometries, materials, textures, animations) { - let object; + super(); - function getGeometry(name) { - if (geometries[name] === undefined) { - console.warn('THREE.ObjectLoader: Undefined geometry', name); - } + this.isUniformsGroup = true; - return geometries[name]; - } + Object.defineProperty( this, 'id', { value: id ++ } ); - function getMaterial(name) { - if (name === undefined) return undefined; + this.name = ''; - if (Array.isArray(name)) { - const array = []; + this.usage = StaticDrawUsage; + this.uniforms = []; - 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); - } + add( uniform ) { - array.push(materials[uuid]); - } + this.uniforms.push( uniform ); - return array; - } + return this; - if (materials[name] === undefined) { - console.warn('THREE.ObjectLoader: Undefined material', name); - } + } - return materials[name]; - } + remove( uniform ) { - function getTexture(uuid) { - if (textures[uuid] === undefined) { - console.warn('THREE.ObjectLoader: Undefined texture', uuid); - } + const index = this.uniforms.indexOf( uniform ); - return textures[uuid]; - } + if ( index !== - 1 ) this.uniforms.splice( index, 1 ); - let geometry, material; + return this; - switch (data.type) { - case 'Scene': - object = new Scene(); + } - if (data.background !== undefined) { - if (Number.isInteger(data.background)) { - object.background = new Color(data.background); - } else { - object.background = getTexture(data.background); - } - } + setName( name ) { - if (data.environment !== undefined) { - object.environment = getTexture(data.environment); - } + this.name = name; - if (data.fog !== undefined) { - if (data.fog.type === 'Fog') { - object.fog = new Fog(data.fog.color, data.fog.near, data.fog.far); - } else if (data.fog.type === 'FogExp2') { - object.fog = new FogExp2(data.fog.color, data.fog.density); - } - } + return this; - break; + } - case 'PerspectiveCamera': - object = new PerspectiveCamera(data.fov, data.aspect, data.near, data.far); - if (data.focus !== undefined) object.focus = data.focus; - if (data.zoom !== undefined) object.zoom = data.zoom; - if (data.filmGauge !== undefined) object.filmGauge = data.filmGauge; - if (data.filmOffset !== undefined) object.filmOffset = data.filmOffset; - if (data.view !== undefined) object.view = Object.assign({}, data.view); - break; + setUsage( value ) { - case 'OrthographicCamera': - object = new OrthographicCamera(data.left, data.right, data.top, data.bottom, data.near, data.far); - if (data.zoom !== undefined) object.zoom = data.zoom; - if (data.view !== undefined) object.view = Object.assign({}, data.view); - break; + this.usage = value; - case 'AmbientLight': - object = new AmbientLight(data.color, data.intensity); - break; + return this; - case 'DirectionalLight': - object = new DirectionalLight(data.color, data.intensity); - break; + } - case 'PointLight': - object = new PointLight(data.color, data.intensity, data.distance, data.decay); - break; + dispose() { - case 'RectAreaLight': - object = new RectAreaLight(data.color, data.intensity, data.width, data.height); - break; + this.dispatchEvent( { type: 'dispose' } ); - case 'SpotLight': - object = new SpotLight(data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay); - break; + return this; - case 'HemisphereLight': - object = new HemisphereLight(data.color, data.groundColor, data.intensity); - break; + } - case 'LightProbe': - object = new LightProbe().fromJSON(data); - break; + copy( source ) { - case 'SkinnedMesh': - geometry = getGeometry(data.geometry); - material = getMaterial(data.material); - object = new SkinnedMesh(geometry, material); - if (data.bindMode !== undefined) object.bindMode = data.bindMode; - if (data.bindMatrix !== undefined) object.bindMatrix.fromArray(data.bindMatrix); - if (data.skeleton !== undefined) object.skeleton = data.skeleton; - break; + this.name = source.name; + this.usage = source.usage; - case 'Mesh': - geometry = getGeometry(data.geometry); - material = getMaterial(data.material); - object = new Mesh(geometry, material); - break; + const uniformsSource = source.uniforms; - case 'InstancedMesh': - geometry = getGeometry(data.geometry); - material = getMaterial(data.material); - const count = data.count; - const instanceMatrix = data.instanceMatrix; - const instanceColor = data.instanceColor; - object = new InstancedMesh(geometry, material, count); - object.instanceMatrix = new InstancedBufferAttribute(new Float32Array(instanceMatrix.array), 16); - if (instanceColor !== undefined) object.instanceColor = new InstancedBufferAttribute(new Float32Array(instanceColor.array), instanceColor.itemSize); - break; + this.uniforms.length = 0; - case 'LOD': - object = new LOD(); - break; + for ( let i = 0, l = uniformsSource.length; i < l; i ++ ) { - case 'Line': - object = new Line(getGeometry(data.geometry), getMaterial(data.material)); - break; + this.uniforms.push( uniformsSource[ i ].clone() ); + + } + + return this; + + } - case 'LineLoop': - object = new LineLoop(getGeometry(data.geometry), getMaterial(data.material)); - break; + clone() { - case 'LineSegments': - object = new LineSegments(getGeometry(data.geometry), getMaterial(data.material)); - break; + return new this.constructor().copy( this ); - 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; +class InstancedInterleavedBuffer extends InterleavedBuffer { - case 'Bone': - object = new Bone(); - break; + constructor( array, stride, meshPerAttribute = 1 ) { - default: - object = new Object3D(); - } + super( array, stride ); - object.uuid = data.uuid; - if (data.name !== undefined) object.name = data.name; + this.isInstancedInterleavedBuffer = true; - if (data.matrix !== undefined) { - object.matrix.fromArray(data.matrix); - if (data.matrixAutoUpdate !== undefined) object.matrixAutoUpdate = data.matrixAutoUpdate; - if (object.matrixAutoUpdate) object.matrix.decompose(object.position, object.quaternion, object.scale); - } else { - if (data.position !== undefined) object.position.fromArray(data.position); - if (data.rotation !== undefined) object.rotation.fromArray(data.rotation); - if (data.quaternion !== undefined) object.quaternion.fromArray(data.quaternion); - if (data.scale !== undefined) object.scale.fromArray(data.scale); - } + this.meshPerAttribute = meshPerAttribute; - 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; - if (data.shadow.radius !== undefined) object.shadow.radius = data.shadow.radius; - if (data.shadow.mapSize !== undefined) object.shadow.mapSize.fromArray(data.shadow.mapSize); - if (data.shadow.camera !== undefined) object.shadow.camera = this.parseObject(data.shadow.camera); - } + copy( source ) { - 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; + super.copy( source ); - if (data.children !== undefined) { - const children = data.children; + this.meshPerAttribute = source.meshPerAttribute; - for (let i = 0; i < children.length; i++) { - object.add(this.parseObject(children[i], geometries, materials, textures, animations)); - } - } + return this; - 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]); - } - } + clone( data ) { - if (data.type === 'LOD') { - if (data.autoUpdate !== undefined) object.autoUpdate = data.autoUpdate; - const levels = data.levels; + const ib = super.clone( data ); - for (let l = 0; l < levels.length; l++) { - const level = levels[l]; - const child = object.getObjectByProperty('uuid', level.object); + ib.meshPerAttribute = this.meshPerAttribute; - if (child !== undefined) { - object.addLevel(child, level.distance); - } - } - } + return ib; - 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]; + toJSON( data ) { - if (skeleton === undefined) { - console.warn('THREE.ObjectLoader: No skeleton found with UUID:', child.skeleton); - } else { - child.bind(skeleton, child.bindMatrix); - } - } - }); - } - /* DEPRECATED */ + const json = super.toJSON( data ); + + json.isInstancedInterleavedBuffer = true; + json.meshPerAttribute = this.meshPerAttribute; + return json; - setTexturePath(value) { - console.warn('THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().'); - return this.setResourcePath(value); } } -const TEXTURE_MAPPING = { - UVMapping: UVMapping, - CubeReflectionMapping: CubeReflectionMapping, - CubeRefractionMapping: CubeRefractionMapping, - EquirectangularReflectionMapping: EquirectangularReflectionMapping, - EquirectangularRefractionMapping: EquirectangularRefractionMapping, - CubeUVReflectionMapping: CubeUVReflectionMapping -}; -const TEXTURE_WRAPPING = { - RepeatWrapping: RepeatWrapping, - ClampToEdgeWrapping: ClampToEdgeWrapping, - MirroredRepeatWrapping: MirroredRepeatWrapping -}; -const TEXTURE_FILTER = { - NearestFilter: NearestFilter, - NearestMipmapNearestFilter: NearestMipmapNearestFilter, - NearestMipmapLinearFilter: NearestMipmapLinearFilter, - LinearFilter: LinearFilter, - LinearMipmapNearestFilter: LinearMipmapNearestFilter, - LinearMipmapLinearFilter: LinearMipmapLinearFilter -}; +class GLBufferAttribute { -class ImageBitmapLoader extends Loader { - constructor(manager) { - super(manager); - this.isImageBitmapLoader = true; + constructor( buffer, type, itemSize, elementSize, count ) { - if (typeof createImageBitmap === 'undefined') { - console.warn('THREE.ImageBitmapLoader: createImageBitmap() not supported.'); - } + this.isGLBufferAttribute = true; - if (typeof fetch === 'undefined') { - console.warn('THREE.ImageBitmapLoader: fetch() not supported.'); - } + this.name = ''; - this.options = { - premultiplyAlpha: 'none' - }; - } + this.buffer = buffer; + this.type = type; + this.itemSize = itemSize; + this.elementSize = elementSize; + this.count = count; + + this.version = 0; - 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 () { - if (onLoad) onLoad(cached); - scope.manager.itemEnd(url); - }, 0); - return cached; - } + set needsUpdate( value ) { + + if ( value === true ) this.version ++; - const fetchOptions = {}; - fetchOptions.credentials = this.crossOrigin === 'anonymous' ? 'same-origin' : 'include'; - fetchOptions.headers = this.requestHeader; - fetch(url, fetchOptions).then(function (res) { - return res.blob(); - }).then(function (blob) { - return createImageBitmap(blob, Object.assign(scope.options, { - colorSpaceConversion: 'none' - })); - }).then(function (imageBitmap) { - Cache.add(url, imageBitmap); - if (onLoad) onLoad(imageBitmap); - scope.manager.itemEnd(url); - }).catch(function (e) { - if (onError) onError(e); - scope.manager.itemError(url); - scope.manager.itemEnd(url); - }); - scope.manager.itemStart(url); } -} + setBuffer( buffer ) { -let _context; + this.buffer = buffer; -const AudioContext = { - getContext: function () { - if (_context === undefined) { - _context = new (window.AudioContext || window.webkitAudioContext)(); - } + return this; - return _context; - }, - setContext: function (value) { - _context = value; } -}; -class AudioLoader extends Loader { - constructor(manager) { - super(manager); - } + setType( type, elementSize ) { - load(url, onLoad, onProgress, onError) { - const scope = this; - const loader = new FileLoader(this.manager); - loader.setResponseType('arraybuffer'); - loader.setPath(this.path); - loader.setRequestHeader(this.requestHeader); - loader.setWithCredentials(this.withCredentials); - loader.load(url, function (buffer) { - try { - // Create a copy of the buffer. The `decodeAudioData` method - // detaches the buffer when complete, preventing reuse. - const bufferCopy = buffer.slice(0); - const context = AudioContext.getContext(); - context.decodeAudioData(bufferCopy, function (audioBuffer) { - onLoad(audioBuffer); - }); - } catch (e) { - if (onError) { - onError(e); - } else { - console.error(e); - } + this.type = type; + this.elementSize = elementSize; + + return this; - scope.manager.itemError(url); - } - }, onProgress, onError); } -} + setItemSize( itemSize ) { -class HemisphereLightProbe extends LightProbe { - constructor(skyColor, groundColor, intensity = 1) { - super(undefined, intensity); - this.isHemisphereLightProbe = true; - 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 ); + this.itemSize = itemSize; + + return this; - 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); } -} + setCount( count ) { -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 ); + this.count = count; + + return this; - this.sh.coefficients[0].set(color1.r, color1.g, color1.b).multiplyScalar(2 * Math.sqrt(Math.PI)); } } -const _eyeRight = /*@__PURE__*/new Matrix4(); +class Raycaster { -const _eyeLeft = /*@__PURE__*/new Matrix4(); + constructor( origin, direction, near = 0, far = Infinity ) { -const _projectionMatrix = /*@__PURE__*/new Matrix4(); + this.ray = new Ray( origin, direction ); + // direction is assumed to be normalized (for accurate distance calculations) -class StereoCamera { - constructor() { - this.type = 'StereoCamera'; - this.aspect = 1; - this.eyeSep = 0.064; - this.cameraL = new PerspectiveCamera(); - this.cameraL.layers.enable(1); - this.cameraL.matrixAutoUpdate = false; - this.cameraR = new PerspectiveCamera(); - this.cameraR.layers.enable(2); - this.cameraR.matrixAutoUpdate = false; - this._cache = { - focus: null, - fov: null, - aspect: null, - near: null, - far: null, - zoom: null, - eyeSep: null + this.near = near; + this.far = far; + this.camera = null; + this.layers = new Layers(); + + this.params = { + Mesh: {}, + Line: { threshold: 1 }, + LOD: {}, + Points: { threshold: 1 }, + Sprite: {} }; + } - 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; + set( origin, direction ) { - if (needsUpdate) { - cache.focus = camera.focus; - cache.fov = camera.fov; - cache.aspect = camera.aspect * this.aspect; - cache.near = camera.near; - cache.far = camera.far; - cache.zoom = camera.zoom; - cache.eyeSep = this.eyeSep; // Off-axis stereoscopic effect based on - // http://paulbourke.net/stereographics/stereorender/ + // direction is assumed to be normalized (for accurate distance calculations) - _projectionMatrix.copy(camera.projectionMatrix); + this.ray.set( origin, direction ); - 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 + } - _eyeLeft.elements[12] = -eyeSepHalf; - _eyeRight.elements[12] = eyeSepHalf; // for left eye + setFromCamera( coords, camera ) { - 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 + if ( camera.isPerspectiveCamera ) { + + this.ray.origin.setFromMatrixPosition( camera.matrixWorld ); + this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize(); + this.camera = camera; + + } else if ( camera.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 ); - xmin = -ymax * cache.aspect - eyeSepOnProjection; - xmax = ymax * cache.aspect - eyeSepOnProjection; - _projectionMatrix.elements[0] = 2 * cache.near / (xmax - xmin); - _projectionMatrix.elements[8] = (xmax + xmin) / (xmax - xmin); - this.cameraR.projectionMatrix.copy(_projectionMatrix); } - this.cameraL.matrixWorld.copy(camera.matrixWorld).multiply(_eyeLeft); - this.cameraR.matrixWorld.copy(camera.matrixWorld).multiply(_eyeRight); } -} + intersectObject( object, recursive = true, intersects = [] ) { -class Clock { - constructor(autoStart = true) { - this.autoStart = autoStart; - this.startTime = 0; - this.oldTime = 0; - this.elapsedTime = 0; - this.running = false; - } + intersectObject( object, this, intersects, recursive ); - start() { - this.startTime = now(); - this.oldTime = this.startTime; - this.elapsedTime = 0; - this.running = true; - } + intersects.sort( ascSort ); - stop() { - this.getElapsedTime(); - this.running = false; - this.autoStart = false; - } + return intersects; - getElapsedTime() { - this.getDelta(); - return this.elapsedTime; } - getDelta() { - let diff = 0; + intersectObjects( objects, recursive = true, intersects = [] ) { - if (this.autoStart && !this.running) { - this.start(); - return 0; - } + for ( let i = 0, l = objects.length; i < l; i ++ ) { + + intersectObject( objects[ i ], this, intersects, recursive ); - if (this.running) { - const newTime = now(); - diff = (newTime - this.oldTime) / 1000; - this.oldTime = newTime; - this.elapsedTime += diff; } - return diff; + intersects.sort( ascSort ); + + return intersects; + } } -function now() { - return (typeof performance === 'undefined' ? Date : performance).now(); // see #10732 +function ascSort( a, b ) { + + return a.distance - b.distance; + } -const _position$1 = /*@__PURE__*/new Vector3(); +function intersectObject( object, raycaster, intersects, recursive ) { -const _quaternion$1 = /*@__PURE__*/new Quaternion(); + if ( object.layers.test( raycaster.layers ) ) { -const _scale$1 = /*@__PURE__*/new Vector3(); + object.raycast( raycaster, intersects ); -const _orientation$1 = /*@__PURE__*/new Vector3(); + } -class AudioListener extends Object3D { - constructor() { - super(); - this.type = 'AudioListener'; - this.context = AudioContext.getContext(); - this.gain = this.context.createGain(); - this.gain.connect(this.context.destination); - this.filter = null; - this.timeDelta = 0; // private + if ( recursive === true ) { + + const children = object.children; + + for ( let i = 0, l = children.length; i < l; i ++ ) { + + intersectObject( children[ i ], raycaster, intersects, true ); + + } + + } + +} + +/** + * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system + * + * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up. + * The azimuthal angle (theta) is measured from the positive z-axis. + */ + +class Spherical { + + constructor( radius = 1, phi = 0, theta = 0 ) { + + this.radius = radius; + this.phi = phi; // polar angle + this.theta = theta; // azimuthal angle - this._clock = new Clock(); - } + return this; - getInput() { - return this.gain; } - removeFilter() { - if (this.filter !== null) { - this.gain.disconnect(this.filter); - this.filter.disconnect(this.context.destination); - this.gain.connect(this.context.destination); - this.filter = null; - } + set( radius, phi, theta ) { + + this.radius = radius; + this.phi = phi; + this.theta = theta; return this; - } - getFilter() { - return this.filter; } - setFilter(value) { - if (this.filter !== null) { - this.gain.disconnect(this.filter); - this.filter.disconnect(this.context.destination); - } else { - this.gain.disconnect(this.context.destination); - } + copy( other ) { + + this.radius = other.radius; + this.phi = other.phi; + this.theta = other.theta; - 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); + // 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; + } - 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); + setFromVector3( v ) { - _orientation$1.set(0, 0, -1).applyQuaternion(_quaternion$1); + return this.setFromCartesianCoords( v.x, v.y, v.z ); - 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); - listener.positionZ.linearRampToValueAtTime(_position$1.z, endTime); - listener.forwardX.linearRampToValueAtTime(_orientation$1.x, endTime); - listener.forwardY.linearRampToValueAtTime(_orientation$1.y, endTime); - listener.forwardZ.linearRampToValueAtTime(_orientation$1.z, endTime); - listener.upX.linearRampToValueAtTime(up.x, endTime); - listener.upY.linearRampToValueAtTime(up.y, endTime); - listener.upZ.linearRampToValueAtTime(up.z, endTime); - } else { - listener.setPosition(_position$1.x, _position$1.y, _position$1.z); - listener.setOrientation(_orientation$1.x, _orientation$1.y, _orientation$1.z, up.x, up.y, up.z); - } } -} + setFromCartesianCoords( x, y, z ) { -class Audio extends Object3D { - constructor(listener) { - super(); - this.type = 'Audio'; - this.listener = listener; - this.context = listener.context; - this.gain = this.context.createGain(); - this.gain.connect(listener.getInput()); - this.autoplay = false; - this.buffer = null; - this.detune = 0; - this.loop = false; - this.loopStart = 0; - this.loopEnd = 0; - this.offset = 0; - this.duration = undefined; - this.playbackRate = 1; - this.isPlaying = false; - this.hasPlaybackControl = true; - this.source = null; - this.sourceType = 'empty'; - this._startedAt = 0; - this._progress = 0; - this._connected = false; - this.filters = []; - } + this.radius = Math.sqrt( x * x + y * y + z * z ); - getOutput() { - return this.gain; - } + if ( this.radius === 0 ) { - setNodeSource(audioNode) { - this.hasPlaybackControl = false; - this.sourceType = 'audioNode'; - this.source = audioNode; - this.connect(); - return this; - } + this.theta = 0; + this.phi = 0; - setMediaElementSource(mediaElement) { - this.hasPlaybackControl = false; - this.sourceType = 'mediaNode'; - this.source = this.context.createMediaElementSource(mediaElement); - this.connect(); - return this; - } + } else { - setMediaStreamSource(mediaStream) { - this.hasPlaybackControl = false; - this.sourceType = 'mediaStreamNode'; - this.source = this.context.createMediaStreamSource(mediaStream); - this.connect(); - return this; - } + this.theta = Math.atan2( x, z ); + this.phi = Math.acos( clamp( y / this.radius, - 1, 1 ) ); + + } - 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; - } + clone() { - if (this.hasPlaybackControl === false) { - console.warn('THREE.Audio: this Audio has no playback control.'); - return; - } + return new this.constructor().copy( this ); - this._startedAt = this.context.currentTime + delay; - const source = this.context.createBufferSource(); - source.buffer = this.buffer; - source.loop = this.loop; - source.loopStart = this.loopStart; - source.loopEnd = this.loopEnd; - source.onended = this.onEnded.bind(this); - source.start(this._startedAt, this._progress + this.offset, this.duration); - this.isPlaying = true; - this.source = source; - this.setDetune(this.detune); - this.setPlaybackRate(this.playbackRate); - return this.connect(); } - 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; +} - if (this.loop === true) { - // ensure _progress does not exceed duration with looped audios - this._progress = this._progress % (this.duration || this.buffer.duration); - } +/** + * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system + */ - this.source.stop(); - this.source.onended = null; - this.isPlaying = false; - } +class Cylindrical { - return this; - } + constructor( radius = 1, theta = 0, y = 0 ) { - stop() { - if (this.hasPlaybackControl === false) { - console.warn('THREE.Audio: this Audio has no playback control.'); - return; - } + 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 - 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]); - } + set( radius, theta, y ) { - this.filters[this.filters.length - 1].connect(this.getOutput()); - } else { - this.source.connect(this.getOutput()); - } + this.radius = radius; + this.theta = theta; + this.y = y; - 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]); - } + copy( other ) { - this.filters[this.filters.length - 1].disconnect(this.getOutput()); - } else { - this.source.disconnect(this.getOutput()); - } + this.radius = other.radius; + this.theta = other.theta; + this.y = other.y; - this._connected = false; return this; - } - getFilters() { - return this.filters; } - setFilters(value) { - if (!value) value = []; + setFromVector3( v ) { - if (this._connected === true) { - this.disconnect(); - this.filters = value.slice(); - this.connect(); - } else { - this.filters = value.slice(); - } + return this.setFromCartesianCoords( v.x, v.y, v.z ); - return this; } - setDetune(value) { - this.detune = value; - if (this.source.detune === undefined) return; // only set detune when available + setFromCartesianCoords( x, y, z ) { - if (this.isPlaying === true) { - this.source.detune.setTargetAtTime(this.detune, this.context.currentTime, 0.01); - } + this.radius = Math.sqrt( x * x + z * z ); + this.theta = Math.atan2( x, z ); + this.y = y; return this; - } - getDetune() { - return this.detune; } - getFilter() { - return this.getFilters()[0]; - } + clone() { + + return new this.constructor().copy( this ); - 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; +const _vector$4 = /*@__PURE__*/ new Vector2(); - if (this.isPlaying === true) { - this.source.playbackRate.setTargetAtTime(this.playbackRate, this.context.currentTime, 0.01); - } +class Box2 { - return this; - } + constructor( min = new Vector2( + Infinity, + Infinity ), max = new Vector2( - Infinity, - Infinity ) ) { - getPlaybackRate() { - return this.playbackRate; - } + this.isBox2 = true; + + this.min = min; + this.max = max; - onEnded() { - this.isPlaying = false; } - getLoop() { - if (this.hasPlaybackControl === false) { - console.warn('THREE.Audio: this Audio has no playback control.'); - return false; - } + set( min, max ) { + + this.min.copy( min ); + this.max.copy( max ); + + return this; - return this.loop; } - setLoop(value) { - if (this.hasPlaybackControl === false) { - console.warn('THREE.Audio: this Audio has no playback control.'); - return; - } + setFromPoints( points ) { - this.loop = value; + this.makeEmpty(); + + for ( let i = 0, il = points.length; i < il; i ++ ) { + + this.expandByPoint( points[ i ] ); - 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; - } + setFromCenterAndSize( center, size ) { - getVolume() { - return this.gain.gain.value; - } + const halfSize = _vector$4.copy( size ).multiplyScalar( 0.5 ); + this.min.copy( center ).sub( halfSize ); + this.max.copy( center ).add( halfSize ); - setVolume(value) { - this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01); return this; + } -} + clone() { -const _position = /*@__PURE__*/new Vector3(); + return new this.constructor().copy( this ); -const _quaternion = /*@__PURE__*/new Quaternion(); + } -const _scale = /*@__PURE__*/new Vector3(); + copy( box ) { -const _orientation = /*@__PURE__*/new Vector3(); + this.min.copy( box.min ); + this.max.copy( box.max ); -class PositionalAudio extends Audio { - constructor(listener) { - super(listener); - this.panner = this.context.createPanner(); - this.panner.panningModel = 'HRTF'; - this.panner.connect(this.gain); - } + return this; - disconnect() { - super.disconnect(); - this.panner.disconnect(this.gain); } - getOutput() { - return this.panner; - } + makeEmpty() { - getRefDistance() { - return this.panner.refDistance; - } + this.min.x = this.min.y = + Infinity; + this.max.x = this.max.y = - Infinity; - setRefDistance(value) { - this.panner.refDistance = value; return this; - } - getRolloffFactor() { - return this.panner.rolloffFactor; } - setRolloffFactor(value) { - this.panner.rolloffFactor = value; - 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 ); - getDistanceModel() { - return this.panner.distanceModel; } - setDistanceModel(value) { - this.panner.distanceModel = value; - return this; + getCenter( target ) { + + return this.isEmpty() ? target.set( 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); + } - getMaxDistance() { - return this.panner.maxDistance; + getSize( target ) { + + return this.isEmpty() ? target.set( 0, 0 ) : target.subVectors( this.max, this.min ); + } - setMaxDistance(value) { - this.panner.maxDistance = value; + expandByPoint( point ) { + + this.min.min( point ); + this.max.max( point ); + return this; + } - setDirectionalCone(coneInnerAngle, coneOuterAngle, coneOuterGain) { - this.panner.coneInnerAngle = coneInnerAngle; - this.panner.coneOuterAngle = coneOuterAngle; - this.panner.coneOuterGain = coneOuterGain; + expandByVector( vector ) { + + this.min.sub( vector ); + this.max.add( vector ); + return this; + } - updateMatrixWorld(force) { - super.updateMatrixWorld(force); - if (this.hasPlaybackControl === true && this.isPlaying === false) return; - this.matrixWorld.decompose(_position, _quaternion, _scale); + expandByScalar( scalar ) { - _orientation.set(0, 0, 1).applyQuaternion(_quaternion); + this.min.addScalar( - scalar ); + this.max.addScalar( scalar ); - const panner = this.panner; + return this; - 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); - panner.positionZ.linearRampToValueAtTime(_position.z, endTime); - panner.orientationX.linearRampToValueAtTime(_orientation.x, endTime); - panner.orientationY.linearRampToValueAtTime(_orientation.y, endTime); - panner.orientationZ.linearRampToValueAtTime(_orientation.z, endTime); - } else { - panner.setPosition(_position.x, _position.y, _position.z); - panner.setOrientation(_orientation.x, _orientation.y, _orientation.z); - } } -} + containsPoint( point ) { -class AudioAnalyser { - constructor(audio, fftSize = 2048) { - this.analyser = audio.context.createAnalyser(); - this.analyser.fftSize = fftSize; - this.data = new Uint8Array(this.analyser.frequencyBinCount); - audio.getOutput().connect(this.analyser); - } + return point.x < this.min.x || point.x > this.max.x || + point.y < this.min.y || point.y > this.max.y ? false : true; - getFrequencyData() { - this.analyser.getByteFrequencyData(this.data); - return this.data; } - getAverageFrequency() { - let value = 0; - const data = this.getFrequencyData(); + containsBox( box ) { - for (let i = 0; i < data.length; i++) { - value += data[i]; - } + 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; - return value / data.length; } -} + getParameter( point, target ) { -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) ] - // - // interpolators can use .buffer as their .result - // the data then goes to 'incoming' - // - // 'accu0' and 'accu1' are used frame-interleaved for - // the cumulative result and are compared to detect - // changes - // - // 'orig' stores the original state of the property - // - // 'add' is used for additive cumulative results - // - // 'work' is optional and is only present for quaternion types. It is used - // to store intermediate quaternion multiplication results + // This can potentially have a divide by zero if the box + // has a size dimension of 0. - switch (typeName) { - case 'quaternion': - mixFunction = this._slerp; - mixFunctionAdditive = this._slerpAdditive; - setIdentity = this._setAdditiveIdentityQuaternion; - this.buffer = new Float64Array(valueSize * 6); - this._workIndex = 5; - break; + 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 ) + ); - 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 + } - mixFunctionAdditive = this._select; - setIdentity = this._setAdditiveIdentityOther; - this.buffer = new Array(valueSize * 5); - break; + intersectsBox( box ) { - default: - mixFunction = this._lerp; - mixFunctionAdditive = this._lerpAdditive; - setIdentity = this._setAdditiveIdentityNumeric; - this.buffer = new Float64Array(valueSize * 5); - } + // using 4 splitting planes to rule out intersections - this._mixBufferRegion = mixFunction; - this._mixBufferRegionAdditive = mixFunctionAdditive; - this._setIdentity = setIdentity; - this._origIndex = 3; - this._addIndex = 4; - this.cumulativeWeight = 0; - this.cumulativeWeightAdditive = 0; - this.useCount = 0; - this.referenceCount = 0; - } // accumulate data in the 'incoming' region into 'accu' + 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; + } - 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; - let currentWeight = this.cumulativeWeight; + clampPoint( point, target ) { - if (currentWeight === 0) { - // accuN := incoming * weight - for (let i = 0; i !== stride; ++i) { - buffer[offset + i] = buffer[i]; - } + return target.copy( point ).clamp( this.min, this.max ); - currentWeight = weight; - } else { - // accuN := accuN + incoming * weight - currentWeight += weight; - const mix = weight / currentWeight; + } - this._mixBufferRegion(buffer, offset, 0, mix, stride); - } + distanceToPoint( point ) { - this.cumulativeWeight = currentWeight; - } // accumulate data in the 'incoming' region into 'add' + const clampedPoint = _vector$4.copy( point ).clamp( this.min, this.max ); + return clampedPoint.sub( point ).length(); + } - accumulateAdditive(weight) { - const buffer = this.buffer, - stride = this.valueSize, - offset = stride * this._addIndex; + intersect( box ) { - if (this.cumulativeWeightAdditive === 0) { - // add = identity - this._setIdentity(); - } // add := add + incoming * weight + this.min.max( box.min ); + this.max.min( box.max ); + return this; - this._mixBufferRegionAdditive(buffer, offset, 0, weight, stride); + } - this.cumulativeWeightAdditive += weight; - } // apply the state of 'accu' to the binding when accus differ + union( box ) { + this.min.min( box.min ); + this.max.max( box.max ); - apply(accuIndex) { - const stride = this.valueSize, - buffer = this.buffer, - offset = accuIndex * stride + stride, - weight = this.cumulativeWeight, - weightAdditive = this.cumulativeWeightAdditive, - binding = this.binding; - this.cumulativeWeight = 0; - this.cumulativeWeightAdditive = 0; + return this; - if (weight < 1) { - // accuN := accuN + original * ( 1 - cumulativeWeight ) - const originalValueOffset = stride * this._origIndex; + } - this._mixBufferRegion(buffer, offset, originalValueOffset, 1 - weight, stride); - } + translate( offset ) { - if (weightAdditive > 0) { - // accuN := accuN + additive accuN - this._mixBufferRegionAdditive(buffer, offset, this._addIndex * stride, 1, stride); - } + this.min.add( offset ); + this.max.add( offset ); - 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 + return this; + } - 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 + equals( box ) { - for (let i = stride, e = originalValueOffset; i !== e; ++i) { - buffer[i] = buffer[originalValueOffset + i % stride]; - } // Add to identity for additive + return box.min.equals( this.min ) && box.max.equals( this.max ); + } - this._setIdentity(); +} - this.cumulativeWeight = 0; - this.cumulativeWeightAdditive = 0; - } // apply the state previously taken via 'saveOriginalState' to the binding +const _startP = /*@__PURE__*/ new Vector3(); +const _startEnd = /*@__PURE__*/ new Vector3(); +class Line3 { - restoreOriginalState() { - const originalValueOffset = this.valueSize * 3; - this.binding.setValue(this.buffer, originalValueOffset); - } + constructor( start = new Vector3(), end = new Vector3() ) { - _setAdditiveIdentityNumeric() { - const startIndex = this._addIndex * this.valueSize; - const endIndex = startIndex + this.valueSize; + this.start = start; + this.end = end; - for (let i = startIndex; i < endIndex; i++) { - this.buffer[i] = 0; - } } - _setAdditiveIdentityQuaternion() { - this._setAdditiveIdentityNumeric(); + set( start, end ) { + + this.start.copy( start ); + this.end.copy( end ); + + return this; - this.buffer[this._addIndex * this.valueSize + 3] = 1; } - _setAdditiveIdentityOther() { - const startIndex = this._origIndex * this.valueSize; - const targetIndex = this._addIndex * this.valueSize; + copy( line ) { - for (let i = 0; i < this.valueSize; i++) { - this.buffer[targetIndex + i] = this.buffer[startIndex + i]; - } - } // mix functions + this.start.copy( line.start ); + this.end.copy( line.end ); + return this; - _select(buffer, dstOffset, srcOffset, t, stride) { - if (t >= 0.5) { - for (let i = 0; i !== stride; ++i) { - buffer[dstOffset + i] = buffer[srcOffset + i]; - } - } } - _slerp(buffer, dstOffset, srcOffset, t) { - Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t); + getCenter( target ) { + + return target.addVectors( this.start, this.end ).multiplyScalar( 0.5 ); + } - _slerpAdditive(buffer, dstOffset, srcOffset, t, stride) { - const workOffset = this._workIndex * stride; // Store result in intermediate buffer offset + delta( target ) { - Quaternion.multiplyQuaternionsFlat(buffer, workOffset, buffer, dstOffset, buffer, srcOffset); // Slerp to the intermediate result + return target.subVectors( this.end, this.start ); - Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t); } - _lerp(buffer, dstOffset, srcOffset, t, stride) { - const s = 1 - t; + distanceSq() { - for (let i = 0; i !== stride; ++i) { - const j = dstOffset + i; - buffer[j] = buffer[j] * s + buffer[srcOffset + i] * t; - } - } + return this.start.distanceToSquared( this.end ); - _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; - } } -} + distance() { -// Characters [].:/ are reserved for track binding syntax. -const _RESERVED_CHARS_RE = '\\[\\]\\.:\\/'; + return this.start.distanceTo( this.end ); -const _reservedRe = new RegExp('[' + _RESERVED_CHARS_RE + ']', 'g'); // Attempts to allow node names from any language. ES5's `\w` regexp matches -// only latin characters, and the unicode \p{L} is not yet supported. So -// instead, we exclude reserved characters and match everything else. + } + at( t, target ) { -const _wordChar = '[^' + _RESERVED_CHARS_RE + ']'; + return this.delta( target ).multiplyScalar( t ).add( this.start ); -const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace('\\.', '') + ']'; // Parent directories, delimited by '/' or ':'. Currently unused, but must -// be matched to parse the rest of the track name. + } + closestPointToPointParameter( point, clampToLine ) { -const _directoryRe = /((?:WC+[\/:])*)/.source.replace('WC', _wordChar); // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. + _startP.subVectors( point, this.start ); + _startEnd.subVectors( this.end, this.start ); + const startEnd2 = _startEnd.dot( _startEnd ); + const startEnd_startP = _startEnd.dot( _startP ); -const _nodeRe = /(WCOD+)?/.source.replace('WCOD', _wordCharOrDot); // Object on target node, and accessor. May not contain reserved -// characters. Accessor may contain any character except closing bracket. + let t = startEnd_startP / startEnd2; + if ( clampToLine ) { -const _objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace('WC', _wordChar); // Property and accessor. May not contain reserved characters. Accessor may -// contain any non-bracket characters. + t = clamp( t, 0, 1 ); + + } + return t; -const _propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace('WC', _wordChar); + } -const _trackRe = new RegExp('' + '^' + _directoryRe + _nodeRe + _objectRe + _propertyRe + '$'); + closestPointToPoint( point, clampToLine, target ) { -const _supportedObjectNames = ['material', 'materials', 'bones']; + const t = this.closestPointToPointParameter( point, clampToLine ); + + return this.delta( target ).multiplyScalar( t ).add( this.start ); -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 + applyMatrix4( matrix ) { - const firstValidIndex = this._targetGroup.nCachedObjects_, - binding = this._bindings[firstValidIndex]; // and only call .getValue on the first + this.start.applyMatrix4( matrix ); + this.end.applyMatrix4( matrix ); + + return this; - if (binding !== undefined) binding.getValue(array, offset); } - setValue(array, offset) { - const bindings = this._bindings; + equals( line ) { + + return line.start.equals( this.start ) && line.end.equals( this.end ); - for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { - bindings[i].setValue(array, offset); - } } - bind() { - const bindings = this._bindings; + clone() { + + return new this.constructor().copy( this ); - 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(); - } - } +const _vector$3 = /*@__PURE__*/ new Vector3(); -} // 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 SpotLightHelper extends Object3D { + constructor( light, color ) { -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' + super(); - this.getValue = this._getValue_unbound; - this.setValue = this._setValue_unbound; - } + this.light = light; - static create(root, path, parsedPath) { - if (!(root && root.isAnimationObjectGroup)) { - return new PropertyBinding(root, path, parsedPath); - } else { - return new PropertyBinding.Composite(root, path, parsedPath); - } - } - /** - * Replaces spaces with underscores and removes unsupported characters from - * node names, to ensure compatibility with parseTrackName(). - * - * @param {string} name Node name to be sanitized. - * @return {string} - */ + this.matrix = light.matrixWorld; + this.matrixAutoUpdate = false; + + this.color = color; + this.type = 'SpotLightHelper'; - static sanitizeNodeName(name) { - return name.replace(/\s/g, '_').replace(_reservedRe, ''); - } + const geometry = new BufferGeometry(); - static parseTrackName(trackName) { - const matches = _trackRe.exec(trackName); + 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 + ]; - if (matches === null) { - throw new Error('PropertyBinding: Cannot parse trackName: ' + trackName); - } + for ( let i = 0, j = 1, l = 32; i < l; i ++, j ++ ) { - const results = { - // directoryName: matches[ 1 ], // (tschw) currently unused - nodeName: matches[2], - objectName: matches[3], - objectIndex: matches[4], - propertyName: matches[5], - // required - propertyIndex: matches[6] - }; - const lastDot = results.nodeName && results.nodeName.lastIndexOf('.'); + const p1 = ( i / l ) * Math.PI * 2; + const p2 = ( j / l ) * Math.PI * 2; - if (lastDot !== undefined && lastDot !== -1) { - 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). + positions.push( + Math.cos( p1 ), Math.sin( p1 ), 1, + Math.cos( p2 ), Math.sin( p2 ), 1 + ); - 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); - } + geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + + const material = new LineBasicMaterial( { fog: false, toneMapped: false } ); + + this.cone = new LineSegments( geometry, material ); + this.add( this.cone ); + + this.update(); - 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. + dispose() { + this.cone.geometry.dispose(); + this.cone.material.dispose(); - if (root.skeleton) { - const bone = root.skeleton.getBoneByName(nodeName); + } - if (bone !== undefined) { - return bone; - } - } // search into node subtree. + update() { + this.light.updateWorldMatrix( true, false ); + this.light.target.updateWorldMatrix( true, false ); - if (root.children) { - const searchNodeSubtree = function (children) { - for (let i = 0; i < children.length; i++) { - const childNode = children[i]; + const coneLength = this.light.distance ? this.light.distance : 1000; + const coneWidth = coneLength * Math.tan( this.light.angle ); - if (childNode.name === nodeName || childNode.uuid === nodeName) { - return childNode; - } + this.cone.scale.set( coneWidth, coneWidth, coneLength ); - const result = searchNodeSubtree(childNode.children); - if (result) return result; - } + _vector$3.setFromMatrixPosition( this.light.target.matrixWorld ); - return null; - }; + this.cone.lookAt( _vector$3 ); - const subTreeNode = searchNodeSubtree(root.children); + if ( this.color !== undefined ) { + + this.cone.material.color.set( this.color ); + + } else { + + this.cone.material.color.copy( this.light.color ); - if (subTreeNode) { - return subTreeNode; - } } - return null; - } // these are used to "bind" a nonexistent property + } + +} + +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 ); + + const geometry = new BufferGeometry(); + const vertices = []; + const colors = []; - _getValue_unavailable() {} + const color1 = new Color( 0, 0, 1 ); + const color2 = new Color( 0, 1, 0 ); - _setValue_unavailable() {} // Getters + for ( let i = 0; i < bones.length; i ++ ) { + const bone = bones[ i ]; - _getValue_direct(buffer, offset) { - buffer[offset] = this.targetObject[this.propertyName]; - } + if ( bone.parent && bone.parent.isBone ) { - _getValue_array(buffer, offset) { - const source = this.resolvedProperty; + vertices.push( 0, 0, 0 ); + vertices.push( 0, 0, 0 ); + colors.push( color1.r, color1.g, color1.b ); + colors.push( color2.r, color2.g, color2.b ); - 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 + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + const material = new LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, toneMapped: false, transparent: true } ); - _setValue_direct(buffer, offset) { - this.targetObject[this.propertyName] = buffer[offset]; - } + super( geometry, material ); - _setValue_direct_setNeedsUpdate(buffer, offset) { - this.targetObject[this.propertyName] = buffer[offset]; - this.targetObject.needsUpdate = true; - } + this.isSkeletonHelper = true; - _setValue_direct_setMatrixWorldNeedsUpdate(buffer, offset) { - this.targetObject[this.propertyName] = buffer[offset]; - this.targetObject.matrixWorldNeedsUpdate = true; - } // EntireArray + this.type = 'SkeletonHelper'; + this.root = object; + this.bones = bones; - _setValue_array(buffer, offset) { - const dest = this.resolvedProperty; + this.matrix = object.matrixWorld; + this.matrixAutoUpdate = false; - for (let i = 0, n = dest.length; i !== n; ++i) { - dest[i] = buffer[offset++]; - } } - _setValue_array_setNeedsUpdate(buffer, offset) { - const dest = this.resolvedProperty; + updateMatrixWorld( force ) { - for (let i = 0, n = dest.length; i !== n; ++i) { - dest[i] = buffer[offset++]; - } + const bones = this.bones; - this.targetObject.needsUpdate = true; - } + const geometry = this.geometry; + const position = geometry.getAttribute( 'position' ); - _setValue_array_setMatrixWorldNeedsUpdate(buffer, offset) { - const dest = this.resolvedProperty; + _matrixWorldInv.copy( this.root.matrixWorld ).invert(); - for (let i = 0, n = dest.length; i !== n; ++i) { - dest[i] = buffer[offset++]; - } + for ( let i = 0, j = 0; i < bones.length; i ++ ) { - this.targetObject.matrixWorldNeedsUpdate = true; - } // ArrayElement + const bone = bones[ i ]; + if ( bone.parent && bone.parent.isBone ) { - _setValue_arrayElement(buffer, offset) { - this.resolvedProperty[this.propertyIndex] = buffer[offset]; - } + _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld ); + _vector$2.setFromMatrixPosition( _boneMatrix ); + position.setXYZ( j, _vector$2.x, _vector$2.y, _vector$2.z ); - _setValue_arrayElement_setNeedsUpdate(buffer, offset) { - this.resolvedProperty[this.propertyIndex] = buffer[offset]; - this.targetObject.needsUpdate = true; - } + _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld ); + _vector$2.setFromMatrixPosition( _boneMatrix ); + position.setXYZ( j + 1, _vector$2.x, _vector$2.y, _vector$2.z ); - _setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer, offset) { - this.resolvedProperty[this.propertyIndex] = buffer[offset]; - this.targetObject.matrixWorldNeedsUpdate = true; - } // HasToFromArray + j += 2; + } - _setValue_fromArray(buffer, offset) { - this.resolvedProperty.fromArray(buffer, offset); - } + } - _setValue_fromArray_setNeedsUpdate(buffer, offset) { - this.resolvedProperty.fromArray(buffer, offset); - this.targetObject.needsUpdate = true; - } + geometry.getAttribute( 'position' ).needsUpdate = true; - _setValue_fromArray_setMatrixWorldNeedsUpdate(buffer, offset) { - this.resolvedProperty.fromArray(buffer, offset); - this.targetObject.matrixWorldNeedsUpdate = true; - } + super.updateMatrixWorld( force ); - _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 - + dispose() { - bind() { - let targetObject = this.node; - const parsedPath = this.parsedPath; - const objectName = parsedPath.objectName; - const propertyName = parsedPath.propertyName; - let propertyIndex = parsedPath.propertyIndex; + this.geometry.dispose(); + this.material.dispose(); - if (!targetObject) { - targetObject = PropertyBinding.findNode(this.rootNode, parsedPath.nodeName) || this.rootNode; - this.node = targetObject; - } // 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 - if (!targetObject) { - console.error('THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.'); - return; - } +function getBoneList( object ) { - if (objectName) { - let objectIndex = parsedPath.objectIndex; // special cases were we need to reach deeper into the hierarchy to get the face materials.... + const boneList = []; - 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 ( object.isBone === true ) { - 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; - } + boneList.push( object ); - 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. + for ( let i = 0; i < object.children.length; i ++ ) { + boneList.push.apply( boneList, getBoneList( object.children[ i ] ) ); - 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; - } - } + return boneList; - break; +} - default: - if (targetObject[objectName] === undefined) { - console.error('THREE.PropertyBinding: Can not bind to objectName of node undefined.', this); - return; - } +class PointLightHelper extends Mesh { - targetObject = targetObject[objectName]; - } + constructor( light, sphereSize, color ) { - if (objectIndex !== undefined) { - if (targetObject[objectIndex] === undefined) { - console.error('THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject); - return; - } + const geometry = new SphereGeometry( sphereSize, 4, 2 ); + const material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } ); - targetObject = targetObject[objectIndex]; - } - } // resolve property + super( geometry, material ); + this.light = light; - const nodeProperty = targetObject[propertyName]; + this.color = color; - 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 + this.type = 'PointLightHelper'; + this.matrix = this.light.matrixWorld; + this.matrixAutoUpdate = false; - let versioning = this.Versioning.None; - this.targetObject = targetObject; + this.update(); - 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 + /* + // TODO: delete this comment? + const distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 ); + const distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } ); - let bindingType = this.BindingType.Direct; + this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial ); + this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial ); - 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; - } + const d = light.distance; - if (!targetObject.geometry.morphAttributes) { - console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this); - return; - } + if ( d === 0.0 ) { - if (targetObject.morphTargetDictionary[propertyIndex] !== undefined) { - propertyIndex = targetObject.morphTargetDictionary[propertyIndex]; - } - } + this.lightDistance.visible = false; - bindingType = this.BindingType.ArrayElement; - this.resolvedProperty = nodeProperty; - this.propertyIndex = propertyIndex; - } else if (nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined) { - // must use copy for Object3D.Euler/Quaternion - bindingType = this.BindingType.HasFromToArray; - this.resolvedProperty = nodeProperty; - } else if (Array.isArray(nodeProperty)) { - bindingType = this.BindingType.EntireArray; - this.resolvedProperty = nodeProperty; - } else { - this.propertyName = propertyName; - } // select getter / setter + } else { + this.lightDistance.scale.set( d, d, d ); - 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.add( this.lightDistance ); + */ - this.getValue = this._getValue_unbound; - this.setValue = this._setValue_unbound; } -} + dispose() { -PropertyBinding.Composite = Composite; -PropertyBinding.prototype.BindingType = { - Direct: 0, - EntireArray: 1, - ArrayElement: 2, - HasFromToArray: 3 -}; -PropertyBinding.prototype.Versioning = { - None: 0, - NeedsUpdate: 1, - 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._setValue_fromArray, PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate, PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate]]; + this.geometry.dispose(); + this.material.dispose(); -/** - * - * A group of objects that receives a shared animation state. - * - * Usage: - * - * - Add objects you would otherwise pass as 'root' to the - * constructor or the .clipAction method of AnimationMixer. - * - * - Instead pass this object as 'root'. - * - * - You can also add and remove objects later when the mixer - * is running. - * - * Note: - * - * Objects of this class appear as one object to the mixer, - * so cache control of the individual objects must be done - * on the group. - * - * Limitation: - * - * - The animated properties must be compatible among the - * all objects in the group. - * - * - A single property can either be controlled through a - * target group or directly, but not both. - */ + } -class AnimationObjectGroup { - constructor() { - this.isAnimationObjectGroup = true; - this.uuid = generateUUID(); // cached objects followed by the active ones + update() { - this._objects = Array.prototype.slice.call(arguments); - this.nCachedObjects_ = 0; // threshold - // note: read by PropertyBinding.Composite + this.light.updateWorldMatrix( true, false ); - const indices = {}; - this._indicesByUUID = indices; // for bookkeeping + if ( this.color !== undefined ) { - for (let i = 0, n = arguments.length; i !== n; ++i) { - indices[arguments[i].uuid] = i; - } + this.material.color.set( this.color ); - this._paths = []; // inside: string + } else { - this._parsedPaths = []; // inside: { we don't care, here } + this.material.color.copy( this.light.color ); - this._bindings = []; // inside: Array< PropertyBinding > + } - this._bindingsIndicesByPath = {}; // inside: indices in these arrays + /* + const d = this.light.distance; - const scope = this; - this.stats = { - objects: { - get total() { - return scope._objects.length; - }, + if ( d === 0.0 ) { - get inUse() { - return this.total - scope.nCachedObjects_; - } + this.lightDistance.visible = false; - }, + } else { - get bindingsPerObject() { - return scope._bindings.length; - } + this.lightDistance.visible = true; + this.lightDistance.scale.set( d, d, d ); + + } + */ - }; } - add() { - const objects = this._objects, - indicesByUUID = this._indicesByUUID, - paths = this._paths, - parsedPaths = this._parsedPaths, - bindings = this._bindings, - nBindings = bindings.length; - let knownObject = undefined, - nObjects = objects.length, - nCachedObjects = this.nCachedObjects_; +} - for (let i = 0, n = arguments.length; i !== n; ++i) { - const object = arguments[i], - uuid = object.uuid; - let index = indicesByUUID[uuid]; +const _vector$1 = /*@__PURE__*/ new Vector3(); +const _color1 = /*@__PURE__*/ new Color(); +const _color2 = /*@__PURE__*/ new Color(); - if (index === undefined) { - // unknown object -> add it to the ACTIVE region - index = nObjects++; - indicesByUUID[uuid] = index; - objects.push(object); // accounting is done, now do the same for all bindings - - for (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 - - const firstActiveIndex = --nCachedObjects, - lastCachedObject = objects[firstActiveIndex]; - indicesByUUID[lastCachedObject.uuid] = index; - objects[index] = lastCachedObject; - indicesByUUID[uuid] = firstActiveIndex; - objects[firstActiveIndex] = object; // accounting is done, now do the same for all bindings - - for (let j = 0, m = nBindings; j !== m; ++j) { - const bindingsForPath = bindings[j], - 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]); - } +class HemisphereLightHelper extends Object3D { - 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 + constructor( light, size, color ) { - } // for arguments + super(); + this.light = light; - this.nCachedObjects_ = nCachedObjects; - } + this.matrix = light.matrixWorld; + this.matrixAutoUpdate = false; - remove() { - const objects = this._objects, - indicesByUUID = this._indicesByUUID, - bindings = this._bindings, - nBindings = bindings.length; - let nCachedObjects = this.nCachedObjects_; + this.color = color; - for (let i = 0, n = arguments.length; i !== n; ++i) { - const object = arguments[i], - uuid = object.uuid, - index = indicesByUUID[uuid]; + this.type = 'HemisphereLightHelper'; - if (index !== undefined && index >= nCachedObjects) { - // move existing object into the CACHED region - const lastCachedIndex = nCachedObjects++, - firstActiveObject = objects[lastCachedIndex]; - indicesByUUID[firstActiveObject.uuid] = index; - objects[index] = firstActiveObject; - indicesByUUID[uuid] = lastCachedIndex; - objects[lastCachedIndex] = object; // accounting is done, now do the same for all bindings + const geometry = new OctahedronGeometry( size ); + geometry.rotateY( Math.PI * 0.5 ); - for (let j = 0, m = nBindings; j !== m; ++j) { - const bindingsForPath = bindings[j], - firstActive = bindingsForPath[lastCachedIndex], - binding = bindingsForPath[index]; - bindingsForPath[index] = firstActive; - bindingsForPath[lastCachedIndex] = binding; - } - } - } // for arguments + this.material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } ); + if ( this.color === undefined ) this.material.vertexColors = true; + const position = geometry.getAttribute( 'position' ); + const colors = new Float32Array( position.count * 3 ); - this.nCachedObjects_ = nCachedObjects; - } // remove & forget + geometry.setAttribute( 'color', new BufferAttribute( colors, 3 ) ); + this.add( new Mesh( geometry, this.material ) ); - uncache() { - const objects = this._objects, - indicesByUUID = this._indicesByUUID, - bindings = this._bindings, - nBindings = bindings.length; - let nCachedObjects = this.nCachedObjects_, - nObjects = objects.length; + this.update(); - for (let i = 0, n = arguments.length; i !== n; ++i) { - const object = arguments[i], - uuid = object.uuid, - index = indicesByUUID[uuid]; + } - if (index !== undefined) { - delete indicesByUUID[uuid]; + dispose() { - 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 - - indicesByUUID[lastCachedObject.uuid] = index; - objects[index] = lastCachedObject; // last object goes to the activated slot and pop - - indicesByUUID[lastObject.uuid] = firstActiveIndex; - objects[firstActiveIndex] = lastObject; - objects.pop(); // accounting is done, now do the same for all bindings - - for (let j = 0, m = nBindings; j !== m; ++j) { - const bindingsForPath = bindings[j], - lastCached = bindingsForPath[firstActiveIndex], - last = bindingsForPath[lastIndex]; - bindingsForPath[index] = lastCached; - bindingsForPath[firstActiveIndex] = last; - bindingsForPath.pop(); - } - } else { - // object is active, just swap with the last and pop - const lastIndex = --nObjects, - lastObject = objects[lastIndex]; + this.children[ 0 ].geometry.dispose(); + this.children[ 0 ].material.dispose(); - if (lastIndex > 0) { - indicesByUUID[lastObject.uuid] = index; - } + } - objects[index] = lastObject; - objects.pop(); // accounting is done, now do the same for all bindings + update() { - for (let j = 0, m = nBindings; j !== m; ++j) { - const bindingsForPath = bindings[j]; - bindingsForPath[index] = bindingsForPath[lastIndex]; - bindingsForPath.pop(); - } - } // cached or active + const mesh = this.children[ 0 ]; - } // if object is known + if ( this.color !== undefined ) { - } // for arguments + this.material.color.set( this.color ); + + } else { + const colors = mesh.geometry.getAttribute( 'color' ); - this.nCachedObjects_ = nCachedObjects; - } // Internal interface used by befriended PropertyBinding.Composite: + _color1.copy( this.light.color ); + _color2.copy( this.light.groundColor ); + for ( let i = 0, l = colors.count; i < l; i ++ ) { - 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); - index = bindings.length; - indicesByPath[path] = index; - paths.push(path); - parsedPaths.push(parsedPath); - bindings.push(bindingsForPath); + const color = ( i < ( l / 2 ) ) ? _color1 : _color2; - for (let i = nCachedObjects, n = objects.length; i !== n; ++i) { - const object = objects[i]; - bindingsForPath[i] = new PropertyBinding(object, path, parsedPath); - } + colors.setXYZ( i, color.r, color.g, color.b ); - 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]; + colors.needsUpdate = true; - if (index !== undefined) { - const paths = this._paths, - parsedPaths = this._parsedPaths, - bindings = this._bindings, - lastBindingsIndex = bindings.length - 1, - lastBindings = bindings[lastBindingsIndex], - lastBindingsPath = path[lastBindingsIndex]; - indicesByPath[lastBindingsPath] = index; - bindings[index] = lastBindings; - bindings.pop(); - parsedPaths[index] = parsedPaths[lastBindingsIndex]; - parsedPaths.pop(); - paths[index] = paths[lastBindingsIndex]; - paths.pop(); } - } -} + this.light.updateWorldMatrix( true, false ); -class AnimationAction { - constructor(mixer, clip, localRoot = null, blendMode = clip.blendMode) { - this._mixer = mixer; - this._clip = clip; - this._localRoot = localRoot; - this.blendMode = blendMode; - const tracks = clip.tracks, - nTracks = tracks.length, - interpolants = new Array(nTracks); - const interpolantSettings = { - endingStart: ZeroCurvatureEnding, - endingEnd: ZeroCurvatureEnding - }; + mesh.lookAt( _vector$1.setFromMatrixPosition( this.light.matrixWorld ).negate() ); - 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) +} - this._propertyBindings = new Array(nTracks); - this._cacheIndex = null; // for the memory manager +class GridHelper extends LineSegments { - this._byClipCacheIndex = null; // for the memory manager + constructor( size = 10, divisions = 10, color1 = 0x444444, color2 = 0x888888 ) { - this._timeScaleInterpolant = null; - this._weightInterpolant = null; - this.loop = LoopRepeat; - this._loopCount = -1; // global mixer time when the action is to be started - // it's set back to 'null' upon start of the action + color1 = new Color( color1 ); + color2 = new Color( color2 ); - this._startTime = null; // scaled local time of the action - // gets clamped or wrapped to 0..clip.duration according to loop + const center = divisions / 2; + const step = size / divisions; + const halfSize = size / 2; - this.time = 0; - this.timeScale = 1; - this._effectiveTimeScale = 1; - this.weight = 1; - this._effectiveWeight = 1; - this.repetitions = Infinity; // no. of repetitions when looping + const vertices = [], colors = []; - this.paused = false; // true -> zero effective time scale + for ( let i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) { - this.enabled = true; // false -> zero effective weight + vertices.push( - halfSize, 0, k, halfSize, 0, k ); + vertices.push( k, 0, - halfSize, k, 0, halfSize ); - this.clampWhenFinished = false; // keep feeding the last frame? + const color = i === center ? color1 : color2; - this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate + color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; - this.zeroSlopeAtEnd = true; // clips for start, loop and end - } // State & Scheduling + } + const geometry = new BufferGeometry(); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - play() { - this._mixer._activateAction(this); + const material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } ); - return this; - } + super( geometry, material ); - stop() { - this._mixer._deactivateAction(this); + this.type = 'GridHelper'; - return this.reset(); } - reset() { - this.paused = false; - this.enabled = true; - this.time = 0; // restart clip - - this._loopCount = -1; // forget previous loops + dispose() { - this._startTime = null; // forget scheduling + this.geometry.dispose(); + this.material.dispose(); - 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 +} +class PolarGridHelper extends LineSegments { - isScheduled() { - return this._mixer._isActiveAction(this); - } + constructor( radius = 10, sectors = 16, rings = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888 ) { - startAt(time) { - this._startTime = time; - return this; - } + color1 = new Color( color1 ); + color2 = new Color( color2 ); - setLoop(mode, repetitions) { - this.loop = mode; - this.repetitions = repetitions; - return this; - } // Weight - // set the weight stopping any scheduled fading - // although .enabled = false yields an effective weight of zero, this - // method does *not* change .enabled, because it would be confusing + const vertices = []; + const colors = []; + // create the sectors - setEffectiveWeight(weight) { - this.weight = weight; // note: same logic as when updated at runtime + if ( sectors > 1 ) { - this._effectiveWeight = this.enabled ? weight : 0; - return this.stopFading(); - } // return the weight considering fading and .enabled + for ( let i = 0; i < sectors; i ++ ) { + const v = ( i / sectors ) * ( Math.PI * 2 ); - getEffectiveWeight() { - return this._effectiveWeight; - } + const x = Math.sin( v ) * radius; + const z = Math.cos( v ) * radius; - fadeIn(duration) { - return this._scheduleFading(duration, 0, 1); - } + vertices.push( 0, 0, 0 ); + vertices.push( x, 0, z ); - fadeOut(duration) { - return this._scheduleFading(duration, 1, 0); - } + const color = ( i & 1 ) ? color1 : color2; - crossFadeFrom(fadeOutAction, duration, warp) { - fadeOutAction.fadeOut(duration); - this.fadeIn(duration); + colors.push( color.r, color.g, color.b ); + colors.push( color.r, color.g, color.b ); + + } - if (warp) { - const fadeInDuration = this._clip.duration, - fadeOutDuration = fadeOutAction._clip.duration, - startEndRatio = fadeOutDuration / fadeInDuration, - endStartRatio = fadeInDuration / fadeOutDuration; - fadeOutAction.warp(1.0, startEndRatio, duration); - this.warp(endStartRatio, 1.0, duration); } - return this; - } + // create the rings - crossFadeTo(fadeInAction, duration, warp) { - return fadeInAction.crossFadeFrom(this, duration, warp); - } + for ( let i = 0; i < rings; i ++ ) { - stopFading() { - const weightInterpolant = this._weightInterpolant; + const color = ( i & 1 ) ? color1 : color2; - if (weightInterpolant !== null) { - this._weightInterpolant = null; + const r = radius - ( radius / rings * i ); - this._mixer._takeBackControlInterpolant(weightInterpolant); - } + for ( let j = 0; j < divisions; j ++ ) { - return this; - } // Time Scale Control - // set the time scale stopping any scheduled warping - // although .paused = true yields an effective time scale of zero, this - // method does *not* change .paused, because it would be confusing + // first vertex + let v = ( j / divisions ) * ( Math.PI * 2 ); - setEffectiveTimeScale(timeScale) { - this.timeScale = timeScale; - this._effectiveTimeScale = this.paused ? 0 : timeScale; - return this.stopWarping(); - } // return the time scale considering warping and .paused + 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 ); - getEffectiveTimeScale() { - return this._effectiveTimeScale; - } + // second vertex - setDuration(duration) { - this.timeScale = this._clip.duration / duration; - return this.stopWarping(); - } + v = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 ); - syncWith(action) { - this.time = action.time; - this.timeScale = action.timeScale; - return this.stopWarping(); - } + x = Math.sin( v ) * r; + z = Math.cos( v ) * r; - halt(duration) { - return this.warp(this._effectiveTimeScale, 0, duration); - } + vertices.push( x, 0, z ); + colors.push( color.r, color.g, color.b ); - warp(startTimeScale, endTimeScale, duration) { - const mixer = this._mixer, - 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; - times[0] = now; - times[1] = now + duration; - values[0] = startTimeScale / timeScale; - values[1] = endTimeScale / timeScale; - return this; - } + const geometry = new BufferGeometry(); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - stopWarping() { - const timeScaleInterpolant = this._timeScaleInterpolant; + const material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } ); - if (timeScaleInterpolant !== null) { - this._timeScaleInterpolant = null; + super( geometry, material ); - this._mixer._takeBackControlInterpolant(timeScaleInterpolant); - } + this.type = 'PolarGridHelper'; - return this; - } // Object Accessors + } + dispose() { - getMixer() { - return this._mixer; - } + this.geometry.dispose(); + this.material.dispose(); - getClip() { - return this._clip; } - getRoot() { - return this._localRoot || this._mixer._root; - } // Interna +} +const _v1 = /*@__PURE__*/ new Vector3(); +const _v2 = /*@__PURE__*/ new Vector3(); +const _v3 = /*@__PURE__*/ new Vector3(); - _update(time, deltaTime, timeDirection, accuIndex) { - // called by the mixer - if (!this.enabled) { - // call ._updateWeight() to update ._effectiveWeight - this._updateWeight(time); +class DirectionalLightHelper extends Object3D { - return; - } + constructor( light, size, color ) { - const startTime = this._startTime; + super(); - if (startTime !== null) { - // check for scheduled start of action - const timeRunning = (time - startTime) * timeDirection; + this.light = light; - if (timeRunning < 0 || timeDirection === 0) { - return; // yet to come / don't decide when delta = 0 - } // start + this.matrix = light.matrixWorld; + this.matrixAutoUpdate = false; + this.color = color; - this._startTime = null; // unschedule + this.type = 'DirectionalLightHelper'; - deltaTime = timeDirection * timeRunning; - } // apply time scale and advance time + 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 ) ); - deltaTime *= this._updateTimeScale(time); + const material = new LineBasicMaterial( { fog: false, toneMapped: false } ); - const clipTime = this._updateTime(deltaTime); // note: _updateTime may disable the action resulting in - // an effective weight of 0 + this.lightPlane = new Line( geometry, material ); + this.add( this.lightPlane ); + geometry = new BufferGeometry(); + geometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) ); - const weight = this._updateWeight(time); + this.targetLine = new Line( geometry, material ); + this.add( this.targetLine ); - if (weight > 0) { - const interpolants = this._interpolants; - const propertyMixers = this._propertyBindings; + this.update(); - switch (this.blendMode) { - case AdditiveAnimationBlendMode: - for (let j = 0, m = interpolants.length; j !== m; ++j) { - interpolants[j].evaluate(clipTime); - propertyMixers[j].accumulateAdditive(weight); - } + } - break; + dispose() { - case NormalAnimationBlendMode: - default: - for (let j = 0, m = interpolants.length; j !== m; ++j) { - interpolants[j].evaluate(clipTime); - propertyMixers[j].accumulate(accuIndex, weight); - } + this.lightPlane.geometry.dispose(); + this.lightPlane.material.dispose(); + this.targetLine.geometry.dispose(); + this.targetLine.material.dispose(); - } - } } - _updateWeight(time) { - let weight = 0; + update() { - if (this.enabled) { - weight = this.weight; - const interpolant = this._weightInterpolant; + this.light.updateWorldMatrix( true, false ); + this.light.target.updateWorldMatrix( true, false ); - if (interpolant !== null) { - const interpolantValue = interpolant.evaluate(time)[0]; - weight *= interpolantValue; + _v1.setFromMatrixPosition( this.light.matrixWorld ); + _v2.setFromMatrixPosition( this.light.target.matrixWorld ); + _v3.subVectors( _v2, _v1 ); - if (time > interpolant.parameterPositions[1]) { - this.stopFading(); + this.lightPlane.lookAt( _v2 ); + + if ( this.color !== undefined ) { + + this.lightPlane.material.color.set( this.color ); + this.targetLine.material.color.set( this.color ); + + } else { + + this.lightPlane.material.color.copy( this.light.color ); + this.targetLine.material.color.copy( this.light.color ); - if (interpolantValue === 0) { - // faded out, disable - this.enabled = false; - } - } - } } - this._effectiveWeight = weight; - return weight; + this.targetLine.lookAt( _v2 ); + this.targetLine.scale.z = _v3.length(); + } - _updateTimeScale(time) { - let timeScale = 0; +} - if (!this.paused) { - timeScale = this.timeScale; - const interpolant = this._timeScaleInterpolant; +const _vector = /*@__PURE__*/ new Vector3(); +const _camera = /*@__PURE__*/ new Camera(); - if (interpolant !== null) { - const interpolantValue = interpolant.evaluate(time)[0]; - timeScale *= interpolantValue; +/** + * - shows frustum, line of sight and up of the camera + * - suitable for fast updates + * - based on frustum visualization in lightgl.js shadowmap example + * https://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html + */ - if (time > interpolant.parameterPositions[1]) { - this.stopWarping(); +class CameraHelper extends LineSegments { - if (timeScale === 0) { - // motion has halted, pause - this.paused = true; - } else { - // warp done - apply final time scale - this.timeScale = timeScale; - } - } - } - } + constructor( camera ) { - this._effectiveTimeScale = timeScale; - return timeScale; - } + const geometry = new BufferGeometry(); + const material = new LineBasicMaterial( { color: 0xffffff, vertexColors: true, toneMapped: false } ); - _updateTime(deltaTime) { - const duration = this._clip.duration; - const loop = this.loop; - let time = this.time + deltaTime; - let loopCount = this._loopCount; - const pingPong = loop === LoopPingPong; + const vertices = []; + const colors = []; - if (deltaTime === 0) { - if (loopCount === -1) return time; - return pingPong && (loopCount & 1) === 1 ? duration - time : time; - } + const pointMap = {}; - if (loop === LoopOnce) { - if (loopCount === -1) { - // just started - this._loopCount = 0; + // near - this._setEndings(true, true, false); - } + addLine( 'n1', 'n2' ); + addLine( 'n2', 'n4' ); + addLine( 'n4', 'n3' ); + addLine( 'n3', 'n1' ); - handle_stop: { - if (time >= duration) { - time = duration; - } else if (time < 0) { - time = 0; - } else { - this.time = time; - break handle_stop; - } + // far - if (this.clampWhenFinished) this.paused = true;else this.enabled = false; - this.time = time; + addLine( 'f1', 'f2' ); + addLine( 'f2', 'f4' ); + addLine( 'f4', 'f3' ); + addLine( 'f3', 'f1' ); - this._mixer.dispatchEvent({ - type: 'finished', - action: this, - direction: deltaTime < 0 ? -1 : 1 - }); - } - } else { - // repetitive Repeat or PingPong - if (loopCount === -1) { - // just started - if (deltaTime >= 0) { - loopCount = 0; + // sides - 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); - } - } + addLine( 'n1', 'f1' ); + addLine( 'n2', 'f2' ); + addLine( 'n3', 'f3' ); + addLine( 'n4', 'f4' ); + + // cone + + addLine( 'p', 'n1' ); + addLine( 'p', 'n2' ); + addLine( 'p', 'n3' ); + addLine( 'p', 'n4' ); + + // up - if (time >= duration || time < 0) { - // wrap around - const loopDelta = Math.floor(time / duration); // signed + addLine( 'u1', 'u2' ); + addLine( 'u2', 'u3' ); + addLine( 'u3', 'u1' ); - time -= duration * loopDelta; - loopCount += Math.abs(loopDelta); - const pending = this.repetitions - loopCount; + // target - 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; + addLine( 'c', 't' ); + addLine( 'p', 'c' ); - this._mixer.dispatchEvent({ - type: 'finished', - action: this, - direction: deltaTime > 0 ? 1 : -1 - }); - } else { - // keep running - if (pending === 1) { - // entering the last round - const atStart = deltaTime < 0; + // cross - this._setEndings(atStart, !atStart, pingPong); - } else { - this._setEndings(false, false, pingPong); - } + addLine( 'cn1', 'cn2' ); + addLine( 'cn3', 'cn4' ); - this._loopCount = loopCount; - this.time = time; + addLine( 'cf1', 'cf2' ); + addLine( 'cf3', 'cf4' ); - this._mixer.dispatchEvent({ - type: 'loop', - action: this, - loopDelta: loopDelta - }); - } - } else { - this.time = time; - } + function addLine( a, b ) { + + addPoint( a ); + addPoint( b ); - if (pingPong && (loopCount & 1) === 1) { - // invert time for the "pong round" - return duration - time; - } } - return time; - } + function addPoint( id ) { - _setEndings(atStart, atEnd, pingPong) { - const settings = this._interpolantSettings; + vertices.push( 0, 0, 0 ); + colors.push( 0, 0, 0 ); - 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 ( pointMap[ id ] === undefined ) { + + pointMap[ id ] = []; - if (atEnd) { - settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; - } else { - settings.endingEnd = WrapAroundEnding; } - } - } - _scheduleFading(duration, weightNow, weightThen) { - const mixer = this._mixer, - now = mixer.time; - let interpolant = this._weightInterpolant; + pointMap[ id ].push( ( vertices.length / 3 ) - 1 ); - if (interpolant === null) { - interpolant = mixer._lendControlInterpolant(); - this._weightInterpolant = interpolant; } - const times = interpolant.parameterPositions, - values = interpolant.sampleValues; - times[0] = now; - values[0] = weightNow; - times[1] = now + duration; - values[1] = weightThen; - return this; - } + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); -} + super( geometry, material ); -const _controlInterpolantsResultBuffer = /*@__PURE__*/new Float32Array(1); + this.type = 'CameraHelper'; -class AnimationMixer extends EventDispatcher { - constructor(root) { - super(); - this._root = root; + this.camera = camera; + if ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix(); - this._initMemoryManager(); + this.matrix = camera.matrixWorld; + this.matrixAutoUpdate = false; + + this.pointMap = pointMap; + + this.update(); + + // colors + + const colorFrustum = new Color( 0xffaa00 ); + const colorCone = new Color( 0xff0000 ); + const colorUp = new Color( 0x00aaff ); + const colorTarget = new Color( 0xffffff ); + const colorCross = new Color( 0x333333 ); + + this.setColors( colorFrustum, colorCone, colorUp, colorTarget, colorCross ); - 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; - let bindingsByName = bindingsByRoot[rootUuid]; - - if (bindingsByName === undefined) { - bindingsByName = {}; - bindingsByRoot[rootUuid] = bindingsByName; - } + setColors( frustum, cone, up, target, cross ) { - for (let i = 0; i !== nTracks; ++i) { - const track = tracks[i], - trackName = track.name; - let binding = bindingsByName[trackName]; + const geometry = this.geometry; - if (binding !== undefined) { - ++binding.referenceCount; - bindings[i] = binding; - } else { - binding = bindings[i]; + const colorAttribute = geometry.getAttribute( 'color' ); - if (binding !== undefined) { - // existing binding, make sure the cache knows - if (binding._cacheIndex === null) { - ++binding.referenceCount; + // near - this._addInactiveBinding(binding, rootUuid, trackName); - } + 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 - continue; - } + // far - const path = prototypeAction && prototypeAction._propertyBindings[i].binding.parsedPath; - binding = new PropertyMixer(PropertyBinding.create(root, trackName, path), track.ValueTypeName, track.getValueSize()); - ++binding.referenceCount; + 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 - this._addInactiveBinding(binding, rootUuid, trackName); + // sides - bindings[i] = binding; - } + 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 - interpolants[i].resultBuffer = binding.buffer; - } - } + // cone - _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]; + 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 - this._bindAction(action, actionsForClip && actionsForClip.knownActions[0]); + // up - this._addInactiveAction(action, clipUuid, rootUuid); - } + 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 - const bindings = action._propertyBindings; // increment reference counts / sort out state + // target - for (let i = 0, n = bindings.length; i !== n; ++i) { - const binding = bindings[i]; + 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 - if (binding.useCount++ === 0) { - this._lendBinding(binding); + // cross - binding.saveOriginalState(); - } - } + 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 - this._lendAction(action); - } - } + 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 - _deactivateAction(action) { - if (this._isActiveAction(action)) { - const bindings = action._propertyBindings; // decrement reference counts / sort out state + colorAttribute.needsUpdate = true; - for (let i = 0, n = bindings.length; i !== n; ++i) { - const binding = bindings[i]; + } - if (--binding.useCount === 0) { - binding.restoreOriginalState(); + update() { - this._takeBackBinding(binding); - } - } + const geometry = this.geometry; + const pointMap = this.pointMap; - this._takeBackAction(action); - } - } // Memory manager + const w = 1, h = 1; + // we need just camera projection matrix inverse + // world matrix must be identity - _initMemoryManager() { - this._actions = []; // 'nActiveActions' followed by inactive ones + _camera.projectionMatrixInverse.copy( this.camera.projectionMatrixInverse ); - this._nActiveActions = 0; - this._actionsByClip = {}; // inside: - // { - // knownActions: Array< AnimationAction > - used as prototypes - // actionByRoot: AnimationAction - lookup - // } + // center / target - this._bindings = []; // 'nActiveBindings' followed by inactive ones + setPoint( 'c', pointMap, geometry, _camera, 0, 0, - 1 ); + setPoint( 't', pointMap, geometry, _camera, 0, 0, 1 ); - this._nActiveBindings = 0; - this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer > + // near - this._controlInterpolants = []; // same game as above + 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 ); - this._nActiveControlInterpolants = 0; - const scope = this; - this.stats = { - actions: { - get total() { - return scope._actions.length; - }, + // far - get inUse() { - return scope._nActiveActions; - } + 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 ); - }, - bindings: { - get total() { - return scope._bindings.length; - }, + // up - get inUse() { - return scope._nActiveBindings; - } + 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 ); - }, - controlInterpolants: { - get total() { - return scope._controlInterpolants.length; - }, + // cross - get inUse() { - return scope._nActiveControlInterpolants; - } + setPoint( 'cf1', pointMap, geometry, _camera, - w, 0, 1 ); + setPoint( 'cf2', pointMap, geometry, _camera, w, 0, 1 ); + setPoint( 'cf3', pointMap, geometry, _camera, 0, - h, 1 ); + setPoint( 'cf4', pointMap, geometry, _camera, 0, h, 1 ); - } - }; - } // Memory management for AnimationAction objects + setPoint( 'cn1', pointMap, geometry, _camera, - w, 0, - 1 ); + setPoint( 'cn2', pointMap, geometry, _camera, w, 0, - 1 ); + setPoint( 'cn3', pointMap, geometry, _camera, 0, - h, - 1 ); + setPoint( 'cn4', pointMap, geometry, _camera, 0, h, - 1 ); + geometry.getAttribute( 'position' ).needsUpdate = true; - _isActiveAction(action) { - const index = action._cacheIndex; - return index !== null && index < this._nActiveActions; } - _addInactiveAction(action, clipUuid, rootUuid) { - const actions = this._actions, - actionsByClip = this._actionsByClip; - let actionsForClip = actionsByClip[clipUuid]; + dispose() { - if (actionsForClip === undefined) { - actionsForClip = { - knownActions: [action], - actionByRoot: {} - }; - action._byClipCacheIndex = 0; - actionsByClip[clipUuid] = actionsForClip; - } else { - const knownActions = actionsForClip.knownActions; - action._byClipCacheIndex = knownActions.length; - knownActions.push(action); - } + this.geometry.dispose(); + this.material.dispose(); - 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._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; - lastKnownAction._byClipCacheIndex = byClipCacheIndex; - knownActionsForClip[byClipCacheIndex] = lastKnownAction; - knownActionsForClip.pop(); - action._byClipCacheIndex = null; - const actionByRoot = actionsForClip.actionByRoot, - rootUuid = (action._localRoot || this._root).uuid; - delete actionByRoot[rootUuid]; +} - if (knownActionsForClip.length === 0) { - delete actionsByClip[clipUuid]; - } - this._removeInactiveBindingsForAction(action); - } +function setPoint( point, pointMap, geometry, camera, x, y, z ) { - _removeInactiveBindingsForAction(action) { - const bindings = action._propertyBindings; + _vector.set( x, y, z ).unproject( camera ); - for (let i = 0, n = bindings.length; i !== n; ++i) { - const binding = bindings[i]; + 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 ); - 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]; - action._cacheIndex = lastActiveIndex; - actions[lastActiveIndex] = action; - firstInactiveAction._cacheIndex = prevIndex; - actions[prevIndex] = firstInactiveAction; +} + +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 ] ); + const positions = new Float32Array( 8 * 3 ); + + const geometry = new BufferGeometry(); + geometry.setIndex( new BufferAttribute( indices, 1 ) ); + geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) ); + + super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); + + this.object = object; + this.type = 'BoxHelper'; + + this.matrixAutoUpdate = false; + + this.update(); + } - _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]; - action._cacheIndex = firstInactiveIndex; - actions[firstInactiveIndex] = action; - lastActiveAction._cacheIndex = prevIndex; - actions[prevIndex] = lastActiveAction; - } // Memory management for PropertyMixer objects + update( object ) { + if ( object !== undefined ) { - _addInactiveBinding(binding, rootUuid, trackName) { - const bindingsByRoot = this._bindingsByRootAndName, - bindings = this._bindings; - let bindingByName = bindingsByRoot[rootUuid]; + console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' ); - if (bindingByName === undefined) { - bindingByName = {}; - bindingsByRoot[rootUuid] = bindingByName; } - bindingByName[trackName] = binding; - binding._cacheIndex = bindings.length; - bindings.push(binding); - } + if ( this.object !== undefined ) { - _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; - lastInactiveBinding._cacheIndex = cacheIndex; - bindings[cacheIndex] = lastInactiveBinding; - bindings.pop(); - delete bindingByName[trackName]; + _box.setFromObject( this.object ); - if (Object.keys(bindingByName).length === 0) { - delete bindingsByRoot[rootUuid]; } - } - _lendBinding(binding) { - const bindings = this._bindings, - prevIndex = binding._cacheIndex, - lastActiveIndex = this._nActiveBindings++, - firstInactiveBinding = bindings[lastActiveIndex]; - binding._cacheIndex = lastActiveIndex; - bindings[lastActiveIndex] = binding; - firstInactiveBinding._cacheIndex = prevIndex; - bindings[prevIndex] = firstInactiveBinding; - } + if ( _box.isEmpty() ) return; - _takeBackBinding(binding) { - const bindings = this._bindings, - prevIndex = binding._cacheIndex, - firstInactiveIndex = --this._nActiveBindings, - lastActiveBinding = bindings[firstInactiveIndex]; - binding._cacheIndex = firstInactiveIndex; - bindings[firstInactiveIndex] = binding; - lastActiveBinding._cacheIndex = prevIndex; - bindings[prevIndex] = lastActiveBinding; - } // Memory management of Interpolants for weight and time scale + const min = _box.min; + const max = _box.max; + /* + 5____4 + 1/___0/| + | 6__|_7 + 2/___3/ - _lendControlInterpolant() { - const interpolants = this._controlInterpolants, - lastActiveIndex = this._nActiveControlInterpolants++; - let interpolant = interpolants[lastActiveIndex]; + 0: max.x, max.y, max.z + 1: min.x, max.y, max.z + 2: min.x, min.y, max.z + 3: max.x, min.y, max.z + 4: max.x, max.y, min.z + 5: min.x, max.y, min.z + 6: min.x, min.y, min.z + 7: max.x, min.y, min.z + */ - if (interpolant === undefined) { - interpolant = new LinearInterpolant(new Float32Array(2), new Float32Array(2), 1, _controlInterpolantsResultBuffer); - interpolant.__cacheIndex = lastActiveIndex; - interpolants[lastActiveIndex] = interpolant; - } + const position = this.geometry.attributes.position; + const array = position.array; + + array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z; + array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z; + array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z; + array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z; + array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z; + array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z; + array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z; + array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z; + + position.needsUpdate = true; + + this.geometry.computeBoundingSphere(); - return interpolant; } - _takeBackControlInterpolant(interpolant) { - const interpolants = this._controlInterpolants, - 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 - // object (this method allocates a lot of dynamic memory in case a - // previously unknown clip/root combination is specified) + setFromObject( object ) { + this.object = object; + this.update(); - clipAction(clip, optionalRoot, blendMode) { - const root = optionalRoot || this._root, - 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; + return this; - if (blendMode === undefined) { - if (clipObject !== null) { - blendMode = clipObject.blendMode; - } else { - blendMode = NormalAnimationBlendMode; - } - } + } - if (actionsForClip !== undefined) { - const existingAction = actionsForClip.actionByRoot[rootUuid]; + copy( source, recursive ) { - 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 + super.copy( source, recursive ); + + this.object = source.object; + return this; + + } - prototypeAction = actionsForClip.knownActions[0]; // also, take the clip from the prototype action + dispose() { - if (clipObject === null) clipObject = prototypeAction._clip; - } // clip must be known when specified via string + this.geometry.dispose(); + this.material.dispose(); + } - if (clipObject === null) return null; // allocate all resources required to run it +} - const newAction = new AnimationAction(this, clipObject, optionalRoot, blendMode); +class Box3Helper extends LineSegments { - this._bindAction(newAction, prototypeAction); // and make the action known to the memory manager + constructor( box, 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 ] ); - this._addInactiveAction(newAction, clipUuid, rootUuid); + const positions = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 1, - 1, 1, - 1, - 1 ]; - return newAction; - } // get an existing action + const geometry = new BufferGeometry(); + geometry.setIndex( new BufferAttribute( indices, 1 ) ); - 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]; + geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); - if (actionsForClip !== undefined) { - return actionsForClip.actionByRoot[rootUuid] || null; - } + super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); - return null; - } // deactivates all previously scheduled actions + this.box = box; + this.type = 'Box3Helper'; - stopAllAction() { - const actions = this._actions, - nActions = this._nActiveActions; + this.geometry.computeBoundingSphere(); - for (let i = nActions - 1; i >= 0; --i) { - actions[i].stop(); - } + } - return this; - } // advance the time and update apply the animation + updateMatrixWorld( force ) { + const box = this.box; - 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 + if ( box.isEmpty() ) return; - for (let i = 0; i !== nActions; ++i) { - const action = actions[i]; + box.getCenter( this.position ); - action._update(time, deltaTime, timeDirection, accuIndex); - } // update scene graph + box.getSize( this.scale ); + this.scale.multiplyScalar( 0.5 ); - const bindings = this._bindings, - nBindings = this._nActiveBindings; + super.updateMatrixWorld( force ); - for (let i = 0; i !== nBindings; ++i) { - bindings[i].apply(accuIndex); - } + } - return this; - } // Allows you to seek to a specific time in an animation. + dispose() { + this.geometry.dispose(); + this.material.dispose(); - 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 +class PlaneHelper extends Line { + constructor( plane, size = 1, hex = 0xffff00 ) { - getRoot() { - return this._root; - } // free all resources specific to a particular clip + const color = hex; + const positions = [ 1, - 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, - 1, 0, 1, 1, 0 ]; - uncacheClip(clip) { - const actions = this._actions, - clipUuid = clip.uuid, - actionsByClip = this._actionsByClip, - actionsForClip = actionsByClip[clipUuid]; + const geometry = new BufferGeometry(); + geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + geometry.computeBoundingSphere(); - 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; + super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); - for (let i = 0, n = actionsToRemove.length; i !== n; ++i) { - const action = actionsToRemove[i]; + this.type = 'PlaneHelper'; - this._deactivateAction(action); + this.plane = plane; - const cacheIndex = action._cacheIndex, - lastInactiveAction = actions[actions.length - 1]; - action._cacheIndex = null; - action._byClipCacheIndex = null; - lastInactiveAction._cacheIndex = cacheIndex; - actions[cacheIndex] = lastInactiveAction; - actions.pop(); + this.size = size; - this._removeInactiveBindingsForAction(action); - } + const positions2 = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ]; - delete actionsByClip[clipUuid]; - } - } // free all resources specific to a particular root target object + const geometry2 = new BufferGeometry(); + geometry2.setAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); + geometry2.computeBoundingSphere(); + this.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false, toneMapped: false } ) ) ); - uncacheRoot(root) { - const rootUuid = root.uuid, - actionsByClip = this._actionsByClip; + } - for (const clipUuid in actionsByClip) { - const actionByRoot = actionsByClip[clipUuid].actionByRoot, - action = actionByRoot[rootUuid]; + updateMatrixWorld( force ) { - if (action !== undefined) { - this._deactivateAction(action); + this.position.set( 0, 0, 0 ); - this._removeInactiveAction(action); - } - } + this.scale.set( 0.5 * this.size, 0.5 * this.size, 1 ); - const bindingsByRoot = this._bindingsByRootAndName, - bindingByName = bindingsByRoot[rootUuid]; + this.lookAt( this.plane.normal ); - if (bindingByName !== undefined) { - for (const trackName in bindingByName) { - const binding = bindingByName[trackName]; - binding.restoreOriginalState(); + this.translateZ( - this.plane.constant ); - this._removeInactiveBinding(binding); - } - } - } // remove a targeted clip from the cache + super.updateMatrixWorld( force ); + } - uncacheAction(clip, optionalRoot) { - const action = this.existingAction(clip, optionalRoot); + dispose() { - if (action !== null) { - this._deactivateAction(action); + this.geometry.dispose(); + this.material.dispose(); + this.children[ 0 ].geometry.dispose(); + this.children[ 0 ].material.dispose(); - this._removeInactiveAction(action); - } } } -class Uniform { - constructor(value) { - if (typeof value === 'string') { - console.warn('THREE.Uniform: Type parameter is no longer needed.'); - value = arguments[1]; - } +const _axis = /*@__PURE__*/ new Vector3(); +let _lineGeometry, _coneGeometry; - this.value = value; - } +class ArrowHelper extends Object3D { - clone() { - return new Uniform(this.value.clone === undefined ? this.value : this.value.clone()); - } + // 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 ) { -class InstancedInterleavedBuffer extends InterleavedBuffer { - constructor(array, stride, meshPerAttribute = 1) { - super(array, stride); - this.isInstancedInterleavedBuffer = true; - this.meshPerAttribute = meshPerAttribute; - } + super(); - copy(source) { - super.copy(source); - this.meshPerAttribute = source.meshPerAttribute; - return this; - } + this.type = 'ArrowHelper'; - clone(data) { - const ib = super.clone(data); - ib.meshPerAttribute = this.meshPerAttribute; - return ib; - } + if ( _lineGeometry === undefined ) { - toJSON(data) { - const json = super.toJSON(data); - json.isInstancedInterleavedBuffer = true; - json.meshPerAttribute = this.meshPerAttribute; - return json; - } + _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 ); -class GLBufferAttribute { - constructor(buffer, type, itemSize, elementSize, count) { - this.isGLBufferAttribute = true; - this.buffer = buffer; - this.type = type; - this.itemSize = itemSize; - this.elementSize = elementSize; - this.count = count; - this.version = 0; - } + } - set needsUpdate(value) { - if (value === true) this.version++; - } + this.position.copy( origin ); - setBuffer(buffer) { - this.buffer = buffer; - return this; - } + this.line = new Line( _lineGeometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); + this.line.matrixAutoUpdate = false; + this.add( this.line ); - setType(type, elementSize) { - this.type = type; - this.elementSize = elementSize; - return this; - } + this.cone = new Mesh( _coneGeometry, new MeshBasicMaterial( { color: color, toneMapped: false } ) ); + this.cone.matrixAutoUpdate = false; + this.add( this.cone ); - setItemSize(itemSize) { - this.itemSize = itemSize; - return this; - } + this.setDirection( dir ); + this.setLength( length, headLength, headWidth ); - setCount(count) { - this.count = count; - return this; } -} + setDirection( dir ) { -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) + // dir is assumed to be normalized - this.near = near; - this.far = far; - this.camera = null; - this.layers = new Layers(); - this.params = { - Mesh: {}, - Line: { - threshold: 1 - }, - LOD: {}, - Points: { - threshold: 1 - }, - Sprite: {} - }; - } + if ( dir.y > 0.99999 ) { - set(origin, direction) { - // direction is assumed to be normalized (for accurate distance calculations) - this.ray.set(origin, direction); - } + this.quaternion.set( 0, 0, 0, 1 ); - setFromCamera(coords, camera) { - if (camera.isPerspectiveCamera) { - this.ray.origin.setFromMatrixPosition(camera.matrixWorld); - this.ray.direction.set(coords.x, coords.y, 0.5).unproject(camera).sub(this.ray.origin).normalize(); - this.camera = camera; - } else if (camera.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 + } else if ( dir.y < - 0.99999 ) { + + this.quaternion.set( 1, 0, 0, 0 ); - 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; - } + _axis.set( dir.z, 0, - dir.x ).normalize(); + + const radians = Math.acos( dir.y ); + + this.quaternion.setFromAxisAngle( _axis, radians ); - 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; -} + setLength( length, headLength = length * 0.2, headWidth = headLength * 0.2 ) { -function intersectObject(object, raycaster, intersects, recursive) { - if (object.layers.test(raycaster.layers)) { - object.raycast(raycaster, intersects); - } + this.line.scale.set( 1, Math.max( 0.0001, length - headLength ), 1 ); // see #17458 + this.line.updateMatrix(); - if (recursive === true) { - const children = object.children; + this.cone.scale.set( headWidth, headLength, headWidth ); + this.cone.position.y = length; + this.cone.updateMatrix(); - for (let i = 0, l = children.length; i < l; i++) { - intersectObject(children[i], raycaster, intersects, true); - } } -} - -/** - * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system - * - * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up. - * The azimuthal angle (theta) is measured from the positive z-axis. - */ -class Spherical { - constructor(radius = 1, phi = 0, theta = 0) { - this.radius = radius; - this.phi = phi; // polar angle + setColor( color ) { - this.theta = theta; // azimuthal angle + this.line.material.color.set( color ); + this.cone.material.color.set( color ); - return this; } - set(radius, phi, theta) { - this.radius = radius; - this.phi = phi; - this.theta = theta; - return this; - } + copy( source ) { - 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 + super.copy( source, false ); + this.line.copy( source.line ); + this.cone.copy( source.cone ); - 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; - } else { - this.theta = Math.atan2(x, z); - this.phi = Math.acos(clamp(y / this.radius, -1, 1)); - } + dispose() { - return this; - } + this.line.geometry.dispose(); + this.line.material.dispose(); + this.cone.geometry.dispose(); + this.cone.material.dispose(); - 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 +class AxesHelper extends LineSegments { - this.theta = theta; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis + constructor( size = 1 ) { - this.y = y; // height above the x-z plane + const vertices = [ + 0, 0, 0, size, 0, 0, + 0, 0, 0, 0, size, 0, + 0, 0, 0, 0, 0, size + ]; - return this; - } + const colors = [ + 1, 0, 0, 1, 0.6, 0, + 0, 1, 0, 0.6, 1, 0, + 0, 0, 1, 0, 0.6, 1 + ]; - set(radius, theta, y) { - this.radius = radius; - this.theta = theta; - this.y = y; - return this; - } + const geometry = new BufferGeometry(); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - copy(other) { - this.radius = other.radius; - this.theta = other.theta; - this.y = other.y; - return this; - } + const material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } ); - setFromVector3(v) { - return this.setFromCartesianCoords(v.x, v.y, v.z); - } + super( geometry, material ); - setFromCartesianCoords(x, y, z) { - this.radius = Math.sqrt(x * x + z * z); - this.theta = Math.atan2(x, z); - this.y = y; - return this; - } + this.type = 'AxesHelper'; - clone() { - return new this.constructor().copy(this); } -} + setColors( xAxisColor, yAxisColor, zAxisColor ) { + + const color = new Color(); + const array = this.geometry.attributes.color.array; -const _vector$4 = /*@__PURE__*/new Vector2(); + color.set( xAxisColor ); + color.toArray( array, 0 ); + color.toArray( array, 3 ); -class Box2 { - constructor(min = new Vector2(+Infinity, +Infinity), max = new Vector2(-Infinity, -Infinity)) { - this.isBox2 = true; - this.min = min; - this.max = max; - } + color.set( yAxisColor ); + color.toArray( array, 6 ); + color.toArray( array, 9 ); + + color.set( zAxisColor ); + color.toArray( array, 12 ); + color.toArray( array, 15 ); + + this.geometry.attributes.color.needsUpdate = true; - set(min, max) { - this.min.copy(min); - this.max.copy(max); return this; + } - setFromPoints(points) { - this.makeEmpty(); + dispose() { - for (let i = 0, il = points.length; i < il; i++) { - this.expandByPoint(points[i]); - } + this.geometry.dispose(); + this.material.dispose(); - 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; - } +class ShapePath { - clone() { - return new this.constructor().copy(this); - } + constructor() { - copy(box) { - this.min.copy(box.min); - this.max.copy(box.max); - return this; - } + this.type = 'ShapePath'; - makeEmpty() { - this.min.x = this.min.y = +Infinity; - this.max.x = this.max.y = -Infinity; - return this; - } + this.color = new Color(); + + this.subPaths = []; + this.currentPath = null; - 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); - } + moveTo( x, y ) { - getSize(target) { - return this.isEmpty() ? target.set(0, 0) : target.subVectors(this.max, this.min); - } + this.currentPath = new Path(); + this.subPaths.push( this.currentPath ); + this.currentPath.moveTo( x, y ); - 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); + lineTo( x, y ) { + + this.currentPath.lineTo( x, y ); + 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; - } + quadraticCurveTo( aCPx, aCPy, aX, aY ) { - 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)); - } + this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY ); - 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; - } + return this; - 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); + bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { - return clampedPoint.sub(point).length(); - } + this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ); - 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); + splineThru( pts ) { + + this.currentPath.splineThru( pts ); + return this; - } - equals(box) { - return box.min.equals(this.min) && box.max.equals(this.max); } -} - -const _startP = /*@__PURE__*/new Vector3(); + toShapes( isCCW ) { -const _startEnd = /*@__PURE__*/new Vector3(); + function toShapesNoHoles( inSubpaths ) { -class Line3 { - constructor(start = new Vector3(), end = new Vector3()) { - this.start = start; - this.end = end; - } + const shapes = []; - set(start, end) { - this.start.copy(start); - this.end.copy(end); - return this; - } + for ( let i = 0, l = inSubpaths.length; i < l; i ++ ) { - copy(line) { - this.start.copy(line.start); - this.end.copy(line.end); - return this; - } + const tmpPath = inSubpaths[ i ]; - getCenter(target) { - return target.addVectors(this.start, this.end).multiplyScalar(0.5); - } + const tmpShape = new Shape(); + tmpShape.curves = tmpPath.curves; - delta(target) { - return target.subVectors(this.end, this.start); - } + shapes.push( tmpShape ); - distanceSq() { - return this.start.distanceToSquared(this.end); - } + } - distance() { - return this.start.distanceTo(this.end); - } + return shapes; - at(t, target) { - return this.delta(target).multiplyScalar(t).add(this.start); - } + } - closestPointToPointParameter(point, clampToLine) { - _startP.subVectors(point, this.start); + function isPointInsidePolygon( inPt, inPolygon ) { - _startEnd.subVectors(this.end, this.start); + const polyLen = inPolygon.length; - const startEnd2 = _startEnd.dot(_startEnd); + // 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 ++ ) { - const startEnd_startP = _startEnd.dot(_startP); + let edgeLowPt = inPolygon[ p ]; + let edgeHighPt = inPolygon[ q ]; - let t = startEnd_startP / startEnd2; + let edgeDx = edgeHighPt.x - edgeLowPt.x; + let edgeDy = edgeHighPt.y - edgeLowPt.y; - if (clampToLine) { - t = clamp(t, 0, 1); - } + if ( Math.abs( edgeDy ) > Number.EPSILON ) { - return t; - } + // not parallel + if ( edgeDy < 0 ) { - closestPointToPoint(point, clampToLine, target) { - const t = this.closestPointToPointParameter(point, clampToLine); - return this.delta(target).multiplyScalar(t).add(this.start); - } + edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx; + edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy; - 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); - } + if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue; - clone() { - return new this.constructor().copy(this); - } + if ( inPt.y === edgeLowPt.y ) { -} + if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ? + // continue; // no intersection or edgeLowPt => doesn't count !!! -const _vector$3 = /*@__PURE__*/new Vector3(); + } else { -class SpotLightHelper extends Object3D { - constructor(light, color) { - super(); - this.light = light; - this.light.updateMatrixWorld(); - this.matrix = light.matrixWorld; - this.matrixAutoUpdate = false; - this.color = color; - 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]; + 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 - 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, - toneMapped: false - }); - this.cone = new LineSegments(geometry, material); - this.add(this.cone); - this.update(); - } + } else { - dispose() { - this.cone.geometry.dispose(); - this.cone.material.dispose(); - } + // 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; - update() { - this.light.updateMatrixWorld(); - 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); + return inside; - 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 isClockWise = ShapeUtils.isClockWise; -const _boneMatrix = /*@__PURE__*/new Matrix4(); + const subPaths = this.subPaths; + if ( subPaths.length === 0 ) return []; -const _matrixWorldInv = /*@__PURE__*/new Matrix4(); + let solid, tmpPath, tmpShape; + const shapes = []; -class SkeletonHelper extends LineSegments { - constructor(object) { - const bones = getBoneList(object); - const geometry = new BufferGeometry(); - const vertices = []; - const colors = []; - const color1 = new Color(0, 0, 1); - const color2 = new Color(0, 1, 0); + if ( subPaths.length === 1 ) { - for (let i = 0; i < bones.length; i++) { - const bone = bones[i]; + tmpPath = subPaths[ 0 ]; + tmpShape = new Shape(); + tmpShape.curves = tmpPath.curves; + shapes.push( tmpShape ); + return shapes; - if (bone.parent && bone.parent.isBone) { - vertices.push(0, 0, 0); - vertices.push(0, 0, 0); - colors.push(color1.r, color1.g, color1.b); - colors.push(color2.r, color2.g, color2.b); - } } - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); - const material = new LineBasicMaterial({ - vertexColors: true, - depthTest: false, - depthWrite: false, - toneMapped: false, - transparent: true - }); - super(geometry, material); - this.isSkeletonHelper = true; - this.type = 'SkeletonHelper'; - this.root = object; - this.bones = bones; - this.matrix = object.matrixWorld; - this.matrixAutoUpdate = false; - } - - updateMatrixWorld(force) { - const bones = this.bones; - const geometry = this.geometry; - const position = geometry.getAttribute('position'); + let holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() ); + holesFirst = isCCW ? ! holesFirst : holesFirst; - _matrixWorldInv.copy(this.root.matrixWorld).invert(); + // console.log("Holes first", holesFirst); - for (let i = 0, j = 0; i < bones.length; i++) { - const bone = bones[i]; + const betterShapeHoles = []; + const newShapes = []; + let newShapeHoles = []; + let mainIdx = 0; + let tmpPoints; - if (bone.parent && bone.parent.isBone) { - _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.matrixWorld); + newShapes[ mainIdx ] = undefined; + newShapeHoles[ mainIdx ] = []; - _vector$2.setFromMatrixPosition(_boneMatrix); + for ( let i = 0, l = subPaths.length; i < l; i ++ ) { - position.setXYZ(j, _vector$2.x, _vector$2.y, _vector$2.z); + tmpPath = subPaths[ i ]; + tmpPoints = tmpPath.getPoints(); + solid = isClockWise( tmpPoints ); + solid = isCCW ? ! solid : solid; - _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.parent.matrixWorld); + if ( solid ) { - _vector$2.setFromMatrixPosition(_boneMatrix); + if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++; - position.setXYZ(j + 1, _vector$2.x, _vector$2.y, _vector$2.z); - j += 2; - } - } + newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints }; + newShapes[ mainIdx ].s.curves = tmpPath.curves; - geometry.getAttribute('position').needsUpdate = true; - super.updateMatrixWorld(force); - } + if ( holesFirst ) mainIdx ++; + newShapeHoles[ mainIdx ] = []; -} + //console.log('cw', i); -function getBoneList(object) { - const boneList = []; + } else { - if (object.isBone === true) { - boneList.push(object); - } + newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } ); - for (let i = 0; i < object.children.length; i++) { - boneList.push.apply(boneList, getBoneList(object.children[i])); - } + //console.log('ccw', i); - return boneList; -} + } -class PointLightHelper extends Mesh { - constructor(light, sphereSize, color) { - const geometry = new SphereGeometry(sphereSize, 4, 2); - const material = new MeshBasicMaterial({ - wireframe: true, - fog: false, - toneMapped: false - }); - 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 ); - const distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } ); - this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial ); - this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial ); - const d = light.distance; - if ( d === 0.0 ) { - this.lightDistance.visible = false; - } else { - this.lightDistance.scale.set( d, d, d ); } - this.add( this.lightDistance ); - */ - } - dispose() { - this.geometry.dispose(); - this.material.dispose(); - } + // only Holes? -> probably all Shapes with wrong orientation + if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths ); - update() { - if (this.color !== undefined) { - this.material.color.set(this.color); - } else { - this.material.color.copy(this.light.color); - } - /* - const d = this.light.distance; - if ( d === 0.0 ) { - this.lightDistance.visible = false; - } else { - this.lightDistance.visible = true; - this.lightDistance.scale.set( d, d, d ); - } - */ - } + if ( newShapes.length > 1 ) { -} + let ambiguous = false; + let toChange = 0; -const _vector$1 = /*@__PURE__*/new Vector3(); + for ( let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { -const _color1 = /*@__PURE__*/new Color(); + betterShapeHoles[ sIdx ] = []; -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; - const geometry = new OctahedronGeometry(size); - geometry.rotateY(Math.PI * 0.5); - this.material = new MeshBasicMaterial({ - wireframe: true, - fog: false, - toneMapped: false - }); - if (this.color === undefined) this.material.vertexColors = true; - const position = geometry.getAttribute('position'); - const colors = new Float32Array(position.count * 3); - geometry.setAttribute('color', new BufferAttribute(colors, 3)); - this.add(new Mesh(geometry, this.material)); - this.update(); - } + for ( let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { - dispose() { - this.children[0].geometry.dispose(); - this.children[0].material.dispose(); - } + const sho = newShapeHoles[ sIdx ]; - update() { - const mesh = this.children[0]; + for ( let hIdx = 0; hIdx < sho.length; hIdx ++ ) { - if (this.color !== undefined) { - this.material.color.set(this.color); - } else { - const colors = mesh.geometry.getAttribute('color'); + const ho = sho[ hIdx ]; + let hole_unassigned = true; - _color1.copy(this.light.color); + for ( let s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) { - _color2.copy(this.light.groundColor); + if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) { - 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); - } + if ( sIdx !== s2Idx ) toChange ++; - colors.needsUpdate = true; - } + if ( hole_unassigned ) { - mesh.lookAt(_vector$1.setFromMatrixPosition(this.light.matrixWorld).negate()); - } + hole_unassigned = false; + betterShapeHoles[ s2Idx ].push( ho ); -} + } else { -class GridHelper extends LineSegments { - constructor(size = 10, divisions = 10, color1 = 0x444444, color2 = 0x888888) { - color1 = new Color(color1); - color2 = new Color(color2); - const center = divisions / 2; - const step = size / divisions; - const halfSize = size / 2; - const vertices = [], - colors = []; + ambiguous = true; - 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); - const color = i === center ? color1 : color2; - color.toArray(colors, j); - j += 3; - color.toArray(colors, j); - j += 3; - color.toArray(colors, j); - j += 3; - color.toArray(colors, j); - j += 3; - } + } - const geometry = new BufferGeometry(); - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); - const material = new LineBasicMaterial({ - vertexColors: true, - toneMapped: false - }); - super(geometry, material); - this.type = 'GridHelper'; - } + } -} + } -class PolarGridHelper extends LineSegments { - constructor(radius = 10, radials = 16, circles = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888) { - color1 = new Color(color1); - color2 = new Color(color2); - const vertices = []; - const colors = []; // create the radials + if ( hole_unassigned ) { + + betterShapeHoles[ sIdx ].push( ho ); - 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 + } + } - for (let i = 0; i <= circles; i++) { - const color = i & 1 ? color1 : color2; - const r = radius - radius / circles * 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 + if ( toChange > 0 && ambiguous === false ) { + + newShapeHoles = betterShapeHoles; - v = (j + 1) / divisions * (Math.PI * 2); - x = Math.sin(v) * r; - z = Math.cos(v) * r; - vertices.push(x, 0, z); - colors.push(color.r, color.g, color.b); } + } - const geometry = new BufferGeometry(); - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); - const material = new LineBasicMaterial({ - vertexColors: true, - toneMapped: false - }); - super(geometry, material); - this.type = 'PolarGridHelper'; - } + let tmpHoles; -} + for ( let i = 0, il = newShapes.length; i < il; i ++ ) { -const _v1 = /*@__PURE__*/new Vector3(); + tmpShape = newShapes[ i ].s; + shapes.push( tmpShape ); + tmpHoles = newShapeHoles[ i ]; -const _v2 = /*@__PURE__*/new Vector3(); + for ( let j = 0, jl = tmpHoles.length; j < jl; j ++ ) { -const _v3 = /*@__PURE__*/new Vector3(); + tmpShape.holes.push( tmpHoles[ j ].h ); -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; - 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)); - const material = new LineBasicMaterial({ - fog: false, - toneMapped: false - }); - this.lightPlane = new Line(geometry, material); - this.add(this.lightPlane); - geometry = new BufferGeometry(); - geometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 0, 1], 3)); - this.targetLine = new Line(geometry, material); - this.add(this.targetLine); - this.update(); - } + } + + } + + //console.log("shape", shapes); + + return shapes; - dispose() { - this.lightPlane.geometry.dispose(); - this.lightPlane.material.dispose(); - this.targetLine.geometry.dispose(); - this.targetLine.material.dispose(); } - update() { - _v1.setFromMatrixPosition(this.light.matrixWorld); +} - _v2.setFromMatrixPosition(this.light.target.matrixWorld); +// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf - _v3.subVectors(_v2, _v1); +const _tables = /*@__PURE__*/ _generateTables(); - this.lightPlane.lookAt(_v2); +function _generateTables() { - if (this.color !== undefined) { - this.lightPlane.material.color.set(this.color); - this.targetLine.material.color.set(this.color); - } else { - this.lightPlane.material.color.copy(this.light.color); - this.targetLine.material.color.copy(this.light.color); - } + // float32 to float16 helpers - this.targetLine.lookAt(_v2); - this.targetLine.scale.z = _v3.length(); - } + 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 ); -const _vector = /*@__PURE__*/new Vector3(); + for ( let i = 0; i < 256; ++ i ) { -const _camera = /*@__PURE__*/new Camera(); -/** - * - shows frustum, line of sight and up of the camera - * - suitable for fast updates - * - based on frustum visualization in lightgl.js shadowmap example - * https://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html - */ + const e = i - 127; + // very small number (0, -0) -class CameraHelper extends LineSegments { - constructor(camera) { - const geometry = new BufferGeometry(); - const material = new LineBasicMaterial({ - color: 0xffffff, - vertexColors: true, - toneMapped: false - }); - const vertices = []; - const colors = []; - const pointMap = {}; // colors + if ( e < - 27 ) { + + baseTable[ i ] = 0x0000; + baseTable[ i | 0x100 ] = 0x8000; + shiftTable[ i ] = 24; + shiftTable[ i | 0x100 ] = 24; + + // small number (denorm) - const colorFrustum = new Color(0xffaa00); - const colorCone = new Color(0xff0000); - const colorUp = new Color(0x00aaff); - const colorTarget = new Color(0xffffff); - const colorCross = new Color(0x333333); // near + } else if ( e < - 14 ) { - addLine('n1', 'n2', colorFrustum); - addLine('n2', 'n4', colorFrustum); - addLine('n4', 'n3', colorFrustum); - addLine('n3', 'n1', colorFrustum); // far + baseTable[ i ] = 0x0400 >> ( - e - 14 ); + baseTable[ i | 0x100 ] = ( 0x0400 >> ( - e - 14 ) ) | 0x8000; + shiftTable[ i ] = - e - 1; + shiftTable[ i | 0x100 ] = - e - 1; - addLine('f1', 'f2', colorFrustum); - addLine('f2', 'f4', colorFrustum); - addLine('f4', 'f3', colorFrustum); - addLine('f3', 'f1', colorFrustum); // sides + // normal number - addLine('n1', 'f1', colorFrustum); - addLine('n2', 'f2', colorFrustum); - addLine('n3', 'f3', colorFrustum); - addLine('n4', 'f4', colorFrustum); // cone + } else if ( e <= 15 ) { - addLine('p', 'n1', colorCone); - addLine('p', 'n2', colorCone); - addLine('p', 'n3', colorCone); - addLine('p', 'n4', colorCone); // up + baseTable[ i ] = ( e + 15 ) << 10; + baseTable[ i | 0x100 ] = ( ( e + 15 ) << 10 ) | 0x8000; + shiftTable[ i ] = 13; + shiftTable[ i | 0x100 ] = 13; - addLine('u1', 'u2', colorUp); - addLine('u2', 'u3', colorUp); - addLine('u3', 'u1', colorUp); // target + // large number (Infinity, -Infinity) - addLine('c', 't', colorTarget); - addLine('p', 'c', colorCross); // cross + } else if ( e < 128 ) { - addLine('cn1', 'cn2', colorCross); - addLine('cn3', 'cn4', colorCross); - addLine('cf1', 'cf2', colorCross); - addLine('cf3', 'cf4', colorCross); + baseTable[ i ] = 0x7c00; + baseTable[ i | 0x100 ] = 0xfc00; + shiftTable[ i ] = 24; + shiftTable[ i | 0x100 ] = 24; - function addLine(a, b, color) { - addPoint(a, color); - addPoint(b, color); - } + // stay (NaN, Infinity, -Infinity) - function addPoint(id, color) { - vertices.push(0, 0, 0); - colors.push(color.r, color.g, color.b); + } else { - if (pointMap[id] === undefined) { - pointMap[id] = []; - } + baseTable[ i ] = 0x7c00; + baseTable[ i | 0x100 ] = 0xfc00; + shiftTable[ i ] = 13; + shiftTable[ i | 0x100 ] = 13; - pointMap[id].push(vertices.length / 3 - 1); } - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); - super(geometry, material); - this.type = 'CameraHelper'; - this.camera = camera; - if (this.camera.updateProjectionMatrix) this.camera.updateProjectionMatrix(); - this.matrix = camera.matrixWorld; - this.matrixAutoUpdate = false; - this.pointMap = pointMap; - this.update(); } - update() { - const geometry = this.geometry; - const pointMap = this.pointMap; - const w = 1, - h = 1; // we need just camera projection matrix inverse - // world matrix must be identity - - _camera.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse); // center / target + // float16 to float32 helpers + const mantissaTable = new Uint32Array( 2048 ); + const exponentTable = new Uint32Array( 64 ); + const offsetTable = new Uint32Array( 64 ); - setPoint('c', pointMap, geometry, _camera, 0, 0, -1); - setPoint('t', pointMap, geometry, _camera, 0, 0, 1); // near + for ( let i = 1; i < 1024; ++ i ) { - 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 + let m = i << 13; // zero pad mantissa bits + let e = 0; // zero exponent - 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 + // normalized + while ( ( m & 0x00800000 ) === 0 ) { - 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 + m <<= 1; + e -= 0x00800000; // decrement exponent - setPoint('cf1', pointMap, geometry, _camera, -w, 0, 1); - setPoint('cf2', pointMap, geometry, _camera, w, 0, 1); - setPoint('cf3', pointMap, geometry, _camera, 0, -h, 1); - setPoint('cf4', pointMap, geometry, _camera, 0, h, 1); - setPoint('cn1', pointMap, geometry, _camera, -w, 0, -1); - setPoint('cn2', pointMap, geometry, _camera, w, 0, -1); - setPoint('cn3', pointMap, geometry, _camera, 0, -h, -1); - setPoint('cn4', pointMap, geometry, _camera, 0, h, -1); - geometry.getAttribute('position').needsUpdate = true; - } + } - dispose() { - this.geometry.dispose(); - this.material.dispose(); - } + m &= ~ 0x00800000; // clear leading 1 bit + e += 0x38800000; // adjust bias -} + mantissaTable[ i ] = m | e; -function setPoint(point, pointMap, geometry, camera, x, y, z) { - _vector.set(x, y, z).unproject(camera); + } - const points = pointMap[point]; + for ( let i = 1024; i < 2048; ++ i ) { - if (points !== undefined) { - const position = geometry.getAttribute('position'); + mantissaTable[ i ] = 0x38000000 + ( ( i - 1024 ) << 13 ); - for (let i = 0, l = points.length; i < l; i++) { - position.setXYZ(points[i], _vector.x, _vector.y, _vector.z); - } } -} -const _box = /*@__PURE__*/new Box3(); + for ( let i = 1; i < 31; ++ i ) { + + exponentTable[ i ] = i << 23; -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]); - const positions = new Float32Array(8 * 3); - const geometry = new BufferGeometry(); - geometry.setIndex(new BufferAttribute(indices, 1)); - geometry.setAttribute('position', new BufferAttribute(positions, 3)); - super(geometry, new LineBasicMaterial({ - color: color, - toneMapped: false - })); - this.object = object; - this.type = 'BoxHelper'; - this.matrixAutoUpdate = false; - this.update(); } - update(object) { - if (object !== undefined) { - console.warn('THREE.BoxHelper: .update() has no longer arguments.'); - } + exponentTable[ 31 ] = 0x47800000; + exponentTable[ 32 ] = 0x80000000; - if (this.object !== undefined) { - _box.setFromObject(this.object); - } + for ( let i = 33; i < 63; ++ i ) { - if (_box.isEmpty()) return; - const min = _box.min; - const max = _box.max; - /* - 5____4 - 1/___0/| - | 6__|_7 - 2/___3/ - 0: max.x, max.y, max.z - 1: min.x, max.y, max.z - 2: min.x, min.y, max.z - 3: max.x, min.y, max.z - 4: max.x, max.y, min.z - 5: min.x, max.y, min.z - 6: min.x, min.y, min.z - 7: max.x, min.y, min.z - */ + exponentTable[ i ] = 0x80000000 + ( ( i - 32 ) << 23 ); - const position = this.geometry.attributes.position; - const array = position.array; - array[0] = max.x; - array[1] = max.y; - array[2] = max.z; - array[3] = min.x; - array[4] = max.y; - array[5] = max.z; - array[6] = min.x; - array[7] = min.y; - array[8] = max.z; - array[9] = max.x; - array[10] = min.y; - array[11] = max.z; - array[12] = max.x; - array[13] = max.y; - array[14] = min.z; - array[15] = min.x; - array[16] = max.y; - array[17] = min.z; - array[18] = min.x; - array[19] = min.y; - array[20] = min.z; - array[21] = max.x; - array[22] = min.y; - array[23] = min.z; - position.needsUpdate = true; - this.geometry.computeBoundingSphere(); } - setFromObject(object) { - this.object = object; - this.update(); - return this; - } + exponentTable[ 63 ] = 0xc7800000; - copy(source, recursive) { - super.copy(source, recursive); - this.object = source.object; - return this; - } + for ( let i = 1; i < 64; ++ i ) { -} + if ( i !== 32 ) { -class Box3Helper extends LineSegments { - constructor(box, 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]); - const positions = [1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1]; - const geometry = new BufferGeometry(); - geometry.setIndex(new BufferAttribute(indices, 1)); - geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); - super(geometry, new LineBasicMaterial({ - color: color, - toneMapped: false - })); - this.box = box; - this.type = 'Box3Helper'; - this.geometry.computeBoundingSphere(); - } + offsetTable[ i ] = 1024; + + } - updateMatrixWorld(force) { - const box = this.box; - if (box.isEmpty()) return; - box.getCenter(this.position); - box.getSize(this.scale); - this.scale.multiplyScalar(0.5); - super.updateMatrixWorld(force); } + return { + floatView: floatView, + uint32View: uint32View, + baseTable: baseTable, + shiftTable: shiftTable, + mantissaTable: mantissaTable, + exponentTable: exponentTable, + offsetTable: offsetTable + }; + } -class PlaneHelper extends Line { - constructor(plane, size = 1, hex = 0xffff00) { - const color = hex; - const positions = [1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0]; - const geometry = new BufferGeometry(); - geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); - geometry.computeBoundingSphere(); - super(geometry, new LineBasicMaterial({ - color: color, - toneMapped: false - })); - this.type = 'PlaneHelper'; - this.plane = plane; - this.size = size; - const positions2 = [1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1]; - const geometry2 = new BufferGeometry(); - geometry2.setAttribute('position', new Float32BufferAttribute(positions2, 3)); - geometry2.computeBoundingSphere(); - this.add(new Mesh(geometry2, new MeshBasicMaterial({ - color: color, - opacity: 0.2, - transparent: true, - depthWrite: false, - toneMapped: false - }))); - } +// float32 to float16 - updateMatrixWorld(force) { - let scale = -this.plane.constant; - if (Math.abs(scale) < 1e-8) scale = 1e-8; // sign does not matter +function toHalfFloat( val ) { - this.scale.set(0.5 * this.size, 0.5 * this.size, scale); - this.children[0].material.side = scale < 0 ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here + if ( Math.abs( val ) > 65504 ) console.warn( 'THREE.DataUtils.toHalfFloat(): Value out of range.' ); - this.lookAt(this.plane.normal); - super.updateMatrixWorld(force); - } + val = clamp( val, - 65504, 65504 ); + + _tables.floatView[ 0 ] = val; + const f = _tables.uint32View[ 0 ]; + const e = ( f >> 23 ) & 0x1ff; + return _tables.baseTable[ e ] + ( ( f & 0x007fffff ) >> _tables.shiftTable[ e ] ); } -const _axis = /*@__PURE__*/new Vector3(); +// float16 to float32 -let _lineGeometry, _coneGeometry; +function fromHalfFloat( val ) { -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'; + const m = val >> 10; + _tables.uint32View[ 0 ] = _tables.mantissaTable[ _tables.offsetTable[ m ] + ( val & 0x3ff ) ] + _tables.exponentTable[ m ]; + return _tables.floatView[ 0 ]; - if (_lineGeometry === undefined) { - _lineGeometry = new BufferGeometry(); +} - _lineGeometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 1, 0], 3)); +var DataUtils = /*#__PURE__*/Object.freeze({ + __proto__: null, + fromHalfFloat: fromHalfFloat, + toHalfFloat: toHalfFloat +}); - _coneGeometry = new CylinderGeometry(0, 0.5, 1, 5, 1); +// r144 - _coneGeometry.translate(0, -0.5, 0); - } +class BoxBufferGeometry extends BoxGeometry { - this.position.copy(origin); - this.line = new Line(_lineGeometry, new LineBasicMaterial({ - color: color, - toneMapped: false - })); - this.line.matrixAutoUpdate = false; - this.add(this.line); - this.cone = new Mesh(_coneGeometry, new MeshBasicMaterial({ - color: color, - toneMapped: false - })); - this.cone.matrixAutoUpdate = false; - this.add(this.cone); - this.setDirection(dir); - this.setLength(length, headLength, headWidth); - } + constructor( width, height, depth, widthSegments, heightSegments, depthSegments ) { + + console.warn( 'THREE.BoxBufferGeometry has been renamed to THREE.BoxGeometry.' ); + super( width, height, depth, widthSegments, heightSegments, depthSegments ); - 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(); - } +// r144 - setColor(color) { - this.line.material.color.set(color); - this.cone.material.color.set(color); - } +class CapsuleBufferGeometry extends CapsuleGeometry { + + constructor( radius, length, capSegments, radialSegments ) { + + console.warn( 'THREE.CapsuleBufferGeometry has been renamed to THREE.CapsuleGeometry.' ); + super( radius, length, capSegments, radialSegments ); - copy(source) { - super.copy(source, false); - this.line.copy(source.line); - this.cone.copy(source.cone); - return this; } } -class AxesHelper extends LineSegments { - constructor(size = 1) { - const vertices = [0, 0, 0, size, 0, 0, 0, 0, 0, 0, size, 0, 0, 0, 0, 0, 0, size]; - const colors = [1, 0, 0, 1, 0.6, 0, 0, 1, 0, 0.6, 1, 0, 0, 0, 1, 0, 0.6, 1]; - const geometry = new BufferGeometry(); - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); - const material = new LineBasicMaterial({ - vertexColors: true, - toneMapped: false - }); - super(geometry, material); - this.type = 'AxesHelper'; - } +// r144 - setColors(xAxisColor, yAxisColor, zAxisColor) { - const color = new Color(); - const array = this.geometry.attributes.color.array; - color.set(xAxisColor); - color.toArray(array, 0); - color.toArray(array, 3); - color.set(yAxisColor); - color.toArray(array, 6); - color.toArray(array, 9); - color.set(zAxisColor); - color.toArray(array, 12); - color.toArray(array, 15); - this.geometry.attributes.color.needsUpdate = true; - return this; - } +class CircleBufferGeometry extends CircleGeometry { + + constructor( radius, segments, thetaStart, thetaLength ) { + + console.warn( 'THREE.CircleBufferGeometry has been renamed to THREE.CircleGeometry.' ); + super( radius, segments, thetaStart, thetaLength ); - dispose() { - this.geometry.dispose(); - this.material.dispose(); } } -class ShapePath { - constructor() { - this.type = 'ShapePath'; - this.color = new Color(); - this.subPaths = []; - this.currentPath = null; - } +// r144 - moveTo(x, y) { - this.currentPath = new Path(); - this.subPaths.push(this.currentPath); - this.currentPath.moveTo(x, y); - return this; - } +class ConeBufferGeometry extends ConeGeometry { - lineTo(x, y) { - this.currentPath.lineTo(x, y); - return this; - } + constructor( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { - quadraticCurveTo(aCPx, aCPy, aX, aY) { - this.currentPath.quadraticCurveTo(aCPx, aCPy, aX, aY); - return this; - } + console.warn( 'THREE.ConeBufferGeometry has been renamed to THREE.ConeGeometry.' ); + super( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); - 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) { - function toShapesNoHoles(inSubpaths) { - const shapes = []; +// r144 - 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); - } +class CylinderBufferGeometry extends CylinderGeometry { - return shapes; - } + constructor( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { - function isPointInsidePolygon(inPt, inPolygon) { - 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 + console.warn( 'THREE.CylinderBufferGeometry has been renamed to THREE.CylinderGeometry.' ); + super( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); - 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) { - edgeLowPt = inPolygon[q]; - edgeDx = -edgeDx; - edgeHighPt = inPolygon[p]; - edgeDy = -edgeDy; - } +// r144 - if (inPt.y < edgeLowPt.y || inPt.y > edgeHighPt.y) continue; +class DodecahedronBufferGeometry extends DodecahedronGeometry { - 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 ? + constructor( radius, detail ) { - if (perpEdge < 0) continue; - inside = !inside; // true intersection left of inPt - } - } else { - // parallel or collinear - if (inPt.y !== edgeLowPt.y) continue; // parallel - // edge lies on the same horizontal line as inPt + console.warn( 'THREE.DodecahedronBufferGeometry has been renamed to THREE.DodecahedronGeometry.' ); + super( radius, detail ); - if (edgeHighPt.x <= inPt.x && inPt.x <= edgeLowPt.x || edgeLowPt.x <= inPt.x && inPt.x <= edgeHighPt.x) return true; // inPt: Point on contour ! - // continue; - } - } + } - return inside; - } +} - 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 = []; +// r144 - if (subPaths.length === 1) { - tmpPath = subPaths[0]; - tmpShape = new Shape(); - tmpShape.curves = tmpPath.curves; - shapes.push(tmpShape); - return shapes; - } +class ExtrudeBufferGeometry extends ExtrudeGeometry { - let holesFirst = !isClockWise(subPaths[0].getPoints()); - holesFirst = isCCW ? !holesFirst : holesFirst; // console.log("Holes first", holesFirst); + constructor( shapes, options ) { - const betterShapeHoles = []; - const newShapes = []; - let newShapeHoles = []; - let mainIdx = 0; - let tmpPoints; - newShapes[mainIdx] = undefined; - newShapeHoles[mainIdx] = []; + console.warn( 'THREE.ExtrudeBufferGeometry has been renamed to THREE.ExtrudeGeometry.' ); + super( shapes, options ); - 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] = { - s: new Shape(), - p: tmpPoints - }; - newShapes[mainIdx].s.curves = tmpPath.curves; - if (holesFirst) mainIdx++; - newShapeHoles[mainIdx] = []; //console.log('cw', i); - } else { - newShapeHoles[mainIdx].push({ - h: tmpPath, - p: tmpPoints[0] - }); //console.log('ccw', i); - } - } // only Holes? -> probably all Shapes with wrong orientation + } +} - if (!newShapes[0]) return toShapesNoHoles(subPaths); +// r144 - if (newShapes.length > 1) { - let ambiguous = false; - let toChange = 0; +class IcosahedronBufferGeometry extends IcosahedronGeometry { - for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { - betterShapeHoles[sIdx] = []; - } + constructor( radius, detail ) { - for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { - const sho = newShapeHoles[sIdx]; + console.warn( 'THREE.IcosahedronBufferGeometry has been renamed to THREE.IcosahedronGeometry.' ); + super( radius, detail ); - 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); - } else { - ambiguous = true; - } - } - } +// r144 - if (hole_unassigned) { - betterShapeHoles[sIdx].push(ho); - } - } - } +class LatheBufferGeometry extends LatheGeometry { - if (toChange > 0 && ambiguous === false) { - newShapeHoles = betterShapeHoles; - } - } + constructor( points, segments, phiStart, phiLength ) { - let tmpHoles; + console.warn( 'THREE.LatheBufferGeometry has been renamed to THREE.LatheGeometry.' ); + super( points, segments, phiStart, phiLength ); + + } - 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); +// r144 +class OctahedronBufferGeometry extends OctahedronGeometry { + + constructor( radius, detail ) { + + console.warn( 'THREE.OctahedronBufferGeometry has been renamed to THREE.OctahedronGeometry.' ); + super( radius, detail ); - return shapes; } } -class DataUtils { - // float32 to float16 - static toHalfFloat(val) { - if (Math.abs(val) > 65504) console.warn('THREE.DataUtils.toHalfFloat(): Value out of range.'); - val = clamp(val, -65504, 65504); - _floatView[0] = val; - const f = _uint32View[0]; - const e = f >> 23 & 0x1ff; - return _baseTable[e] + ((f & 0x007fffff) >> _shiftTable[e]); - } // float16 to float32 +// 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 ); - static fromHalfFloat(val) { - const m = val >> 10; - _uint32View[0] = _mantissaTable[_offsetTable[m] + (val & 0x3ff)] + _exponentTable[m]; - return _floatView[0]; } -} // float32 to float16 helpers +} +// r144 -const _buffer = new ArrayBuffer(4); +class PolyhedronBufferGeometry extends PolyhedronGeometry { -const _floatView = new Float32Array(_buffer); + constructor( vertices, indices, radius, detail ) { -const _uint32View = new Uint32Array(_buffer); + console.warn( 'THREE.PolyhedronBufferGeometry has been renamed to THREE.PolyhedronGeometry.' ); + super( vertices, indices, radius, detail ); -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) +// r144 - if (e < -27) { - _baseTable[i] = 0x0000; - _baseTable[i | 0x100] = 0x8000; - _shiftTable[i] = 24; - _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 - } 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) - } else if (e < 128) { - _baseTable[i] = 0x7c00; - _baseTable[i | 0x100] = 0xfc00; - _shiftTable[i] = 24; - _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 +class RingBufferGeometry extends RingGeometry { + constructor( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { -const _mantissaTable = new Uint32Array(2048); + console.warn( 'THREE.RingBufferGeometry has been renamed to THREE.RingGeometry.' ); + super( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ); -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 +// r144 - let e = 0; // zero exponent - // normalized +class ShapeBufferGeometry extends ShapeGeometry { - while ((m & 0x00800000) === 0) { - m <<= 1; - e -= 0x00800000; // decrement exponent - } + constructor( shapes, curveSegments ) { - m &= ~0x00800000; // clear leading 1 bit + console.warn( 'THREE.ShapeBufferGeometry has been renamed to THREE.ShapeGeometry.' ); + super( shapes, curveSegments ); - e += 0x38800000; // adjust bias + } - _mantissaTable[i] = m | e; } -for (let i = 1024; i < 2048; ++i) { - _mantissaTable[i] = 0x38000000 + (i - 1024 << 13); -} +// r144 -for (let i = 1; i < 31; ++i) { - _exponentTable[i] = i << 23; -} +class SphereBufferGeometry extends SphereGeometry { + + constructor( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { -_exponentTable[31] = 0x47800000; -_exponentTable[32] = 0x80000000; + console.warn( 'THREE.SphereBufferGeometry has been renamed to THREE.SphereGeometry.' ); + super( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ); + + } -for (let i = 33; i < 63; ++i) { - _exponentTable[i] = 0x80000000 + (i - 32 << 23); } -_exponentTable[63] = 0xc7800000; +// r144 + +class TetrahedronBufferGeometry extends TetrahedronGeometry { + + constructor( radius, detail ) { + + console.warn( 'THREE.TetrahedronBufferGeometry has been renamed to THREE.TetrahedronGeometry.' ); + super( radius, detail ); -for (let i = 1; i < 64; ++i) { - if (i !== 32) { - _offsetTable[i] = 1024; } + } -class ParametricGeometry extends BufferGeometry { - constructor() { - console.error('THREE.ParametricGeometry has been moved to /examples/jsm/geometries/ParametricGeometry.js'); - super(); - } +// r144 -} // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 +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 ); -class TextGeometry extends BufferGeometry { - constructor() { - console.error('THREE.TextGeometry has been moved to /examples/jsm/geometries/TextGeometry.js'); - super(); } -} // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 +} + +// r144 -function FontLoader() { - console.error('THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js'); -} // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 +class TorusKnotBufferGeometry extends TorusKnotGeometry { -function Font() { - console.error('THREE.Font has been moved to /examples/jsm/loaders/FontLoader.js'); -} // r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0 + constructor( radius, tube, tubularSegments, radialSegments, p, q ) { -function ImmediateRenderObject() { - console.error('THREE.ImmediateRenderObject has been removed.'); -} // r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17 + console.warn( 'THREE.TorusKnotBufferGeometry has been renamed to THREE.TorusKnotGeometry.' ); + super( radius, tube, tubularSegments, radialSegments, p, q ); -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; } -} // r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce +} + +// r144 -class DataTexture2DArray extends DataArrayTexture { - constructor(data, width, height, depth) { - console.warn('THREE.DataTexture2DArray has been renamed to DataArrayTexture.'); - super(data, width, height, depth); - } +class TubeBufferGeometry extends TubeGeometry { -} // r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce + constructor( path, tubularSegments, radius, radialSegments, closed ) { + + console.warn( 'THREE.TubeBufferGeometry has been renamed to THREE.TubeGeometry.' ); + super( path, tubularSegments, radius, radialSegments, closed ); -class DataTexture3D extends Data3DTexture { - constructor(data, width, height, depth) { - console.warn('THREE.DataTexture3D has been renamed to Data3DTexture.'); - super(data, width, height, depth); } } -if (typeof __THREE_DEVTOOLS__ !== 'undefined') { - __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('register', { - detail: { - revision: REVISION - } - })); +if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { + + __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'register', { detail: { + revision: REVISION, + } } ) ); + } -if (typeof window !== 'undefined') { - if (window.__THREE__) { - console.warn('WARNING: Multiple instances of Three.js being imported.'); +if ( typeof window !== 'undefined' ) { + + if ( window.__THREE__ ) { + + console.warn( 'WARNING: Multiple instances of Three.js being imported.' ); + } else { + window.__THREE__ = REVISION; + } + } exports.ACESFilmicToneMapping = ACESFilmicToneMapping; @@ -35164,7 +50578,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; @@ -35175,20 +50589,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; @@ -35207,14 +50622,12 @@ 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; exports.DataArrayTexture = DataArrayTexture; exports.DataTexture = DataTexture; -exports.DataTexture2DArray = DataTexture2DArray; -exports.DataTexture3D = DataTexture3D; exports.DataTextureLoader = DataTextureLoader; exports.DataUtils = DataUtils; exports.DecrementStencilOp = DecrementStencilOp; @@ -35226,7 +50639,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; @@ -35242,18 +50655,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; @@ -35270,12 +50680,11 @@ 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; exports.ImageUtils = ImageUtils; -exports.ImmediateRenderObject = ImmediateRenderObject; exports.IncrementStencilOp = IncrementStencilOp; exports.IncrementWrapStencilOp = IncrementWrapStencilOp; exports.InstancedBufferAttribute = InstancedBufferAttribute; @@ -35296,7 +50705,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; @@ -35371,7 +50780,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; @@ -35382,11 +50791,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; @@ -35394,7 +50802,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; @@ -35404,6 +50812,8 @@ exports.QuadraticBezierCurve3 = QuadraticBezierCurve3; exports.Quaternion = Quaternion; exports.QuaternionKeyframeTrack = QuaternionKeyframeTrack; exports.QuaternionLinearInterpolant = QuaternionLinearInterpolant; +exports.RED_GREEN_RGTC2_Format = RED_GREEN_RGTC2_Format; +exports.RED_RGTC1_Format = RED_RGTC1_Format; exports.REVISION = REVISION; exports.RGBADepthPacking = RGBADepthPacking; exports.RGBAFormat = RGBAFormat; @@ -35429,7 +50839,6 @@ exports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format; exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format; exports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format; exports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format; -exports.RGBFormat = RGBFormat; exports.RGB_ETC1_Format = RGB_ETC1_Format; exports.RGB_ETC2_Format = RGB_ETC2_Format; exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format; @@ -35447,8 +50856,10 @@ exports.ReinhardToneMapping = ReinhardToneMapping; exports.RepeatWrapping = RepeatWrapping; exports.ReplaceStencilOp = ReplaceStencilOp; exports.ReverseSubtractEquation = ReverseSubtractEquation; -exports.RingBufferGeometry = RingGeometry; +exports.RingBufferGeometry = RingBufferGeometry; exports.RingGeometry = RingGeometry; +exports.SIGNED_RED_GREEN_RGTC2_Format = SIGNED_RED_GREEN_RGTC2_Format; +exports.SIGNED_RED_RGTC1_Format = SIGNED_RED_RGTC1_Format; exports.SRGBColorSpace = SRGBColorSpace; exports.Scene = Scene; exports.ShaderChunk = ShaderChunk; @@ -35456,7 +50867,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; @@ -35464,10 +50875,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; @@ -35491,27 +50901,28 @@ 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.TwoPassDoubleSide = TwoPassDoubleSide; exports.UVMapping = UVMapping; exports.Uint16BufferAttribute = Uint16BufferAttribute; exports.Uint32BufferAttribute = Uint32BufferAttribute; exports.Uint8BufferAttribute = Uint8BufferAttribute; exports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute; exports.Uniform = Uniform; +exports.UniformsGroup = UniformsGroup; exports.UniformsLib = UniformsLib; exports.UniformsUtils = UniformsUtils; exports.UnsignedByteType = UnsignedByteType; @@ -35531,7 +50942,6 @@ exports.WebGL3DRenderTarget = WebGL3DRenderTarget; exports.WebGLArrayRenderTarget = WebGLArrayRenderTarget; exports.WebGLCubeRenderTarget = WebGLCubeRenderTarget; exports.WebGLMultipleRenderTargets = WebGLMultipleRenderTargets; -exports.WebGLMultisampleRenderTarget = WebGLMultisampleRenderTarget; exports.WebGLRenderTarget = WebGLRenderTarget; exports.WebGLRenderer = WebGLRenderer; exports.WebGLUtils = WebGLUtils; diff --git a/build/three.js b/build/three.js index c370ce924cfec4..7f359b9694e128 100644 --- a/build/three.js +++ b/build/three.js @@ -1,6 +1,6 @@ /** * @license - * Copyright 2010-2022 Three.js Authors + * Copyright 2010-2023 Three.js Authors * SPDX-License-Identifier: MIT */ (function (global, factory) { @@ -9,21 +9,9 @@ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.THREE = {})); })(this, (function (exports) { 'use strict'; - const REVISION = '141dev'; - const MOUSE = { - LEFT: 0, - MIDDLE: 1, - RIGHT: 2, - ROTATE: 0, - DOLLY: 1, - PAN: 2 - }; - const TOUCH = { - ROTATE: 0, - PAN: 1, - DOLLY_PAN: 2, - DOLLY_ROTATE: 3 - }; + const REVISION = '150dev'; + const MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 }; + const TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 }; const CullFaceNone = 0; const CullFaceBack = 1; const CullFaceFront = 2; @@ -35,8 +23,7 @@ const FrontSide = 0; const BackSide = 1; const DoubleSide = 2; - const FlatShading = 1; - const SmoothShading = 2; + const TwoPassDoubleSide = 2; // r149 const NoBlending = 0; const NormalBlending = 1; const AdditiveBlending = 2; @@ -76,6 +63,7 @@ const CineonToneMapping = 3; const ACESFilmicToneMapping = 4; const CustomToneMapping = 5; + const UVMapping = 300; const CubeReflectionMapping = 301; const CubeRefractionMapping = 302; @@ -107,7 +95,6 @@ const UnsignedShort5551Type = 1018; const UnsignedInt248Type = 1020; const AlphaFormat = 1021; - const RGBFormat = 1022; const RGBAFormat = 1023; const LuminanceFormat = 1024; const LuminanceAlphaFormat = 1025; @@ -118,6 +105,7 @@ const RGFormat = 1030; const RGIntegerFormat = 1031; const RGBAIntegerFormat = 1033; + const RGB_S3TC_DXT1_Format = 33776; const RGBA_S3TC_DXT1_Format = 33777; const RGBA_S3TC_DXT3_Format = 33778; @@ -144,6 +132,10 @@ const RGBA_ASTC_12x10_Format = 37820; const RGBA_ASTC_12x12_Format = 37821; const RGBA_BPTC_Format = 36492; + const RED_RGTC1_Format = 36283; + const SIGNED_RED_RGTC1_Format = 36284; + const RED_GREEN_RGTC2_Format = 36285; + const SIGNED_RED_GREEN_RGTC2_Format = 36286; const LoopOnce = 2200; const LoopRepeat = 2201; const LoopPingPong = 2202; @@ -163,11 +155,13 @@ 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'; + const ZeroStencilOp = 0; const KeepStencilOp = 7680; const ReplaceStencilOp = 7681; @@ -176,6 +170,7 @@ const IncrementWrapStencilOp = 34055; const DecrementWrapStencilOp = 34056; const InvertStencilOp = 5386; + const NeverStencilFunc = 512; const LessStencilFunc = 513; const EqualStencilFunc = 514; @@ -184,6 +179,7 @@ const NotEqualStencilFunc = 517; const GreaterEqualStencilFunc = 518; const AlwaysStencilFunc = 519; + const StaticDrawUsage = 35044; const DynamicDrawUsage = 35048; const StreamDrawUsage = 35040; @@ -193,924 +189,1260 @@ const StaticCopyUsage = 35046; const DynamicCopyUsage = 35050; const StreamCopyUsage = 35042; + const GLSL1 = '100'; const GLSL3 = '300 es'; + const _SRGBAFormat = 1035; // fallback for WebGL 1 /** * https://github.com/mrdoob/eventdispatcher.js/ */ + class EventDispatcher { - addEventListener(type, listener) { - if (this._listeners === undefined) this._listeners = {}; + + addEventListener( type, listener ) { + + if ( this._listeners === undefined ) this._listeners = {}; + const listeners = this._listeners; - if (listeners[type] === undefined) { - listeners[type] = []; + if ( listeners[ type ] === undefined ) { + + listeners[ type ] = []; + } - if (listeners[type].indexOf(listener) === -1) { - listeners[type].push(listener); + if ( listeners[ type ].indexOf( listener ) === - 1 ) { + + listeners[ type ].push( listener ); + } + } - hasEventListener(type, listener) { - if (this._listeners === undefined) return false; + hasEventListener( type, listener ) { + + if ( this._listeners === undefined ) return false; + const listeners = this._listeners; - return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1; + + return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1; + } - removeEventListener(type, listener) { - if (this._listeners === undefined) return; + removeEventListener( type, listener ) { + + if ( this._listeners === undefined ) return; + const listeners = this._listeners; - const listenerArray = listeners[type]; + const listenerArray = listeners[ type ]; - if (listenerArray !== undefined) { - const index = listenerArray.indexOf(listener); + if ( listenerArray !== undefined ) { + + const index = listenerArray.indexOf( listener ); + + if ( index !== - 1 ) { + + listenerArray.splice( index, 1 ); - if (index !== -1) { - listenerArray.splice(index, 1); } + } + } - dispatchEvent(event) { - if (this._listeners === undefined) return; + dispatchEvent( event ) { + + if ( this._listeners === undefined ) return; + const listeners = this._listeners; - const listenerArray = listeners[event.type]; + const listenerArray = listeners[ event.type ]; + + if ( listenerArray !== undefined ) { - if (listenerArray !== undefined) { - event.target = this; // Make a copy, in case listeners are removed while iterating. + event.target = this; - const array = listenerArray.slice(0); + // 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 ); - for (let i = 0, l = array.length; i < l; i++) { - array[i].call(this, event); } event.target = null; + } + } } - const _lut = []; - - for (let i = 0; i < 256; i++) { - _lut[i] = (i < 16 ? '0' : '') + i.toString(16); - } + 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 ) ); + } - function clamp(value, min, max) { - return Math.max(min, Math.min(max, value)); - } // compute euclidean modulo of m % n + // 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 + function mapLinear( x, a1, a2, b1, b2 ) { + return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 ); - function euclideanModulo(n, m) { - return (n % m + m) % m; - } // Linear mapping from range to range + } + // 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 ) { - 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/ + if ( x !== y ) { + return ( value - x ) / ( y - x ); - 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/ + function damp( x, y, lambda, dt ) { + + return lerp( x, y, 1 - Math.exp( - lambda * dt ) ); + + } + + // https://www.desmos.com/calculator/vcsjnyz7x4 + function pingpong( x, length = 1 ) { + + return length - Math.abs( euclideanModulo( x, length * 2 ) - length ); - 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://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; - function damp(x, y, lambda, dt) { - return lerp(x, y, 1 - Math.exp(-lambda * dt)); - } // https://www.desmos.com/calculator/vcsjnyz7x4 + x = ( x - min ) / ( max - min ); + return x * x * x * ( x * ( x * 6 - 15 ) + 10 ); - function pingpong(x, length = 1) { - return length - Math.abs(euclideanModulo(x, length * 2) - length); - } // http://en.wikipedia.org/wiki/Smoothstep + } + + // Random integer from interval + function randInt( low, high ) { + return low + Math.floor( Math.random() * ( high - low + 1 ) ); - 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 float from interval + function randFloat( low, high ) { + return low + Math.random() * ( high - low ); - function randInt(low, high) { - return low + Math.floor(Math.random() * (high - low + 1)); - } // Random float from interval + } + // Random float from <-range/2, range/2> interval + function randFloatSpread( range ) { - function randFloat(low, high) { - return low + Math.random() * (high - low); - } // Random float from <-range/2, range/2> interval + return range * ( 0.5 - Math.random() ); + } - 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; - function seededRandom(s) { - if (s !== undefined) _seed = s; // Mulberry32 generator + // 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; + + 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) { + function degToRad( degrees ) { + return degrees * DEG2RAD; + } - function radToDeg(radians) { + function radToDeg( radians ) { + return radians * RAD2DEG; + } - function isPowerOfTwo(value) { - return (value & value - 1) === 0 && value !== 0; + 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 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 floorPowerOfTwo( value ) { + + return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) ); + } - function setQuaternionFromProperEuler(q, a, b, c, order) { + function setQuaternionFromProperEuler( q, a, b, c, order ) { + // Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles + // rotations are applied to the axes in the order specified by 'order' // rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c' // angles are in radians + const cos = Math.cos; const sin = Math.sin; - const c2 = cos(b / 2); - const s2 = sin(b / 2); - const c13 = cos((a + c) / 2); - const s13 = sin((a + c) / 2); - const c1_3 = cos((a - c) / 2); - const s1_3 = sin((a - c) / 2); - const c3_1 = cos((c - a) / 2); - const s3_1 = sin((c - a) / 2); - - switch (order) { + + const c2 = cos( b / 2 ); + const s2 = sin( b / 2 ); + + const c13 = cos( ( a + c ) / 2 ); + const s13 = sin( ( a + c ) / 2 ); + + const c1_3 = cos( ( a - c ) / 2 ); + const s1_3 = sin( ( a - c ) / 2 ); + + const c3_1 = cos( ( c - a ) / 2 ); + const s3_1 = sin( ( c - a ) / 2 ); + + switch ( order ) { + case 'XYX': - q.set(c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13); + 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); + 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); + 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); + 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); + 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); + q.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 ); break; default: - console.warn('THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order); + console.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order ); + } + } - function denormalize$1(value, array) { - switch (array.constructor) { + 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); + + return Math.max( value / 32767.0, - 1.0 ); case Int8Array: - return Math.max(value / 127.0, -1.0); + + return Math.max( value / 127.0, - 1.0 ); default: - throw new Error('Invalid component type.'); + + throw new Error( 'Invalid component type.' ); + } + } - function normalize(value, array) { - switch (array.constructor) { + function normalize( value, array ) { + + switch ( array.constructor ) { + case Float32Array: + return value; case Uint16Array: - return Math.round(value * 65535.0); + + return Math.round( value * 65535.0 ); case Uint8Array: - return Math.round(value * 255.0); + + return Math.round( value * 255.0 ); case Int16Array: - return Math.round(value * 32767.0); + + return Math.round( value * 32767.0 ); case Int8Array: - return Math.round(value * 127.0); + + return Math.round( value * 127.0 ); default: - throw new Error('Invalid component type.'); + + throw new Error( 'Invalid component type.' ); + } + } var MathUtils = /*#__PURE__*/Object.freeze({ __proto__: null, DEG2RAD: DEG2RAD, RAD2DEG: RAD2DEG, - generateUUID: generateUUID, + ceilPowerOfTwo: ceilPowerOfTwo, clamp: clamp, + damp: damp, + degToRad: degToRad, + denormalize: denormalize, euclideanModulo: euclideanModulo, - mapLinear: mapLinear, + floorPowerOfTwo: floorPowerOfTwo, + generateUUID: generateUUID, inverseLerp: inverseLerp, + isPowerOfTwo: isPowerOfTwo, lerp: lerp, - damp: damp, + mapLinear: mapLinear, + normalize: normalize, pingpong: pingpong, - smoothstep: smoothstep, - smootherstep: smootherstep, - randInt: randInt, + radToDeg: radToDeg, randFloat: randFloat, randFloatSpread: randFloatSpread, + randInt: randInt, seededRandom: seededRandom, - degToRad: degToRad, - radToDeg: radToDeg, - isPowerOfTwo: isPowerOfTwo, - ceilPowerOfTwo: ceilPowerOfTwo, - floorPowerOfTwo: floorPowerOfTwo, setQuaternionFromProperEuler: setQuaternionFromProperEuler, - normalize: normalize, - denormalize: denormalize$1 + smootherstep: smootherstep, + smoothstep: smoothstep }); class Vector2 { - constructor(x = 0, y = 0) { - this.isVector2 = true; + + constructor( x = 0, y = 0 ) { + + Vector2.prototype.isVector2 = true; + this.x = x; this.y = y; + } get width() { + return this.x; + } - set width(value) { + set width( value ) { + this.x = value; + } get height() { + return this.y; + } - set height(value) { + set height( value ) { + this.y = value; + } - set(x, y) { + set( x, y ) { + this.x = x; this.y = y; + return this; + } - setScalar(scalar) { + setScalar( scalar ) { + this.x = scalar; this.y = scalar; + return this; + } - setX(x) { + setX( x ) { + this.x = x; + return this; + } - setY(y) { + setY( y ) { + this.y = y; + return this; + } - setComponent(index, value) { - switch (index) { - case 0: - this.x = value; - break; + setComponent( index, value ) { - case 1: - this.y = value; - break; + switch ( index ) { + + case 0: this.x = value; break; + case 1: this.y = value; break; + default: throw new Error( 'index is out of range: ' + index ); - default: - throw new Error('index is out of range: ' + index); } return this; + } - getComponent(index) { - switch (index) { - case 0: - return this.x; + getComponent( index ) { - case 1: - return this.y; + switch ( index ) { + + case 0: return this.x; + case 1: return this.y; + default: throw new Error( 'index is out of range: ' + index ); - default: - throw new Error('index is out of range: ' + index); } + } clone() { - return new this.constructor(this.x, this.y); + + return new this.constructor( this.x, this.y ); + } - copy(v) { + copy( v ) { + this.x = v.x; this.y = v.y; + return this; + } - add(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.'); - return this.addVectors(v, w); - } + add( v ) { this.x += v.x; this.y += v.y; + return this; + } - addScalar(s) { + addScalar( s ) { + this.x += s; this.y += s; + return this; + } - addVectors(a, b) { + addVectors( a, b ) { + this.x = a.x + b.x; this.y = a.y + b.y; + return this; + } - addScaledVector(v, s) { + addScaledVector( v, s ) { + this.x += v.x * s; this.y += v.y * s; + return this; + } - sub(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.'); - return this.subVectors(v, w); - } + sub( v ) { this.x -= v.x; this.y -= v.y; + return this; + } - subScalar(s) { + subScalar( s ) { + this.x -= s; this.y -= s; + return this; + } - subVectors(a, b) { + subVectors( a, b ) { + this.x = a.x - b.x; this.y = a.y - b.y; + return this; + } - multiply(v) { + multiply( v ) { + this.x *= v.x; this.y *= v.y; + return this; + } - multiplyScalar(scalar) { + multiplyScalar( scalar ) { + this.x *= scalar; this.y *= scalar; + return this; + } - divide(v) { + divide( v ) { + this.x /= v.x; this.y /= v.y; + return this; + } - divideScalar(scalar) { - return this.multiplyScalar(1 / scalar); + divideScalar( scalar ) { + + return this.multiplyScalar( 1 / scalar ); + } - applyMatrix3(m) { - const x = this.x, - y = this.y; + applyMatrix3( m ) { + + const x = this.x, 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]; + + 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); + 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); + max( v ) { + + this.x = Math.max( this.x, v.x ); + this.y = Math.max( this.y, v.y ); + return this; + } - clamp(min, max) { + 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.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)); + 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) { + clampLength( min, max ) { + const length = this.length(); - return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, 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.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); + + 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); + + 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); + + 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; + + this.x = - this.x; + this.y = - this.y; + return this; + } - dot(v) { + dot( v ) { + return this.x * v.x + this.y * v.y; + } - cross(v) { + 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); + + return Math.sqrt( this.x * this.x + this.y * this.y ); + } manhattanLength() { - return Math.abs(this.x) + Math.abs(this.y); - } + + return Math.abs( this.x ) + Math.abs( this.y ); + + } normalize() { - return this.divideScalar(this.length() || 1); + + 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; + + const angle = Math.atan2( - this.y, - this.x ) + Math.PI; + return angle; + } - distanceTo(v) { - return Math.sqrt(this.distanceToSquared(v)); + distanceTo( v ) { + + return Math.sqrt( this.distanceToSquared( v ) ); + } - distanceToSquared(v) { - const dx = this.x - v.x, - dy = this.y - v.y; + distanceToSquared( v ) { + + const dx = this.x - v.x, 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); + manhattanDistanceTo( v ) { + + return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ); + } - setLength(length) { - return this.normalize().multiplyScalar(length); + setLength( length ) { + + return this.normalize().multiplyScalar( length ); + } - lerp(v, alpha) { - this.x += (v.x - this.x) * alpha; - this.y += (v.y - this.y) * alpha; + 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; + 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; + equals( v ) { + + return ( ( v.x === this.x ) && ( v.y === this.y ) ); + } - fromArray(array, offset = 0) { - this.x = array[offset]; - this.y = array[offset + 1]; + 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; + toArray( array = [], offset = 0 ) { + + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + return array; + } - fromBufferAttribute(attribute, index, offset) { - if (offset !== undefined) { - console.warn('THREE.Vector2: offset has been removed from .fromBufferAttribute().'); - } + fromBufferAttribute( attribute, index ) { + + this.x = attribute.getX( index ); + this.y = attribute.getY( 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); + rotateAround( center, angle ) { + + const c = Math.cos( 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]() { + *[ Symbol.iterator ]() { + yield this.x; yield this.y; + } } class Matrix3 { + constructor() { - this.isMatrix3 = true; - this.elements = [1, 0, 0, 0, 1, 0, 0, 0, 1]; - if (arguments.length > 0) { - console.error('THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.'); - } + 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) { + set( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { + const te = this.elements; - te[0] = n11; - te[1] = n21; - te[2] = n31; - te[3] = n12; - te[4] = n22; - te[5] = n32; - te[6] = n13; - te[7] = n23; - te[8] = n33; + + te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; + te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; + te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; + return this; + } identity() { - this.set(1, 0, 0, 0, 1, 0, 0, 0, 1); + + this.set( + + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 + + ); + return this; + } - copy(m) { + copy( m ) { + const te = this.elements; const me = m.elements; - te[0] = me[0]; - te[1] = me[1]; - te[2] = me[2]; - te[3] = me[3]; - te[4] = me[4]; - te[5] = me[5]; - te[6] = me[6]; - te[7] = me[7]; - te[8] = me[8]; + + te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; + te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; + te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ]; + return this; + } - extractBasis(xAxis, yAxis, zAxis) { - xAxis.setFromMatrix3Column(this, 0); - yAxis.setFromMatrix3Column(this, 1); - zAxis.setFromMatrix3Column(this, 2); + extractBasis( xAxis, yAxis, zAxis ) { + + xAxis.setFromMatrix3Column( this, 0 ); + yAxis.setFromMatrix3Column( this, 1 ); + zAxis.setFromMatrix3Column( this, 2 ); + return this; + } - setFromMatrix4(m) { + 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]); + + 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); + multiply( m ) { + + return this.multiplyMatrices( this, m ); + } - premultiply(m) { - return this.multiplyMatrices(m, this); + premultiply( m ) { + + return this.multiplyMatrices( m, this ); + } - multiplyMatrices(a, b) { + multiplyMatrices( a, b ) { + const ae = a.elements; const be = b.elements; const te = this.elements; - const a11 = ae[0], - a12 = ae[3], - a13 = ae[6]; - const a21 = ae[1], - a22 = ae[4], - a23 = ae[7]; - const a31 = ae[2], - a32 = ae[5], - a33 = ae[8]; - const b11 = be[0], - b12 = be[3], - b13 = be[6]; - const b21 = be[1], - b22 = be[4], - b23 = be[7]; - const b31 = be[2], - b32 = be[5], - b33 = be[8]; - te[0] = a11 * b11 + a12 * b21 + a13 * b31; - te[3] = a11 * b12 + a12 * b22 + a13 * b32; - te[6] = a11 * b13 + a12 * b23 + a13 * b33; - te[1] = a21 * b11 + a22 * b21 + a23 * b31; - te[4] = a21 * b12 + a22 * b22 + a23 * b32; - te[7] = a21 * b13 + a22 * b23 + a23 * b33; - te[2] = a31 * b11 + a32 * b21 + a33 * b31; - te[5] = a31 * b12 + a32 * b22 + a33 * b32; - te[8] = a31 * b13 + a32 * b23 + a33 * b33; - return this; - } - - multiplyScalar(s) { + + const a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; + const a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; + const a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; + + const b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; + const b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; + const b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; + + te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; + te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; + te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; + + te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; + te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; + te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; + + te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; + te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; + te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; + + return this; + + } + + multiplyScalar( s ) { + const te = this.elements; - te[0] *= s; - te[3] *= s; - te[6] *= s; - te[1] *= s; - te[4] *= s; - te[7] *= s; - te[2] *= s; - te[5] *= s; - te[8] *= s; + + te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; + te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; + te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; + return this; + } determinant() { + const te = this.elements; - const a = te[0], - b = te[1], - c = te[2], - d = te[3], - e = te[4], - f = te[5], - g = te[6], - h = te[7], - i = te[8]; + + const a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], + d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], + g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; + return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; + } invert() { + const te = this.elements, - n11 = te[0], - n21 = te[1], - n31 = te[2], - n12 = te[3], - n22 = te[4], - n32 = te[5], - n13 = te[6], - n23 = te[7], - n33 = te[8], - t11 = n33 * n22 - n32 * n23, - t12 = n32 * n13 - n33 * n12, - t13 = n23 * n12 - n22 * n13, - det = n11 * t11 + n21 * t12 + n31 * t13; - if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0); + + n11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ], + n12 = te[ 3 ], n22 = te[ 4 ], n32 = te[ 5 ], + n13 = te[ 6 ], n23 = te[ 7 ], n33 = te[ 8 ], + + t11 = n33 * n22 - n32 * n23, + t12 = n32 * n13 - n33 * n12, + t13 = n23 * n12 - n22 * n13, + + det = n11 * t11 + n21 * t12 + n31 * t13; + + if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + const detInv = 1 / det; - te[0] = t11 * detInv; - te[1] = (n31 * n23 - n33 * n21) * detInv; - te[2] = (n32 * n21 - n31 * n22) * detInv; - te[3] = t12 * detInv; - te[4] = (n33 * n11 - n31 * n13) * detInv; - te[5] = (n31 * n12 - n32 * n11) * detInv; - te[6] = t13 * detInv; - te[7] = (n21 * n13 - n23 * n11) * detInv; - te[8] = (n22 * n11 - n21 * n12) * detInv; + + te[ 0 ] = t11 * detInv; + te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; + te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; + + te[ 3 ] = t12 * detInv; + te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; + te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; + + te[ 6 ] = t13 * detInv; + te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; + te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; + return this; + } transpose() { + let tmp; const m = this.elements; - tmp = m[1]; - m[1] = m[3]; - m[3] = tmp; - tmp = m[2]; - m[2] = m[6]; - m[6] = tmp; - tmp = m[5]; - m[5] = m[7]; - m[7] = tmp; + + tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; + tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; + tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; + return this; + } - getNormalMatrix(matrix4) { - return this.setFromMatrix4(matrix4).invert().transpose(); + getNormalMatrix( matrix4 ) { + + return this.setFromMatrix4( matrix4 ).invert().transpose(); + } - transposeIntoArray(r) { + transposeIntoArray( r ) { + const m = this.elements; - r[0] = m[0]; - r[1] = m[3]; - r[2] = m[6]; - r[3] = m[1]; - r[4] = m[4]; - r[5] = m[7]; - r[6] = m[2]; - r[7] = m[5]; - r[8] = m[8]; + + r[ 0 ] = m[ 0 ]; + r[ 1 ] = m[ 3 ]; + r[ 2 ] = m[ 6 ]; + r[ 3 ] = m[ 1 ]; + r[ 4 ] = m[ 4 ]; + r[ 5 ] = m[ 7 ]; + r[ 6 ] = m[ 2 ]; + r[ 7 ] = m[ 5 ]; + r[ 8 ] = m[ 8 ]; + return this; + } - setUvTransform(tx, ty, sx, sy, rotation, cx, cy) { - const c = Math.cos(rotation); - const s = Math.sin(rotation); - this.set(sx * c, sx * s, -sx * (c * cx + s * cy) + cx + tx, -sy * s, sy * c, -sy * (-s * cx + c * cy) + cy + ty, 0, 0, 1); + setUvTransform( tx, ty, sx, sy, rotation, cx, cy ) { + + const c = Math.cos( rotation ); + const s = Math.sin( rotation ); + + this.set( + sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, + - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, + 0, 0, 1 + ); + return this; + } - scale(sx, sy) { - const te = this.elements; - te[0] *= sx; - te[3] *= sx; - te[6] *= sx; - te[1] *= sy; - te[4] *= sy; - te[7] *= sy; + // + + scale( sx, sy ) { + + this.premultiply( _m3.makeScale( sx, sy ) ); + return this; + } - rotate(theta) { - const c = Math.cos(theta); - const s = Math.sin(theta); - const te = this.elements; - const a11 = te[0], - a12 = te[3], - a13 = te[6]; - const a21 = te[1], - a22 = te[4], - a23 = te[7]; - te[0] = c * a11 + s * a21; - te[3] = c * a12 + s * a22; - te[6] = c * a13 + s * a23; - te[1] = -s * a11 + c * a21; - te[4] = -s * a12 + c * a22; - te[7] = -s * a13 + c * a23; - return this; - } - - translate(tx, ty) { - const te = this.elements; - te[0] += tx * te[2]; - te[3] += tx * te[5]; - te[6] += tx * te[8]; - te[1] += ty * te[2]; - te[4] += ty * te[5]; - te[7] += ty * te[8]; + 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 ); + + this.set( + + c, - s, 0, + s, c, 0, + 0, 0, 1 + + ); + + return this; + + } + + makeScale( x, y ) { + + this.set( + + x, 0, 0, + 0, y, 0, + 0, 0, 1 + + ); + return this; + } - equals(matrix) { + // + + equals( matrix ) { + const te = this.elements; const me = matrix.elements; - for (let i = 0; i < 9; i++) { - if (te[i] !== me[i]) return false; + 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]; + fromArray( array, offset = 0 ) { + + for ( let i = 0; i < 9; i ++ ) { + + this.elements[ i ] = array[ i + offset ]; + } return this; + } - toArray(array = [], offset = 0) { + toArray( array = [], offset = 0 ) { + const te = this.elements; - array[offset] = te[0]; - array[offset + 1] = te[1]; - array[offset + 2] = te[2]; - array[offset + 3] = te[3]; - array[offset + 4] = te[4]; - array[offset + 5] = te[5]; - array[offset + 6] = te[6]; - array[offset + 7] = te[7]; - array[offset + 8] = te[8]; + + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; + + array[ offset + 3 ] = te[ 3 ]; + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; + + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; + array[ offset + 8 ] = te[ 8 ]; + return array; + } clone() { - return new this.constructor().fromArray(this.elements); + + return new this.constructor().fromArray( this.elements ); + } } - function arrayNeedsUint32(array) { + 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; + + for ( let i = array.length - 1; i >= 0; -- i ) { + + if ( array[ i ] >= 65535 ) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 + } return false; + } const TYPED_ARRAYS = { @@ -1125,636 +1457,685 @@ Float64Array: Float64Array }; - function getTypedArray(type, buffer) { - return new TYPED_ARRAYS[type](buffer); + function getTypedArray( type, buffer ) { + + return new TYPED_ARRAYS[ type ]( buffer ); + + } + + function createElementNS( name ) { + + return document.createElementNS( 'http://www.w3.org/1999/xhtml', name ); + } - function createElementNS(name) { - return document.createElementNS('http://www.w3.org/1999/xhtml', name); + function SRGBToLinear( c ) { + + return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 ); + } - function SRGBToLinear(c) { - return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4); + function LinearToSRGB( c ) { + + return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055; + } - 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 - }, - [LinearSRGBColorSpace]: { - [SRGBColorSpace]: LinearToSRGB - } + [ SRGBColorSpace ]: { [ LinearSRGBColorSpace ]: SRGBToLinear }, + [ LinearSRGBColorSpace ]: { [ SRGBColorSpace ]: LinearToSRGB }, }; + const ColorManagement = { + legacyMode: true, get workingColorSpace() { + return LinearSRGBColorSpace; + }, - set workingColorSpace(colorSpace) { - console.warn('THREE.ColorManagement: .workingColorSpace is readonly.'); + set workingColorSpace( colorSpace ) { + + console.warn( 'THREE.ColorManagement: .workingColorSpace is readonly.' ); + }, - convert: function (color, sourceColorSpace, targetColorSpace) { - if (this.legacyMode || sourceColorSpace === targetColorSpace || !sourceColorSpace || !targetColorSpace) { + 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); - color.g = fn(color.g); - color.b = fn(color.b); + if ( FN[ sourceColorSpace ] && FN[ sourceColorSpace ][ targetColorSpace ] !== undefined ) { + + const fn = FN[ sourceColorSpace ][ targetColorSpace ]; + + color.r = fn( color.r ); + color.g = fn( color.g ); + color.b = fn( color.b ); + return color; + } - throw new Error('Unsupported color space conversion.'); + throw new Error( 'Unsupported color space conversion.' ); + }, - fromWorkingColorSpace: function (color, targetColorSpace) { - return this.convert(color, this.workingColorSpace, targetColorSpace); + + fromWorkingColorSpace: function ( color, targetColorSpace ) { + + return this.convert( color, this.workingColorSpace, targetColorSpace ); + + }, + + toWorkingColorSpace: function ( color, sourceColorSpace ) { + + return this.convert( color, sourceColorSpace, this.workingColorSpace ); + }, - toWorkingColorSpace: function (color, sourceColorSpace) { - return this.convert(color, sourceColorSpace, this.workingColorSpace); - } - }; - const _colorKeywords = { - 'aliceblue': 0xF0F8FF, - 'antiquewhite': 0xFAEBD7, - 'aqua': 0x00FFFF, - 'aquamarine': 0x7FFFD4, - 'azure': 0xF0FFFF, - 'beige': 0xF5F5DC, - 'bisque': 0xFFE4C4, - 'black': 0x000000, - 'blanchedalmond': 0xFFEBCD, - 'blue': 0x0000FF, - 'blueviolet': 0x8A2BE2, - 'brown': 0xA52A2A, - 'burlywood': 0xDEB887, - 'cadetblue': 0x5F9EA0, - 'chartreuse': 0x7FFF00, - 'chocolate': 0xD2691E, - 'coral': 0xFF7F50, - 'cornflowerblue': 0x6495ED, - 'cornsilk': 0xFFF8DC, - 'crimson': 0xDC143C, - 'cyan': 0x00FFFF, - 'darkblue': 0x00008B, - 'darkcyan': 0x008B8B, - 'darkgoldenrod': 0xB8860B, - 'darkgray': 0xA9A9A9, - 'darkgreen': 0x006400, - 'darkgrey': 0xA9A9A9, - 'darkkhaki': 0xBDB76B, - 'darkmagenta': 0x8B008B, - 'darkolivegreen': 0x556B2F, - 'darkorange': 0xFF8C00, - 'darkorchid': 0x9932CC, - 'darkred': 0x8B0000, - 'darksalmon': 0xE9967A, - 'darkseagreen': 0x8FBC8F, - 'darkslateblue': 0x483D8B, - 'darkslategray': 0x2F4F4F, - 'darkslategrey': 0x2F4F4F, - 'darkturquoise': 0x00CED1, - 'darkviolet': 0x9400D3, - 'deeppink': 0xFF1493, - 'deepskyblue': 0x00BFFF, - 'dimgray': 0x696969, - 'dimgrey': 0x696969, - 'dodgerblue': 0x1E90FF, - 'firebrick': 0xB22222, - 'floralwhite': 0xFFFAF0, - 'forestgreen': 0x228B22, - 'fuchsia': 0xFF00FF, - 'gainsboro': 0xDCDCDC, - 'ghostwhite': 0xF8F8FF, - 'gold': 0xFFD700, - 'goldenrod': 0xDAA520, - 'gray': 0x808080, - 'green': 0x008000, - 'greenyellow': 0xADFF2F, - 'grey': 0x808080, - 'honeydew': 0xF0FFF0, - 'hotpink': 0xFF69B4, - 'indianred': 0xCD5C5C, - 'indigo': 0x4B0082, - 'ivory': 0xFFFFF0, - 'khaki': 0xF0E68C, - 'lavender': 0xE6E6FA, - 'lavenderblush': 0xFFF0F5, - 'lawngreen': 0x7CFC00, - 'lemonchiffon': 0xFFFACD, - 'lightblue': 0xADD8E6, - 'lightcoral': 0xF08080, - 'lightcyan': 0xE0FFFF, - 'lightgoldenrodyellow': 0xFAFAD2, - 'lightgray': 0xD3D3D3, - 'lightgreen': 0x90EE90, - 'lightgrey': 0xD3D3D3, - 'lightpink': 0xFFB6C1, - 'lightsalmon': 0xFFA07A, - 'lightseagreen': 0x20B2AA, - 'lightskyblue': 0x87CEFA, - 'lightslategray': 0x778899, - 'lightslategrey': 0x778899, - 'lightsteelblue': 0xB0C4DE, - 'lightyellow': 0xFFFFE0, - 'lime': 0x00FF00, - 'limegreen': 0x32CD32, - 'linen': 0xFAF0E6, - 'magenta': 0xFF00FF, - 'maroon': 0x800000, - 'mediumaquamarine': 0x66CDAA, - 'mediumblue': 0x0000CD, - 'mediumorchid': 0xBA55D3, - 'mediumpurple': 0x9370DB, - 'mediumseagreen': 0x3CB371, - 'mediumslateblue': 0x7B68EE, - 'mediumspringgreen': 0x00FA9A, - 'mediumturquoise': 0x48D1CC, - 'mediumvioletred': 0xC71585, - 'midnightblue': 0x191970, - 'mintcream': 0xF5FFFA, - 'mistyrose': 0xFFE4E1, - 'moccasin': 0xFFE4B5, - 'navajowhite': 0xFFDEAD, - 'navy': 0x000080, - 'oldlace': 0xFDF5E6, - 'olive': 0x808000, - 'olivedrab': 0x6B8E23, - 'orange': 0xFFA500, - 'orangered': 0xFF4500, - 'orchid': 0xDA70D6, - 'palegoldenrod': 0xEEE8AA, - 'palegreen': 0x98FB98, - 'paleturquoise': 0xAFEEEE, - 'palevioletred': 0xDB7093, - 'papayawhip': 0xFFEFD5, - 'peachpuff': 0xFFDAB9, - 'peru': 0xCD853F, - 'pink': 0xFFC0CB, - 'plum': 0xDDA0DD, - 'powderblue': 0xB0E0E6, - 'purple': 0x800080, - 'rebeccapurple': 0x663399, - 'red': 0xFF0000, - 'rosybrown': 0xBC8F8F, - 'royalblue': 0x4169E1, - 'saddlebrown': 0x8B4513, - 'salmon': 0xFA8072, - 'sandybrown': 0xF4A460, - 'seagreen': 0x2E8B57, - 'seashell': 0xFFF5EE, - 'sienna': 0xA0522D, - 'silver': 0xC0C0C0, - 'skyblue': 0x87CEEB, - 'slateblue': 0x6A5ACD, - 'slategray': 0x708090, - 'slategrey': 0x708090, - 'snow': 0xFFFAFA, - 'springgreen': 0x00FF7F, - 'steelblue': 0x4682B4, - 'tan': 0xD2B48C, - 'teal': 0x008080, - 'thistle': 0xD8BFD8, - 'tomato': 0xFF6347, - 'turquoise': 0x40E0D0, - 'violet': 0xEE82EE, - 'wheat': 0xF5DEB3, - 'white': 0xFFFFFF, - 'whitesmoke': 0xF5F5F5, - 'yellow': 0xFFFF00, - 'yellowgreen': 0x9ACD32 - }; - const _rgb = { - r: 0, - g: 0, - b: 0 - }; - const _hslA = { - h: 0, - s: 0, - l: 0 - }; - const _hslB = { - h: 0, - s: 0, - l: 0 }; - function hue2rgb(p, q, t) { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t); + const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, + 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, + 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, + 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, + 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, + 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, + 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, + 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, + 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, + 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, + 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, + 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, + 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, + 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, + 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, + 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, + 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, + 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, + 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, + 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, + 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, + 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, + 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, + 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; + + 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 }; + + function hue2rgb( p, q, t ) { + + if ( t < 0 ) t += 1; + if ( t > 1 ) t -= 1; + if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; + if ( t < 1 / 2 ) return q; + if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); return p; + } - function toComponents(source, target) { + function toComponents( source, target ) { + target.r = source.r; target.g = source.g; target.b = source.b; + return target; + } class Color { - constructor(r, g, b) { + + constructor( r, g, b ) { + this.isColor = true; + this.r = 1; this.g = 1; this.b = 1; - if (g === undefined && b === undefined) { + if ( g === undefined && b === undefined ) { + // r is THREE.Color, hex or string - return this.set(r); + return this.set( r ); + } - return this.setRGB(r, g, b); + return this.setRGB( r, g, b ); + } - set(value) { - if (value && value.isColor) { - this.copy(value); - } else if (typeof value === 'number') { - this.setHex(value); - } else if (typeof value === 'string') { - this.setStyle(value); + set( value ) { + + if ( value && value.isColor ) { + + this.copy( value ); + + } else if ( typeof value === 'number' ) { + + this.setHex( value ); + + } else if ( typeof value === 'string' ) { + + this.setStyle( value ); + } return this; + } - setScalar(scalar) { + 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; - this.g = (hex >> 8 & 255) / 255; - this.b = (hex & 255) / 255; - ColorManagement.toWorkingColorSpace(this, colorSpace); + setHex( hex, colorSpace = SRGBColorSpace ) { + + hex = Math.floor( hex ); + + this.r = ( hex >> 16 & 255 ) / 255; + this.g = ( hex >> 8 & 255 ) / 255; + this.b = ( hex & 255 ) / 255; + + 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); + + 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); + h = euclideanModulo( h, 1 ); + s = clamp( s, 0, 1 ); + l = clamp( l, 0, 1 ); + + if ( s === 0 ) { - if (s === 0) { this.r = this.g = this.b = l; + } else { - const p = l <= 0.5 ? l * (1 + s) : l + s - l * s; - const q = 2 * l - p; - this.r = hue2rgb(q, p, h + 1 / 3); - this.g = hue2rgb(q, p, h); - this.b = hue2rgb(q, p, h - 1 / 3); + + const p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); + const q = ( 2 * l ) - p; + + this.r = hue2rgb( q, p, h + 1 / 3 ); + this.g = hue2rgb( q, p, h ); + this.b = hue2rgb( q, p, h - 1 / 3 ); + } - ColorManagement.toWorkingColorSpace(this, colorSpace); + ColorManagement.toWorkingColorSpace( this, colorSpace ); + return this; + } - setStyle(style, colorSpace = SRGBColorSpace) { - function handleAlpha(string) { - if (string === undefined) return; + 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.' ); - if (parseFloat(string) < 1) { - console.warn('THREE.Color: Alpha component of ' + style + ' will be ignored.'); } + } + let m; - if (m = /^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec(style)) { + if ( m = /^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec( style ) ) { + // rgb / hsl + let color; - const name = m[1]; - const components = m[2]; + const name = m[ 1 ]; + const components = m[ 2 ]; + + switch ( name ) { - switch (name) { case 'rgb': case 'rgba': - if (color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { + + if ( color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { + // rgb(255,0,0) rgba(255,0,0,0.5) - this.r = Math.min(255, parseInt(color[1], 10)) / 255; - this.g = Math.min(255, parseInt(color[2], 10)) / 255; - this.b = Math.min(255, parseInt(color[3], 10)) / 255; - ColorManagement.toWorkingColorSpace(this, colorSpace); - handleAlpha(color[4]); + this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255; + this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255; + this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255; + + ColorManagement.toWorkingColorSpace( this, colorSpace ); + + handleAlpha( color[ 4 ] ); + return this; + } - if (color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { + 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; - this.g = Math.min(100, parseInt(color[2], 10)) / 100; - this.b = Math.min(100, parseInt(color[3], 10)) / 100; - ColorManagement.toWorkingColorSpace(this, colorSpace); - handleAlpha(color[4]); + this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100; + this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100; + this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100; + + ColorManagement.toWorkingColorSpace( this, colorSpace ); + + 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; - handleAlpha(color[4]); - return this.setHSL(h, s, l, colorSpace); + const h = parseFloat( color[ 1 ] ) / 360; + 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)) { + + } else if ( m = /^\#([A-Fa-f\d]+)$/.exec( style ) ) { + // hex color - const hex = m[1]; + + const hex = m[ 1 ]; const size = hex.length; - if (size === 3) { + if ( size === 3 ) { + // #ff0 - this.r = parseInt(hex.charAt(0) + hex.charAt(0), 16) / 255; - this.g = parseInt(hex.charAt(1) + hex.charAt(1), 16) / 255; - this.b = parseInt(hex.charAt(2) + hex.charAt(2), 16) / 255; - ColorManagement.toWorkingColorSpace(this, colorSpace); + this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255; + this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255; + this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255; + + ColorManagement.toWorkingColorSpace( this, colorSpace ); + return this; - } else if (size === 6) { + + } else if ( size === 6 ) { + // #ff0000 - this.r = parseInt(hex.charAt(0) + hex.charAt(1), 16) / 255; - this.g = parseInt(hex.charAt(2) + hex.charAt(3), 16) / 255; - this.b = parseInt(hex.charAt(4) + hex.charAt(5), 16) / 255; - ColorManagement.toWorkingColorSpace(this, colorSpace); + this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255; + this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255; + this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255; + + ColorManagement.toWorkingColorSpace( this, colorSpace ); + return this; + } + } - if (style && style.length > 0) { - return this.setColorName(style, colorSpace); + if ( style && style.length > 0 ) { + + return this.setColorName( style, colorSpace ); + } return this; + } - setColorName(style, colorSpace = SRGBColorSpace) { + setColorName( style, colorSpace = SRGBColorSpace ) { + // color keywords - const hex = _colorKeywords[style.toLowerCase()]; + const hex = _colorKeywords[ style.toLowerCase() ]; + + if ( hex !== undefined ) { - if (hex !== undefined) { // red - this.setHex(hex, colorSpace); + this.setHex( hex, colorSpace ); + } else { + // unknown color - console.warn('THREE.Color: Unknown color ' + style); + console.warn( 'THREE.Color: Unknown color ' + style ); + } return this; + } clone() { - return new this.constructor(this.r, this.g, this.b); + + return new this.constructor( this.r, this.g, this.b ); + } - copy(color) { + 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); + 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); + copyLinearToSRGB( color ) { + + this.r = LinearToSRGB( color.r ); + this.g = LinearToSRGB( color.g ); + this.b = LinearToSRGB( color.b ); + return this; + } convertSRGBToLinear() { - this.copySRGBToLinear(this); + + this.copySRGBToLinear( this ); + return this; + } convertLinearToSRGB() { - this.copyLinearToSRGB(this); + + 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; + getHex( colorSpace = SRGBColorSpace ) { + + 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); + 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; - const max = Math.max(r, g, b); - const min = Math.min(r, g, 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; + const lightness = ( min + max ) / 2.0; + + if ( min === max ) { - 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; + saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); - case g: - hue = (b - r) / delta + 2; - break; + 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; - 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); + getStyle( colorSpace = SRGBColorSpace ) { + + ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb$1 ), colorSpace ); + + if ( colorSpace !== SRGBColorSpace ) { - 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; - _hslA.s += s; - _hslA.l += l; - this.setHSL(_hslA.h, _hslA.s, _hslA.l); + offsetHSL( h, s, l ) { + + this.getHSL( _hslA ); + + _hslA.h += h; _hslA.s += s; _hslA.l += l; + + this.setHSL( _hslA.h, _hslA.s, _hslA.l ); + return this; + } - add(color) { + add( color ) { + this.r += color.r; this.g += color.g; this.b += color.b; + return this; + } - addColors(color1, color2) { + 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) { + 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); + 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) { + multiply( color ) { + this.r *= color.r; this.g *= color.g; this.b *= color.b; + return this; + } - multiplyScalar(s) { + 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; + 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; + 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); - const h = lerp(_hslA.h, _hslB.h, alpha); - const s = lerp(_hslA.s, _hslB.s, alpha); - const l = lerp(_hslA.l, _hslB.l, alpha); - this.setHSL(h, s, l); + lerpHSL( color, alpha ) { + + this.getHSL( _hslA ); + color.getHSL( _hslB ); + + const h = lerp( _hslA.h, _hslB.h, alpha ); + const s = lerp( _hslA.s, _hslB.s, alpha ); + const l = lerp( _hslA.l, _hslB.l, alpha ); + + this.setHSL( h, s, l ); + return this; + } - equals(c) { - return c.r === this.r && c.g === this.g && c.b === this.b; + 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]; + 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; + 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); + fromBufferAttribute( attribute, index ) { - if (attribute.normalized === true) { - // assuming Uint8Array - this.r /= 255; - this.g /= 255; - this.b /= 255; - } + this.r = attribute.getX( index ); + this.g = attribute.getY( index ); + this.b = attribute.getZ( index ); return this; + } toJSON() { + return this.getHex(); + } - *[Symbol.iterator]() { + *[ Symbol.iterator ]() { + yield this.r; yield this.g; yield this.b; + } } @@ -1764,69 +2145,109 @@ let _canvas; class ImageUtils { - static getDataURL(image) { - if (/^data:/i.test(image.src)) { + + static getDataURL( image ) { + + if ( /^data:/i.test( image.src ) ) { + return image.src; + } - if (typeof HTMLCanvasElement == 'undefined') { + if ( typeof HTMLCanvasElement == 'undefined' ) { + return image.src; + } let canvas; - if (image instanceof HTMLCanvasElement) { + if ( image instanceof HTMLCanvasElement ) { + canvas = image; + } else { - if (_canvas === undefined) _canvas = createElementNS('canvas'); + + if ( _canvas === undefined ) _canvas = createElementNS( 'canvas' ); + _canvas.width = image.width; _canvas.height = image.height; - const context = _canvas.getContext('2d'); + const context = _canvas.getContext( '2d' ); + + if ( image instanceof ImageData ) { + + context.putImageData( image, 0, 0 ); - if (image instanceof ImageData) { - context.putImageData(image, 0, 0); } else { - context.drawImage(image, 0, 0, image.width, image.height); + + 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); + 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 ); + } else { - return canvas.toDataURL('image/png'); + + 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'); + 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' ); + canvas.width = image.width; canvas.height = image.height; - const context = canvas.getContext('2d'); - context.drawImage(image, 0, 0, image.width, image.height); - const imageData = context.getImageData(0, 0, image.width, image.height); + + const context = canvas.getContext( '2d' ); + 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; + for ( let i = 0; i < data.length; i ++ ) { + + data[ i ] = SRGBToLinear( data[ i ] / 255 ) * 255; + } - context.putImageData(imageData, 0, 0); + 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 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]); + + data[ i ] = SRGBToLinear( data[ i ] ); + } + } return { @@ -1834,782 +2255,1068 @@ width: image.width, height: image.height }; + } else { - console.warn('THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.'); + + console.warn( 'THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.' ); return image; + } + } } class Source { - constructor(data = null) { + + constructor( data = null ) { + this.isSource = true; + this.uuid = generateUUID(); + this.data = data; + this.version = 0; + } - set needsUpdate(value) { - if (value === true) this.version++; + set needsUpdate( value ) { + + if ( value === true ) this.version ++; + } - toJSON(meta) { - const isRootObject = meta === undefined || typeof meta === 'string'; + toJSON( meta ) { + + const isRootObject = ( meta === undefined || typeof meta === 'string' ); + + if ( ! isRootObject && meta.images[ this.uuid ] !== undefined ) { + + return meta.images[ this.uuid ]; - 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) { + if ( data !== null ) { + let url; - if (Array.isArray(data)) { + if ( Array.isArray( data ) ) { + // cube texture + url = []; - for (let i = 0, l = data.length; i < l; i++) { - if (data[i].isDataTexture) { - url.push(serializeImage(data[i].image)); + for ( let i = 0, l = data.length; i < l; i ++ ) { + + if ( data[ i ].isDataTexture ) { + + url.push( serializeImage( data[ i ].image ) ); + } else { - url.push(serializeImage(data[i])); + + url.push( serializeImage( data[ i ] ) ); + } + } + } else { + // texture - url = serializeImage(data); + + url = serializeImage( data ); + } output.url = url; + } - if (!isRootObject) { - meta.images[this.uuid] = output; + 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) { + 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); + + return ImageUtils.getDataURL( image ); + } else { - if (image.data) { + + if ( image.data ) { + // images of DataTexture + return { - data: Array.prototype.slice.call(image.data), + data: Array.from( image.data ), width: image.width, height: image.height, type: image.data.constructor.name }; + } else { - console.warn('THREE.Texture: Unable to serialize Texture.'); + + console.warn( 'THREE.Texture: Unable to serialize Texture.' ); return {}; + } + } + } 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', { - value: textureId++ - }); + + Object.defineProperty( this, 'id', { value: textureId ++ } ); + this.uuid = generateUUID(); + this.name = ''; - this.source = new Source(image); + + this.source = new Source( image ); this.mipmaps = []; + this.mapping = mapping; + this.wrapS = wrapS; this.wrapT = wrapT; + this.magFilter = magFilter; this.minFilter = minFilter; + this.anisotropy = anisotropy; + this.format = format; this.internalFormat = null; this.type = type; - this.offset = new Vector2(0, 0); - this.repeat = new Vector2(1, 1); - this.center = new Vector2(0, 0); + + this.offset = new Vector2( 0, 0 ); + this.repeat = new Vector2( 1, 1 ); + this.center = new Vector2( 0, 0 ); this.rotation = 0; + this.matrixAutoUpdate = true; this.matrix = new Matrix3(); + this.generateMipmaps = true; this.premultiplyAlpha = false; this.flipY = true; - this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) + 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.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; + } + + 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); + + 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); + + return new this.constructor().copy( this ); + } - copy(source) { + copy( source ) { + this.name = source.name; + this.source = source.source; - this.mipmaps = source.mipmaps.slice(0); + this.mipmaps = source.mipmaps.slice( 0 ); + this.mapping = source.mapping; + this.wrapS = source.wrapS; this.wrapT = source.wrapT; + this.magFilter = source.magFilter; this.minFilter = source.minFilter; + this.anisotropy = source.anisotropy; + this.format = source.format; this.internalFormat = source.internalFormat; this.type = source.type; - this.offset.copy(source.offset); - this.repeat.copy(source.repeat); - this.center.copy(source.center); + + this.offset.copy( source.offset ); + this.repeat.copy( source.repeat ); + this.center.copy( source.center ); this.rotation = source.rotation; + this.matrixAutoUpdate = source.matrixAutoUpdate; - this.matrix.copy(source.matrix); + this.matrix.copy( source.matrix ); + this.generateMipmaps = source.generateMipmaps; this.premultiplyAlpha = source.premultiplyAlpha; this.flipY = source.flipY; this.unpackAlignment = source.unpackAlignment; this.encoding = source.encoding; - this.userData = JSON.parse(JSON.stringify(source.userData)); + + this.userData = JSON.parse( JSON.stringify( source.userData ) ); + this.needsUpdate = true; + return this; + } - toJSON(meta) { - const isRootObject = meta === undefined || typeof meta === 'string'; + toJSON( meta ) { + + const isRootObject = ( meta === undefined || typeof meta === 'string' ); + + if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) { + + return meta.textures[ this.uuid ]; - if (!isRootObject && meta.textures[this.uuid] !== undefined) { - return meta.textures[this.uuid]; } const output = { + metadata: { version: 4.5, type: 'Texture', generator: 'Texture.toJSON' }, + uuid: this.uuid, name: this.name, - image: this.source.toJSON(meta).uuid, + + image: this.source.toJSON( meta ).uuid, + mapping: this.mapping, - repeat: [this.repeat.x, this.repeat.y], - offset: [this.offset.x, this.offset.y], - center: [this.center.x, this.center.y], + + repeat: [ this.repeat.x, this.repeat.y ], + offset: [ this.offset.x, this.offset.y ], + center: [ this.center.x, this.center.y ], rotation: this.rotation, - wrap: [this.wrapS, this.wrapT], + + wrap: [ this.wrapS, this.wrapT ], + format: this.format, type: this.type, encoding: this.encoding, + minFilter: this.minFilter, magFilter: this.magFilter, anisotropy: this.anisotropy, + flipY: this.flipY, + + generateMipmaps: this.generateMipmaps, premultiplyAlpha: this.premultiplyAlpha, unpackAlignment: this.unpackAlignment + }; - if (JSON.stringify(this.userData) !== '{}') output.userData = this.userData; - if (!isRootObject) { - meta.textures[this.uuid] = output; + if ( Object.keys( this.userData ).length > 0 ) output.userData = this.userData; + + if ( ! isRootObject ) { + + meta.textures[ this.uuid ] = output; + } return output; + } dispose() { - this.dispatchEvent({ - type: 'dispose' - }); + + this.dispatchEvent( { type: 'dispose' } ); + } - transformUv(uv) { - if (this.mapping !== UVMapping) return uv; - uv.applyMatrix3(this.matrix); + transformUv( uv ) { + + if ( this.mapping !== UVMapping ) return uv; + + uv.applyMatrix3( this.matrix ); + + if ( uv.x < 0 || uv.x > 1 ) { + + switch ( this.wrapS ) { - if (uv.x < 0 || uv.x > 1) { - switch (this.wrapS) { case RepeatWrapping: - uv.x = uv.x - Math.floor(uv.x); + + 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; + + 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); + + uv.x = uv.x - Math.floor( uv.x ); + } break; + } + } - if (uv.y < 0 || uv.y > 1) { - switch (this.wrapT) { + if ( uv.y < 0 || uv.y > 1 ) { + + switch ( this.wrapT ) { + case RepeatWrapping: - uv.y = uv.y - Math.floor(uv.y); + + 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; + + 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); + + uv.y = uv.y - Math.floor( uv.y ); + } break; + } + } - if (this.flipY) { + if ( this.flipY ) { + uv.y = 1 - uv.y; + } return uv; + } - set needsUpdate(value) { - if (value === true) { - this.version++; + 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) { - this.isVector4 = true; + + constructor( x = 0, y = 0, z = 0, w = 1 ) { + + Vector4.prototype.isVector4 = true; + this.x = x; this.y = y; this.z = z; this.w = w; + } get width() { + return this.z; + } - set width(value) { + set width( value ) { + this.z = value; + } get height() { + return this.w; + } - set height(value) { + set height( value ) { + this.w = value; + } - set(x, y, z, w) { + set( x, y, z, w ) { + this.x = x; this.y = y; this.z = z; this.w = w; + return this; + } - setScalar(scalar) { + setScalar( scalar ) { + this.x = scalar; this.y = scalar; this.z = scalar; this.w = scalar; + return this; + } - setX(x) { + setX( x ) { + this.x = x; + return this; + } - setY(y) { + setY( y ) { + this.y = y; + return this; + } - setZ(z) { + setZ( z ) { + this.z = z; + return this; + } - setW(w) { + setW( w ) { + this.w = w; + return this; - } - setComponent(index, value) { - switch (index) { - case 0: - this.x = value; - break; + } - case 1: - this.y = value; - break; + setComponent( index, value ) { - case 2: - this.z = value; - break; + switch ( index ) { - case 3: - this.w = value; - break; + 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 ); - 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; + getComponent( index ) { - case 2: - return this.z; + switch ( index ) { - case 3: - return this.w; + 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 ); - default: - throw new Error('index is out of range: ' + index); } + } clone() { - return new this.constructor(this.x, this.y, this.z, this.w); + + return new this.constructor( this.x, this.y, this.z, this.w ); + } - copy(v) { + copy( v ) { + this.x = v.x; this.y = v.y; this.z = v.z; - this.w = v.w !== undefined ? v.w : 1; + this.w = ( v.w !== undefined ) ? v.w : 1; + return this; + } - add(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.'); - return this.addVectors(v, w); - } + add( v ) { this.x += v.x; this.y += v.y; this.z += v.z; this.w += v.w; + return this; + } - addScalar(s) { + addScalar( s ) { + this.x += s; this.y += s; this.z += s; this.w += s; + return this; + } - addVectors(a, b) { + addVectors( a, b ) { + this.x = a.x + b.x; this.y = a.y + b.y; this.z = a.z + b.z; this.w = a.w + b.w; + return this; + } - addScaledVector(v, s) { + addScaledVector( v, s ) { + this.x += v.x * s; this.y += v.y * s; this.z += v.z * s; this.w += v.w * s; + return this; + } - sub(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.'); - return this.subVectors(v, w); - } + sub( v ) { this.x -= v.x; this.y -= v.y; this.z -= v.z; this.w -= v.w; + return this; + } - subScalar(s) { + subScalar( s ) { + this.x -= s; this.y -= s; this.z -= s; this.w -= s; + return this; + } - subVectors(a, b) { + subVectors( a, b ) { + this.x = a.x - b.x; this.y = a.y - b.y; this.z = a.z - b.z; this.w = a.w - b.w; + return this; + } - multiply(v) { + multiply( v ) { + this.x *= v.x; this.y *= v.y; this.z *= v.z; this.w *= v.w; + return this; + } - multiplyScalar(scalar) { + multiplyScalar( scalar ) { + this.x *= scalar; this.y *= scalar; this.z *= scalar; this.w *= scalar; + return this; + } - applyMatrix4(m) { - const x = this.x, - y = this.y, - z = this.z, - w = this.w; + applyMatrix4( m ) { + + const x = this.x, 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; - this.z = e[2] * x + e[6] * y + e[10] * z + e[14] * w; - this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w; + + this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; + this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; + this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; + this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; + return this; + } - divideScalar(scalar) { - return this.multiplyScalar(1 / scalar); + divideScalar( scalar ) { + + return this.multiplyScalar( 1 / scalar ); + } - setAxisAngleFromQuaternion(q) { + 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.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; this.z = 0; + } else { + this.x = q.x / s; this.y = q.y / s; this.z = q.z / s; + } return this; + } - setAxisAngleFromRotationMatrix(m) { + 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 + 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 ]; + + if ( ( Math.abs( m12 - m21 ) < epsilon ) && + ( Math.abs( m13 - m31 ) < epsilon ) && + ( Math.abs( m23 - m32 ) < epsilon ) ) { - 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]; - - 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) { + + 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); + + 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; - const yy = (m22 + 1) / 2; - const zz = (m33 + 1) / 2; - const xy = (m12 + m21) / 4; - const xz = (m13 + m31) / 4; - const yz = (m23 + m32) / 4; - - if (xx > yy && xx > zz) { + + const xx = ( m11 + 1 ) / 2; + const yy = ( m22 + 1 ) / 2; + const zz = ( m33 + 1 ) / 2; + 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) { + + if ( xx < epsilon ) { + x = 0; y = 0.707106781; z = 0.707106781; + } else { - x = Math.sqrt(xx); + + x = Math.sqrt( xx ); y = xy / x; z = xz / x; + } - } else if (yy > zz) { + + } else if ( yy > zz ) { + // m22 is the largest diagonal term - if (yy < epsilon) { + + if ( yy < epsilon ) { + x = 0.707106781; y = 0; z = 0.707106781; + } else { - y = Math.sqrt(yy); + + y = Math.sqrt( yy ); x = xy / y; z = yz / y; + } + } else { + // m33 is the largest diagonal term so base result on this - if (zz < epsilon) { + + if ( zz < epsilon ) { + x = 0.707106781; y = 0.707106781; z = 0; + } else { - z = Math.sqrt(zz); + + z = Math.sqrt( zz ); x = xz / z; y = yz / z; + } + } - this.set(x, y, z, angle); + 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 - 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; - if (Math.abs(s) < 0.001) s = 1; // prevent divide by zero, should not happen if matrix is orthogonal and should be + // prevent divide by zero, should not happen if matrix is orthogonal and should be // caught by singularity test above, but I've left it in just in case - this.x = (m32 - m23) / s; - this.y = (m13 - m31) / s; - this.z = (m21 - m12) / s; - this.w = Math.acos((m11 + m22 + m33 - 1) / 2); + this.x = ( m32 - m23 ) / s; + this.y = ( m13 - m31 ) / s; + this.z = ( m21 - m12 ) / s; + this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); + return this; + } - min(v) { - this.x = Math.min(this.x, v.x); - this.y = Math.min(this.y, v.y); - this.z = Math.min(this.z, v.z); - this.w = Math.min(this.w, v.w); + min( v ) { + + this.x = Math.min( this.x, v.x ); + this.y = Math.min( this.y, v.y ); + this.z = Math.min( this.z, v.z ); + this.w = Math.min( this.w, v.w ); + return this; + } - max(v) { - this.x = Math.max(this.x, v.x); - this.y = Math.max(this.y, v.y); - this.z = Math.max(this.z, v.z); - this.w = Math.max(this.w, v.w); + max( v ) { + + this.x = Math.max( this.x, v.x ); + this.y = Math.max( this.y, v.y ); + this.z = Math.max( this.z, v.z ); + this.w = Math.max( this.w, v.w ); + return this; + } - clamp(min, max) { + 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)); + + 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)); - this.z = Math.max(minVal, Math.min(maxVal, this.z)); - this.w = Math.max(minVal, Math.min(maxVal, this.w)); + clampScalar( minVal, maxVal ) { + + this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); + this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); + this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); + this.w = Math.max( minVal, Math.min( maxVal, this.w ) ); + return this; + } - clampLength(min, max) { + clampLength( min, max ) { + const length = this.length(); - return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, 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); - this.w = Math.floor(this.w); + + this.x = Math.floor( this.x ); + this.y = Math.floor( this.y ); + this.z = Math.floor( this.z ); + this.w = Math.floor( this.w ); + return this; + } ceil() { - this.x = Math.ceil(this.x); - this.y = Math.ceil(this.y); - this.z = Math.ceil(this.z); - this.w = Math.ceil(this.w); + + this.x = Math.ceil( this.x ); + this.y = Math.ceil( this.y ); + this.z = Math.ceil( this.z ); + this.w = Math.ceil( this.w ); + return this; + } round() { - this.x = Math.round(this.x); - this.y = Math.round(this.y); - this.z = Math.round(this.z); - this.w = Math.round(this.w); + + this.x = Math.round( this.x ); + this.y = Math.round( this.y ); + this.z = Math.round( this.z ); + this.w = Math.round( this.w ); + return this; + } roundToZero() { - this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x); - this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y); - this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z); - this.w = this.w < 0 ? Math.ceil(this.w) : Math.floor(this.w); + + this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); + this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); + this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); + this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); + return this; + } negate() { - this.x = -this.x; - this.y = -this.y; - this.z = -this.z; - this.w = -this.w; + + this.x = - this.x; + this.y = - this.y; + this.z = - this.z; + this.w = - this.w; + return this; + } - dot(v) { + 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); + + 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); + + 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); + return this.divideScalar( this.length() || 1 ); + } - lerp(v, alpha) { - this.x += (v.x - this.x) * alpha; - this.y += (v.y - this.y) * alpha; - this.z += (v.z - this.z) * alpha; - this.w += (v.w - this.w) * alpha; - return this; + setLength( length ) { + + return this.normalize().multiplyScalar( length ); + } - lerpVectors(v1, v2, alpha) { - this.x = v1.x + (v2.x - v1.x) * alpha; - this.y = v1.y + (v2.y - v1.y) * alpha; - this.z = v1.z + (v2.z - v1.z) * alpha; - this.w = v1.w + (v2.w - v1.w) * alpha; + lerp( v, alpha ) { + + this.x += ( v.x - this.x ) * alpha; + this.y += ( v.y - this.y ) * alpha; + this.z += ( v.z - this.z ) * alpha; + this.w += ( v.w - this.w ) * alpha; + return this; - } - 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]; - this.z = array[offset + 2]; - this.w = array[offset + 3]; + lerpVectors( v1, v2, alpha ) { + + this.x = v1.x + ( v2.x - v1.x ) * alpha; + this.y = v1.y + ( v2.y - v1.y ) * alpha; + this.z = v1.z + ( v2.z - v1.z ) * alpha; + this.w = v1.w + ( v2.w - v1.w ) * alpha; + return this; - } - toArray(array = [], offset = 0) { - array[offset] = this.x; - array[offset + 1] = this.y; - array[offset + 2] = this.z; - array[offset + 3] = this.w; - return array; } - fromBufferAttribute(attribute, index, offset) { - if (offset !== undefined) { - console.warn('THREE.Vector4: offset has been removed from .fromBufferAttribute().'); - } + 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 ]; + this.z = array[ offset + 2 ]; + this.w = array[ offset + 3 ]; + + return this; + + } + + toArray( array = [], offset = 0 ) { + + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + array[ offset + 2 ] = this.z; + array[ offset + 3 ] = this.w; + + return array; + + } + + fromBufferAttribute( attribute, index ) { + + this.x = attribute.getX( index ); + this.y = attribute.getY( index ); + this.z = attribute.getZ( index ); + this.w = attribute.getW( index ); + + return this; - this.x = attribute.getX(index); - this.y = attribute.getY(index); - this.z = attribute.getZ(index); - this.w = attribute.getW(index); - return this; } random() { + this.x = Math.random(); this.y = Math.random(); this.z = Math.random(); this.w = Math.random(); + return this; + } - *[Symbol.iterator]() { + *[ Symbol.iterator ]() { + yield this.x; yield this.y; yield this.z; yield this.w; + } } @@ -2619,111 +3326,149 @@ * 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; this.height = height; this.depth = 1; - this.scissor = new Vector4(0, 0, width, height); + + this.scissor = new Vector4( 0, 0, width, height ); this.scissorTest = false; - this.viewport = new Vector4(0, 0, width, height); - const image = { - width: width, - height: height, - depth: 1 - }; - this.texture = new Texture(image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); + + this.viewport = new Vector4( 0, 0, width, height ); + + const image = { width: width, height: height, depth: 1 }; + + this.texture = new Texture( image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); this.texture.isRenderTargetTexture = true; + this.texture.flipY = false; this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; this.texture.internalFormat = options.internalFormat !== undefined ? options.internalFormat : null; this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; + this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false; + this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; + this.samples = options.samples !== undefined ? options.samples : 0; + } - setSize(width, height, depth = 1) { - if (this.width !== width || this.height !== height || this.depth !== depth) { + setSize( width, height, depth = 1 ) { + + if ( this.width !== width || this.height !== height || this.depth !== depth ) { + this.width = width; this.height = height; this.depth = depth; + this.texture.image.width = width; this.texture.image.height = height; this.texture.image.depth = depth; + this.dispose(); + } - this.viewport.set(0, 0, width, height); - this.scissor.set(0, 0, width, height); + this.viewport.set( 0, 0, width, height ); + this.scissor.set( 0, 0, width, height ); + } clone() { - return new this.constructor().copy(this); + + return new this.constructor().copy( this ); + } - copy(source) { + copy( source ) { + this.width = source.width; this.height = source.height; this.depth = source.depth; - this.viewport.copy(source.viewport); + + 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 ); - const image = Object.assign({}, source.texture.image); - this.texture.source = new Source(image); this.depthBuffer = source.depthBuffer; this.stencilBuffer = source.stencilBuffer; - if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone(); + + if ( source.depthTexture !== null ) this.depthTexture = source.depthTexture.clone(); + this.samples = source.samples; + return this; + } dispose() { - this.dispatchEvent({ - type: 'dispose' - }); + + this.dispatchEvent( { type: 'dispose' } ); + } } class DataArrayTexture extends Texture { - constructor(data = null, width = 1, height = 1, depth = 1) { - super(null); + + constructor( data = null, width = 1, height = 1, depth = 1 ) { + + super( null ); + this.isDataArrayTexture = true; - this.image = { - data, - width, - height, - depth - }; + + this.image = { data, width, height, depth }; + this.magFilter = NearestFilter; this.minFilter = NearestFilter; + this.wrapR = ClampToEdgeWrapping; + this.generateMipmaps = false; this.flipY = false; this.unpackAlignment = 1; + } } class WebGLArrayRenderTarget extends WebGLRenderTarget { - constructor(width, height, depth) { - super(width, height); + + 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 = new DataArrayTexture( null, width, height, depth ); + this.texture.isRenderTargetTexture = true; + } } class Data3DTexture extends Texture { - constructor(data = null, width = 1, height = 1, depth = 1) { + + constructor( data = null, width = 1, height = 1, depth = 1 ) { + // We're going to add .setXXX() methods for setting properties later. // Users can still set in DataTexture3D directly. // @@ -2731,222 +3476,291 @@ // texture.anisotropy = 16; // // See #14839 - super(null); + + super( null ); + this.isData3DTexture = true; - this.image = { - data, - width, - height, - depth - }; + + this.image = { data, width, height, depth }; + this.magFilter = NearestFilter; this.minFilter = NearestFilter; + this.wrapR = ClampToEdgeWrapping; + this.generateMipmaps = false; this.flipY = false; this.unpackAlignment = 1; + } } class WebGL3DRenderTarget extends WebGLRenderTarget { - constructor(width, height, depth) { - super(width, height); + + 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 = new Data3DTexture( null, width, height, depth ); + this.texture.isRenderTargetTexture = true; + } } class WebGLMultipleRenderTargets extends WebGLRenderTarget { - constructor(width, height, count, options = {}) { - super(width, height, 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; + 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) { + 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; + 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); + this.viewport.set( 0, 0, width, height ); + this.scissor.set( 0, 0, width, height ); + return this; + } - copy(source) { + copy( source ) { + this.dispose(); + this.width = source.width; this.height = source.height; this.depth = source.depth; - this.viewport.set(0, 0, this.width, this.height); - this.scissor.set(0, 0, this.width, this.height); + + this.viewport.set( 0, 0, this.width, this.height ); + this.scissor.set( 0, 0, this.width, this.height ); + this.depthBuffer = source.depthBuffer; this.stencilBuffer = source.stencilBuffer; - if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone(); + + 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; + 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 { - constructor(x = 0, y = 0, z = 0, w = 1) { + + constructor( x = 0, y = 0, z = 0, w = 1 ) { + this.isQuaternion = true; + this._x = x; this._y = y; this._z = z; this._w = w; - } - static slerp(qa, qb, qm, t) { - console.warn('THREE.Quaternion: Static .slerp() has been deprecated. Use qm.slerpQuaternions( qa, qb, t ) instead.'); - return qm.slerpQuaternions(qa, qb, t); } - static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) { + static slerpFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { + // fuzz-free, array-based Quaternion SLERP operation - let x0 = src0[srcOffset0 + 0], - y0 = src0[srcOffset0 + 1], - z0 = src0[srcOffset0 + 2], - w0 = src0[srcOffset0 + 3]; - const x1 = src1[srcOffset1 + 0], - y1 = src1[srcOffset1 + 1], - z1 = src1[srcOffset1 + 2], - w1 = src1[srcOffset1 + 3]; - - if (t === 0) { - dst[dstOffset + 0] = x0; - dst[dstOffset + 1] = y0; - dst[dstOffset + 2] = z0; - dst[dstOffset + 3] = w0; + + let x0 = src0[ srcOffset0 + 0 ], + y0 = src0[ srcOffset0 + 1 ], + z0 = src0[ srcOffset0 + 2 ], + w0 = src0[ srcOffset0 + 3 ]; + + const x1 = src1[ srcOffset1 + 0 ], + y1 = src1[ srcOffset1 + 1 ], + z1 = src1[ srcOffset1 + 2 ], + w1 = src1[ srcOffset1 + 3 ]; + + if ( t === 0 ) { + + dst[ dstOffset + 0 ] = x0; + dst[ dstOffset + 1 ] = y0; + dst[ dstOffset + 2 ] = z0; + dst[ dstOffset + 3 ] = w0; return; + } - if (t === 1) { - dst[dstOffset + 0] = x1; - dst[dstOffset + 1] = y1; - dst[dstOffset + 2] = z1; - dst[dstOffset + 3] = w1; + if ( t === 1 ) { + + dst[ dstOffset + 0 ] = x1; + dst[ dstOffset + 1 ] = y1; + dst[ dstOffset + 2 ] = z1; + dst[ dstOffset + 3 ] = w1; return; + } - if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) { + 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 ); + + s = Math.sin( s * len ) / sin; + t = Math.sin( t * len ) / sin; - if (sqrSin > Number.EPSILON) { - const sin = Math.sqrt(sqrSin), - len = Math.atan2(sin, cos * dir); - s = Math.sin(s * len) / sin; - t = Math.sin(t * len) / sin; } const tDir = t * dir; + x0 = x0 * s + x1 * tDir; y0 = y0 * s + y1 * tDir; z0 = z0 * s + z1 * tDir; - w0 = w0 * s + w1 * tDir; // Normalize in case we just did a lerp: + 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 ); - if (s === 1 - t) { - const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0); x0 *= f; y0 *= f; z0 *= f; w0 *= f; + } + } - dst[dstOffset] = x0; - dst[dstOffset + 1] = y0; - dst[dstOffset + 2] = z0; - dst[dstOffset + 3] = w0; + dst[ dstOffset ] = x0; + dst[ dstOffset + 1 ] = y0; + dst[ dstOffset + 2 ] = z0; + dst[ dstOffset + 3 ] = w0; + } - static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) { - const x0 = src0[srcOffset0]; - const y0 = src0[srcOffset0 + 1]; - const z0 = src0[srcOffset0 + 2]; - const w0 = src0[srcOffset0 + 3]; - const x1 = src1[srcOffset1]; - const y1 = src1[srcOffset1 + 1]; - const z1 = src1[srcOffset1 + 2]; - const w1 = src1[srcOffset1 + 3]; - dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1; - dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1; - dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1; - dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1; + static multiplyQuaternionsFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1 ) { + + const x0 = src0[ srcOffset0 ]; + const y0 = src0[ srcOffset0 + 1 ]; + const z0 = src0[ srcOffset0 + 2 ]; + const w0 = src0[ srcOffset0 + 3 ]; + + const x1 = src1[ srcOffset1 ]; + const y1 = src1[ srcOffset1 + 1 ]; + const z1 = src1[ srcOffset1 + 2 ]; + const w1 = src1[ srcOffset1 + 3 ]; + + dst[ dstOffset ] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1; + dst[ dstOffset + 1 ] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1; + dst[ dstOffset + 2 ] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1; + dst[ dstOffset + 3 ] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1; + return dst; + } get x() { + return this._x; + } - set x(value) { - this._x = value; + set x( value ) { + this._x = value; this._onChangeCallback(); + } get y() { + return this._y; + } - set y(value) { - this._y = value; + set y( value ) { + this._y = value; this._onChangeCallback(); + } get z() { + return this._z; + } - set z(value) { - this._z = value; + set z( value ) { + this._z = value; this._onChangeCallback(); + } get w() { + return this._w; + } - set w(value) { - this._w = value; + set w( value ) { + this._w = value; this._onChangeCallback(); + } - set(x, y, z, w) { + set( x, y, z, w ) { + this._x = x; this._y = y; this._z = z; @@ -2955,13 +3769,17 @@ this._onChangeCallback(); return this; + } clone() { - return new this.constructor(this._x, this._y, this._z, this._w); + + return new this.constructor( this._x, this._y, this._z, this._w ); + } - copy(quaternion) { + copy( quaternion ) { + this._x = quaternion.x; this._y = quaternion.y; this._z = quaternion.z; @@ -2970,30 +3788,30 @@ 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.'); - } + setFromEuler( euler, update ) { + + const x = euler._x, y = euler._y, z = euler._z, order = euler._order; - const x = euler._x, - y = euler._y, - z = euler._z, - order = euler._order; // http://www.mathworks.com/matlabcentral/fileexchange/ + // http://www.mathworks.com/matlabcentral/fileexchange/ // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ // content/SpinCalc.m const cos = Math.cos; const sin = Math.sin; - const c1 = cos(x / 2); - const c2 = cos(y / 2); - const c3 = cos(z / 2); - const s1 = sin(x / 2); - const s2 = sin(y / 2); - const s3 = sin(z / 2); - - switch (order) { + + const c1 = cos( x / 2 ); + const c2 = cos( y / 2 ); + const c3 = cos( z / 2 ); + + const s1 = sin( x / 2 ); + const s2 = sin( y / 2 ); + const s3 = sin( z / 2 ); + + switch ( order ) { + case 'XYZ': this._x = s1 * c2 * c3 + c1 * s2 * s3; this._y = c1 * s2 * c3 - s1 * c2 * s3; @@ -3037,191 +3855,247 @@ break; default: - console.warn('THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order); + console.warn( 'THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order ); + } - if (update !== false) this._onChangeCallback(); + if ( update !== false ) this._onChangeCallback(); + return this; + } - setFromAxisAngle(axis, angle) { + 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); + + const halfAngle = angle / 2, s = Math.sin( halfAngle ); + this._x = axis.x * s; this._y = axis.y * s; this._z = axis.z * s; - this._w = Math.cos(halfAngle); + this._w = Math.cos( halfAngle ); this._onChangeCallback(); return this; + } - setFromRotationMatrix(m) { + setFromRotationMatrix( m ) { + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + const te = m.elements, - m11 = te[0], - m12 = te[4], - m13 = te[8], - m21 = te[1], - m22 = te[5], - m23 = te[9], - m31 = te[2], - m32 = te[6], - m33 = te[10], - trace = m11 + m22 + m33; - - if (trace > 0) { - const s = 0.5 / Math.sqrt(trace + 1.0); + + m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], + m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], + m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ], + + trace = m11 + m22 + m33; + + if ( trace > 0 ) { + + const s = 0.5 / Math.sqrt( trace + 1.0 ); + this._w = 0.25 / s; - this._x = (m32 - m23) * s; - this._y = (m13 - m31) * s; - this._z = (m21 - m12) * s; - } else if (m11 > m22 && m11 > m33) { - const s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33); - this._w = (m32 - m23) / s; + this._x = ( m32 - m23 ) * s; + this._y = ( m13 - m31 ) * s; + this._z = ( m21 - m12 ) * s; + + } else if ( m11 > m22 && m11 > m33 ) { + + const s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); + + this._w = ( m32 - m23 ) / s; this._x = 0.25 * s; - this._y = (m12 + m21) / s; - this._z = (m13 + m31) / s; - } else if (m22 > m33) { - const s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33); - this._w = (m13 - m31) / s; - this._x = (m12 + m21) / s; + this._y = ( m12 + m21 ) / s; + this._z = ( m13 + m31 ) / s; + + } else if ( m22 > m33 ) { + + const s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); + + this._w = ( m13 - m31 ) / s; + this._x = ( m12 + m21 ) / s; this._y = 0.25 * s; - this._z = (m23 + m32) / s; + this._z = ( m23 + m32 ) / s; + } else { - const s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22); - this._w = (m21 - m12) / s; - this._x = (m13 + m31) / s; - this._y = (m23 + m32) / s; + + const s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); + + this._w = ( m21 - m12 ) / s; + this._x = ( m13 + m31 ) / s; + this._y = ( m23 + m32 ) / s; this._z = 0.25 * s; + } this._onChangeCallback(); return this; + } - setFromUnitVectors(vFrom, vTo) { + setFromUnitVectors( vFrom, vTo ) { + // assumes direction vectors vFrom and vTo are normalized - let r = vFrom.dot(vTo) + 1; - if (r < Number.EPSILON) { + let r = vFrom.dot( vTo ) + 1; + + if ( r < Number.EPSILON ) { + // vFrom and vTo point in opposite directions + r = 0; - if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { - this._x = -vFrom.y; + if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { + + this._x = - vFrom.y; this._y = vFrom.x; this._z = 0; this._w = r; + } else { + this._x = 0; - this._y = -vFrom.z; + this._y = - vFrom.z; this._z = vFrom.y; this._w = r; + } + } else { + // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 + this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; this._w = r; + } return this.normalize(); + } - angleTo(q) { - return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1))); + angleTo( q ) { + + return 2 * Math.acos( Math.abs( clamp( this.dot( q ), - 1, 1 ) ) ); + } - rotateTowards(q, step) { - const angle = this.angleTo(q); - if (angle === 0) return this; - const t = Math.min(1, step / angle); - this.slerp(q, t); + rotateTowards( q, step ) { + + const angle = this.angleTo( q ); + + if ( angle === 0 ) return this; + + const t = Math.min( 1, step / angle ); + + this.slerp( q, t ); + return this; + } identity() { - return this.set(0, 0, 0, 1); + + 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._x *= - 1; + this._y *= - 1; + this._z *= - 1; this._onChangeCallback(); return this; + } - dot(v) { + 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); + + 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) { + if ( l === 0 ) { + this._x = 0; this._y = 0; this._z = 0; this._w = 1; + } else { + l = 1 / l; + this._x = this._x * l; this._y = this._y * l; this._z = this._z * l; this._w = this._w * l; + } this._onChangeCallback(); return this; + } - multiply(q, p) { - if (p !== undefined) { - console.warn('THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.'); - return this.multiplyQuaternions(q, p); - } + multiply( q ) { + + return this.multiplyQuaternions( this, q ); - return this.multiplyQuaternions(this, q); } - premultiply(q) { - return this.multiplyQuaternions(q, this); + premultiply( q ) { + + return this.multiplyQuaternions( q, this ); + } - multiplyQuaternions(a, b) { + multiplyQuaternions( a, b ) { + // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm - const qax = a._x, - qay = a._y, - qaz = a._z, - qaw = a._w; - const qbx = b._x, - qby = b._y, - qbz = b._z, - qbw = b._w; + + const qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; + const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; + this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; @@ -3230,8574 +4104,5674 @@ 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/ + slerp( qb, t ) { - let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; + if ( t === 0 ) return this; + if ( t === 1 ) return this.copy( qb ); - if (cosHalfTheta < 0) { - this._w = -qb._w; - this._x = -qb._x; - this._y = -qb._y; - this._z = -qb._z; - cosHalfTheta = -cosHalfTheta; - } else { - this.copy(qb); - } + const x = this._x, y = this._y, z = this._z, w = this._w; - if (cosHalfTheta >= 1.0) { - this._w = w; + // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + + let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; + + if ( cosHalfTheta < 0 ) { + + this._w = - qb._w; + this._x = - qb._x; + this._y = - qb._y; + this._z = - qb._z; + + cosHalfTheta = - cosHalfTheta; + + } else { + + this.copy( qb ); + + } + + if ( cosHalfTheta >= 1.0 ) { + + this._w = w; this._x = x; this._y = y; this._z = z; + return this; + } const sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; - if (sqrSinHalfTheta <= Number.EPSILON) { + if ( sqrSinHalfTheta <= Number.EPSILON ) { + const s = 1 - t; this._w = s * w + t * this._w; this._x = s * x + t * this._x; this._y = s * y + t * this._y; this._z = s * z + t * this._z; - this.normalize(); + this.normalize(); this._onChangeCallback(); return this; + } - const sinHalfTheta = Math.sqrt(sqrSinHalfTheta); - const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta); - const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta, - ratioB = Math.sin(t * halfTheta) / sinHalfTheta; - this._w = w * ratioA + this._w * ratioB; - this._x = x * ratioA + this._x * ratioB; - this._y = y * ratioA + this._y * ratioB; - this._z = z * ratioA + this._z * ratioB; + const sinHalfTheta = Math.sqrt( sqrSinHalfTheta ); + const halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta ); + const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, + ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; + + this._w = ( w * ratioA + this._w * ratioB ); + this._x = ( x * ratioA + this._x * ratioB ); + this._y = ( y * ratioA + this._y * ratioB ); + this._z = ( z * ratioA + this._z * ratioB ); this._onChangeCallback(); return this; + } - slerpQuaternions(qa, qb, t) { - return this.copy(qa).slerp(qb, t); + slerpQuaternions( qa, qb, t ) { + + return this.copy( qa ).slerp( qb, t ); + } random() { + // Derived from http://planning.cs.uiuc.edu/node198.html // Note, this source uses w, x, y, z ordering, // so we swap the order below. + const u1 = Math.random(); - const sqrt1u1 = Math.sqrt(1 - u1); - const sqrtu1 = Math.sqrt(u1); + const sqrt1u1 = Math.sqrt( 1 - u1 ); + const sqrtu1 = Math.sqrt( u1 ); + const u2 = 2 * Math.PI * Math.random(); + const u3 = 2 * Math.PI * Math.random(); - return this.set(sqrt1u1 * Math.cos(u2), sqrtu1 * Math.sin(u3), sqrtu1 * Math.cos(u3), sqrt1u1 * Math.sin(u2)); + + 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; + 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]; + fromArray( array, offset = 0 ) { + + this._x = array[ offset ]; + this._y = array[ offset + 1 ]; + this._z = array[ offset + 2 ]; + this._w = array[ offset + 3 ]; this._onChangeCallback(); return this; + } - toArray(array = [], offset = 0) { - array[offset] = this._x; - array[offset + 1] = this._y; - array[offset + 2] = this._z; - array[offset + 3] = this._w; + toArray( array = [], offset = 0 ) { + + array[ offset ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._w; + return array; + } - fromBufferAttribute(attribute, index) { - this._x = attribute.getX(index); - this._y = attribute.getY(index); - this._z = attribute.getZ(index); - this._w = attribute.getW(index); + fromBufferAttribute( attribute, index ) { + + this._x = attribute.getX( index ); + this._y = attribute.getY( index ); + this._z = attribute.getZ( index ); + this._w = attribute.getW( index ); + return this; + } - _onChange(callback) { + _onChange( callback ) { + this._onChangeCallback = callback; + return this; + } _onChangeCallback() {} - *[Symbol.iterator]() { + *[ Symbol.iterator ]() { + yield this._x; yield this._y; yield this._z; yield this._w; + } } class Vector3 { - constructor(x = 0, y = 0, z = 0) { - this.isVector3 = true; + + constructor( x = 0, y = 0, z = 0 ) { + + Vector3.prototype.isVector3 = true; + this.x = x; this.y = y; this.z = z; + } - set(x, y, z) { - if (z === undefined) z = this.z; // sprite.scale.set(x,y) + set( x, y, z ) { + + if ( z === undefined ) z = this.z; // sprite.scale.set(x,y) this.x = x; this.y = y; this.z = z; + return this; + } - setScalar(scalar) { + setScalar( scalar ) { + this.x = scalar; this.y = scalar; this.z = scalar; + return this; + } - setX(x) { + setX( x ) { + this.x = x; + return this; + } - setY(y) { + setY( y ) { + this.y = y; + return this; + } - setZ(z) { + setZ( z ) { + this.z = z; + return this; + } - setComponent(index, value) { - switch (index) { - case 0: - this.x = value; - break; + setComponent( index, value ) { - case 1: - this.y = value; - break; + switch ( index ) { - case 2: - this.z = value; - break; + 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 ); - default: - throw new Error('index is out of range: ' + index); } return this; + } - getComponent(index) { - switch (index) { - case 0: - return this.x; + getComponent( index ) { - case 1: - return this.y; + switch ( index ) { - case 2: - return this.z; + 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 ); - default: - throw new Error('index is out of range: ' + index); } + } clone() { - return new this.constructor(this.x, this.y, this.z); + + return new this.constructor( this.x, this.y, this.z ); + } - copy(v) { + copy( v ) { + this.x = v.x; this.y = v.y; this.z = v.z; + return this; + } - add(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.'); - return this.addVectors(v, w); - } + add( v ) { this.x += v.x; this.y += v.y; this.z += v.z; + return this; + } - addScalar(s) { + addScalar( s ) { + this.x += s; this.y += s; this.z += s; + return this; + } - addVectors(a, b) { + 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) { + addScaledVector( v, s ) { + this.x += v.x * s; this.y += v.y * s; this.z += v.z * s; + return this; + } - sub(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.'); - return this.subVectors(v, w); - } + sub( v ) { this.x -= v.x; this.y -= v.y; this.z -= v.z; + return this; + } - subScalar(s) { + subScalar( s ) { + this.x -= s; this.y -= s; this.z -= s; + return this; + } - subVectors(a, b) { + subVectors( a, b ) { + this.x = a.x - b.x; this.y = a.y - b.y; this.z = a.z - b.z; + return this; + } - multiply(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.'); - return this.multiplyVectors(v, w); - } + multiply( v ) { this.x *= v.x; this.y *= v.y; this.z *= v.z; + return this; + } - multiplyScalar(scalar) { + multiplyScalar( scalar ) { + this.x *= scalar; this.y *= scalar; this.z *= scalar; + return this; + } - multiplyVectors(a, b) { + multiplyVectors( a, b ) { + this.x = a.x * b.x; this.y = a.y * b.y; this.z = a.z * b.z; + return this; + } - applyEuler(euler) { - if (!(euler && euler.isEuler)) { - console.error('THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.'); - } + applyEuler( euler ) { + + return this.applyQuaternion( _quaternion$4.setFromEuler( euler ) ); - return this.applyQuaternion(_quaternion$4.setFromEuler(euler)); } - applyAxisAngle(axis, angle) { - return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle)); + applyAxisAngle( axis, angle ) { + + return this.applyQuaternion( _quaternion$4.setFromAxisAngle( axis, angle ) ); + } - applyMatrix3(m) { - const x = this.x, - y = this.y, - z = this.z; + applyMatrix3( m ) { + + const x = this.x, y = this.y, z = this.z; const e = m.elements; - this.x = e[0] * x + e[3] * y + e[6] * z; - this.y = e[1] * x + e[4] * y + e[7] * z; - this.z = e[2] * x + e[5] * y + e[8] * z; + + 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(); + applyNormalMatrix( m ) { + + return this.applyMatrix3( m ).normalize(); + } - applyMatrix4(m) { - const x = this.x, - y = this.y, - z = this.z; + applyMatrix4( m ) { + + const x = this.x, y = this.y, z = this.z; const e = m.elements; - const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]); - this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * w; - this.y = (e[1] * x + e[5] * y + e[9] * z + e[13]) * w; - this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w; + + const w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); + + this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; + this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; + this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; + return this; + } - applyQuaternion(q) { - const x = this.x, - y = this.y, - z = this.z; - const qx = q.x, - qy = q.y, - qz = q.z, - qw = q.w; // calculate quat * vector + applyQuaternion( q ) { + + const x = this.x, y = this.y, z = this.z; + const qx = q.x, qy = q.y, qz = q.z, qw = q.w; + + // calculate quat * vector const ix = qw * x + qy * z - qz * y; const iy = qw * y + qz * x - qx * z; const iz = qw * z + qx * y - qy * x; - const iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat + 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; - 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); + project( camera ) { + + return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix ); + } - unproject(camera) { - return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld); + unproject( camera ) { + + return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld ); + } - transformDirection(m) { + transformDirection( m ) { + // input: THREE.Matrix4 affine matrix // vector interpreted as a direction - const x = this.x, - y = this.y, - z = this.z; + + const x = this.x, y = this.y, z = this.z; const e = m.elements; - this.x = e[0] * x + e[4] * y + e[8] * z; - this.y = e[1] * x + e[5] * y + e[9] * z; - this.z = e[2] * x + e[6] * y + e[10] * z; + + 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) { + divide( v ) { + this.x /= v.x; this.y /= v.y; this.z /= v.z; + return this; + } - divideScalar(scalar) { - return this.multiplyScalar(1 / scalar); + 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); + 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); + 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) { + 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.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)); + 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) { + clampLength( min, max ) { + const length = this.length(); - return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, 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); + + 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); + + 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); + + 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); + + 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; + + this.x = - this.x; + this.y = - this.y; + this.z = - this.z; + return this; + } - dot(v) { + 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); + + 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); + + return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); + } normalize() { - return this.divideScalar(this.length() || 1); + + return this.divideScalar( this.length() || 1 ); + } - setLength(length) { - return this.normalize().multiplyScalar(length); + 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; + 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; + lerpVectors( v1, v2, alpha ) { + + this.x = v1.x + ( v2.x - v1.x ) * alpha; + this.y = v1.y + ( v2.y - v1.y ) * alpha; + this.z = v1.z + ( v2.z - v1.z ) * alpha; + return this; + } - cross(v, w) { - if (w !== undefined) { - console.warn('THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.'); - return this.crossVectors(v, w); - } + cross( v ) { + + return this.crossVectors( this, v ); - return this.crossVectors(this, v); } - crossVectors(a, b) { - const ax = a.x, - ay = a.y, - az = a.z; - const bx = b.x, - by = b.y, - bz = b.z; + crossVectors( a, b ) { + + const ax = a.x, ay = a.y, az = a.z; + const bx = b.x, by = b.y, bz = b.z; + this.x = ay * bz - az * by; this.y = az * bx - ax * bz; this.z = ax * by - ay * bx; + return this; + } - projectOnVector(v) { + 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); + + 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); + projectOnPlane( planeNormal ) { + + _vector$c.copy( this ).projectOnVector( planeNormal ); + + return this.sub( _vector$c ); - return this.sub(_vector$c); } - reflect(normal) { + 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))); + + 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 + angleTo( v ) { + + const denominator = Math.sqrt( this.lengthSq() * v.lengthSq() ); + + if ( denominator === 0 ) return Math.PI / 2; + + const theta = this.dot( v ) / denominator; + + // clamp, to handle numerical problems + + return Math.acos( clamp( theta, - 1, 1 ) ); - return Math.acos(clamp(theta, -1, 1)); } - distanceTo(v) { - return Math.sqrt(this.distanceToSquared(v)); + 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; + distanceToSquared( v ) { + + const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; + return dx * dx + dy * dy + dz * dz; + } - manhattanDistanceTo(v) { - return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z); + 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); + setFromSpherical( s ) { + + return this.setFromSphericalCoords( s.radius, s.phi, s.theta ); + } - setFromSphericalCoords(radius, phi, theta) { - const sinPhiRadius = Math.sin(phi) * radius; - this.x = sinPhiRadius * Math.sin(theta); - this.y = Math.cos(phi) * radius; - this.z = sinPhiRadius * Math.cos(theta); + setFromSphericalCoords( radius, phi, theta ) { + + const sinPhiRadius = Math.sin( phi ) * radius; + + this.x = sinPhiRadius * Math.sin( theta ); + this.y = Math.cos( phi ) * radius; + this.z = sinPhiRadius * Math.cos( theta ); + return this; + } - setFromCylindrical(c) { - return this.setFromCylindricalCoords(c.radius, c.theta, c.y); + setFromCylindrical( c ) { + + return this.setFromCylindricalCoords( c.radius, c.theta, c.y ); + } - setFromCylindricalCoords(radius, theta, y) { - this.x = radius * Math.sin(theta); + setFromCylindricalCoords( radius, theta, y ) { + + this.x = radius * Math.sin( theta ); this.y = y; - this.z = radius * Math.cos(theta); + this.z = radius * Math.cos( theta ); + return this; + } - setFromMatrixPosition(m) { + setFromMatrixPosition( m ) { + const e = m.elements; - this.x = e[12]; - this.y = e[13]; - this.z = e[14]; + + this.x = e[ 12 ]; + this.y = e[ 13 ]; + this.z = e[ 14 ]; + return this; + } - setFromMatrixScale(m) { - const sx = this.setFromMatrixColumn(m, 0).length(); - const sy = this.setFromMatrixColumn(m, 1).length(); - const sz = this.setFromMatrixColumn(m, 2).length(); + setFromMatrixScale( m ) { + + const sx = this.setFromMatrixColumn( m, 0 ).length(); + const sy = this.setFromMatrixColumn( m, 1 ).length(); + const sz = this.setFromMatrixColumn( m, 2 ).length(); + this.x = sx; this.y = sy; this.z = sz; + return this; + } - setFromMatrixColumn(m, index) { - return this.fromArray(m.elements, index * 4); + setFromMatrixColumn( m, index ) { + + return this.fromArray( m.elements, index * 4 ); + } - setFromMatrix3Column(m, index) { - return this.fromArray(m.elements, index * 3); + setFromMatrix3Column( m, index ) { + + return this.fromArray( m.elements, index * 3 ); + } - setFromEuler(e) { + 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; + 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]; + 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; + toArray( array = [], offset = 0 ) { + + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + array[ offset + 2 ] = this.z; + return array; + } - fromBufferAttribute(attribute, index, offset) { - if (offset !== undefined) { - console.warn('THREE.Vector3: offset has been removed from .fromBufferAttribute().'); - } + fromBufferAttribute( attribute, index ) { + + this.x = attribute.getX( index ); + this.y = attribute.getY( index ); + this.z = attribute.getZ( 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 u = ( Math.random() - 0.5 ) * 2; const t = Math.random() * Math.PI * 2; - const f = Math.sqrt(1 - u ** 2); - this.x = f * Math.cos(t); - this.y = f * Math.sin(t); + const f = Math.sqrt( 1 - u ** 2 ); + + this.x = f * Math.cos( t ); + this.y = f * Math.sin( t ); this.z = u; + return this; + } - *[Symbol.iterator]() { + *[ Symbol.iterator ]() { + yield this.x; yield this.y; yield this.z; + } } - const _vector$c = /*@__PURE__*/new Vector3(); - - const _quaternion$4 = /*@__PURE__*/new Quaternion(); + const _vector$c = /*@__PURE__*/ new Vector3(); + const _quaternion$4 = /*@__PURE__*/ new Quaternion(); class Box3 { - constructor(min = new Vector3(+Infinity, +Infinity, +Infinity), max = new Vector3(-Infinity, -Infinity, -Infinity)) { + + constructor( min = new Vector3( + Infinity, + Infinity, + Infinity ), max = new Vector3( - Infinity, - Infinity, - Infinity ) ) { + this.isBox3 = true; + this.min = min; this.max = max; + } - set(min, max) { - this.min.copy(min); - this.max.copy(max); + set( min, max ) { + + this.min.copy( min ); + this.max.copy( max ); + return this; + } - setFromArray(array) { - let minX = +Infinity; - let minY = +Infinity; - let minZ = +Infinity; - let maxX = -Infinity; - let maxY = -Infinity; - let maxZ = -Infinity; + setFromArray( array ) { + + let minX = + Infinity; + let minY = + Infinity; + let minZ = + Infinity; + + 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 ]; + const z = array[ i + 2 ]; + + if ( x < minX ) minX = x; + if ( y < minY ) minY = y; + if ( z < minZ ) minZ = z; + + if ( x > maxX ) maxX = x; + if ( y > maxY ) maxY = y; + if ( z > maxZ ) maxZ = z; - for (let i = 0, l = array.length; i < l; i += 3) { - const x = array[i]; - const y = array[i + 1]; - const z = array[i + 2]; - if (x < minX) minX = x; - if (y < minY) minY = y; - if (z < minZ) minZ = z; - if (x > maxX) maxX = x; - if (y > maxY) maxY = y; - if (z > maxZ) maxZ = z; } - this.min.set(minX, minY, minZ); - this.max.set(maxX, maxY, maxZ); + this.min.set( minX, minY, minZ ); + this.max.set( maxX, maxY, maxZ ); + return this; + } - setFromBufferAttribute(attribute) { - let minX = +Infinity; - let minY = +Infinity; - let minZ = +Infinity; - let maxX = -Infinity; - let maxY = -Infinity; - let maxZ = -Infinity; + setFromBufferAttribute( attribute ) { + + let minX = + Infinity; + let minY = + Infinity; + let minZ = + Infinity; + + 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 ); + const z = attribute.getZ( i ); + + if ( x < minX ) minX = x; + if ( y < minY ) minY = y; + if ( z < minZ ) minZ = z; + + if ( x > maxX ) maxX = x; + if ( y > maxY ) maxY = y; + if ( z > maxZ ) maxZ = z; - for (let i = 0, l = attribute.count; i < l; i++) { - const x = attribute.getX(i); - const y = attribute.getY(i); - const z = attribute.getZ(i); - if (x < minX) minX = x; - if (y < minY) minY = y; - if (z < minZ) minZ = z; - if (x > maxX) maxX = x; - if (y > maxY) maxY = y; - if (z > maxZ) maxZ = z; } - this.min.set(minX, minY, minZ); - this.max.set(maxX, maxY, maxZ); + this.min.set( minX, minY, minZ ); + this.max.set( maxX, maxY, maxZ ); + return this; + } - setFromPoints(points) { + setFromPoints( points ) { + this.makeEmpty(); - for (let i = 0, il = points.length; i < il; i++) { - this.expandByPoint(points[i]); + 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); + setFromCenterAndSize( center, size ) { + + const halfSize = _vector$b.copy( size ).multiplyScalar( 0.5 ); + + this.min.copy( center ).sub( halfSize ); + this.max.copy( center ).add( halfSize ); - this.min.copy(center).sub(halfSize); - this.max.copy(center).add(halfSize); return this; + } - setFromObject(object, precise = false) { + setFromObject( object, precise = false ) { + this.makeEmpty(); - return this.expandByObject(object, precise); + + return this.expandByObject( object, precise ); + } clone() { - return new this.constructor().copy(this); + + return new this.constructor().copy( this ); + } - copy(box) { - this.min.copy(box.min); - this.max.copy(box.max); + 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; + + 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; + + 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); + 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); + 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); + expandByPoint( point ) { + + this.min.min( point ); + this.max.max( point ); + return this; + } - expandByVector(vector) { - this.min.sub(vector); - this.max.add(vector); + expandByVector( vector ) { + + this.min.sub( vector ); + this.max.add( vector ); + return this; + } - expandByScalar(scalar) { - this.min.addScalar(-scalar); - this.max.addScalar(scalar); + expandByScalar( scalar ) { + + this.min.addScalar( - scalar ); + this.max.addScalar( scalar ); + return this; + } - expandByObject(object, precise = false) { + 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); + + object.updateWorldMatrix( false, false ); + const geometry = object.geometry; - if (geometry !== undefined) { - if (precise && geometry.attributes != undefined && geometry.attributes.position !== undefined) { + 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 ++ ) { - for (let i = 0, l = position.count; i < l; i++) { - _vector$b.fromBufferAttribute(position, i).applyMatrix4(object.matrixWorld); + _vector$b.fromBufferAttribute( position, i ).applyMatrix4( object.matrixWorld ); + this.expandByPoint( _vector$b ); - this.expandByPoint(_vector$b); } + } else { - if (geometry.boundingBox === null) { + + if ( geometry.boundingBox === null ) { + geometry.computeBoundingBox(); + } - _box$3.copy(geometry.boundingBox); + _box$3.copy( geometry.boundingBox ); + _box$3.applyMatrix4( object.matrixWorld ); - _box$3.applyMatrix4(object.matrixWorld); + this.union( _box$3 ); - this.union(_box$3); } + } const children = object.children; - for (let i = 0, l = children.length; i < l; i++) { - this.expandByObject(children[i], precise); + 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; + 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; + 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) { + 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)); + + 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) { + 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; + 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) { + 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 ); - return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius; } - intersectsPlane(plane) { + 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; - if (plane.normal.x > 0) { + if ( plane.normal.x > 0 ) { + min = plane.normal.x * this.min.x; max = plane.normal.x * this.max.x; + } else { + min = plane.normal.x * this.max.x; max = plane.normal.x * this.min.x; + } - if (plane.normal.y > 0) { + if ( plane.normal.y > 0 ) { + min += plane.normal.y * this.min.y; max += plane.normal.y * this.max.y; + } else { + min += plane.normal.y * this.max.y; max += plane.normal.y * this.min.y; + } - if (plane.normal.z > 0) { + if ( plane.normal.z > 0 ) { + min += plane.normal.z * this.min.z; max += plane.normal.z * this.max.z; + } else { + min += plane.normal.z * this.max.z; max += plane.normal.z * this.min.z; - } - - return min <= -plane.constant && max >= -plane.constant; - } - - intersectsTriangle(triangle) { - if (this.isEmpty()) { - return false; - } // compute box center and extents + } - this.getCenter(_center); + return ( min <= - plane.constant && max >= - plane.constant ); - _extents.subVectors(this.max, _center); // translate triangle to aabb origin + } + intersectsTriangle( triangle ) { - _v0$2.subVectors(triangle.a, _center); + if ( this.isEmpty() ) { - _v1$7.subVectors(triangle.b, _center); + return false; - _v2$3.subVectors(triangle.c, _center); // compute edge vectors for triangle + } + // compute box center and extents + this.getCenter( _center ); + _extents.subVectors( this.max, _center ); - _f0.subVectors(_v1$7, _v0$2); + // translate triangle to aabb origin + _v0$2.subVectors( triangle.a, _center ); + _v1$7.subVectors( triangle.b, _center ); + _v2$4.subVectors( triangle.c, _center ); - _f1.subVectors(_v2$3, _v1$7); + // compute edge vectors for triangle + _f0.subVectors( _v1$7, _v0$2 ); + _f1.subVectors( _v2$4, _v1$7 ); + _f2.subVectors( _v0$2, _v2$4 ); - _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$4, _extents ) ) { - - 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)) { return false; - } // test 3 face normals from the aabb + } - axes = [1, 0, 0, 0, 1, 0, 0, 0, 1]; + // 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$4, _extents ) ) { - if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) { return false; - } // finally testing the face normal of the triangle - // use already existing triangle edge vectors here + } - _triangleNormal.crossVectors(_f0, _f1); + // 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 ]; - 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); + clampPoint( point, target ) { - return clampedPoint.sub(point).length(); - } + return target.copy( point ).clamp( this.min, this.max ); - 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. + distanceToPoint( point ) { - if (this.isEmpty()) this.makeEmpty(); - return this; - } + const clampedPoint = _vector$b.copy( point ).clamp( this.min, this.max ); + + return clampedPoint.sub( point ).length(); - 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 + getBoundingSphere( target ) { - _points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix); // 000 + this.getCenter( target.center ); + target.radius = this.getSize( _vector$b ).length() * 0.5; - _points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix); // 001 + return target; + } - _points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix); // 010 + intersect( box ) { + this.min.max( box.min ); + this.max.min( box.max ); - _points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix); // 011 + // 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; - _points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix); // 100 + } + union( box ) { - _points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix); // 101 + this.min.min( box.min ); + this.max.max( box.max ); + return this; - _points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix); // 110 + } + applyMatrix4( matrix ) { - _points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix); // 111 + // 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 + _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; - } + this.setFromPoints( _points ); - 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()]; + translate( offset ) { - const _vector$b = /*@__PURE__*/new Vector3(); + this.min.add( offset ); + this.max.add( offset ); - const _box$3 = /*@__PURE__*/new Box3(); // triangle centered vertices + return this; + } - const _v0$2 = /*@__PURE__*/new Vector3(); + equals( box ) { - const _v1$7 = /*@__PURE__*/new Vector3(); + return box.min.equals( this.min ) && box.max.equals( this.max ); - const _v2$3 = /*@__PURE__*/new Vector3(); // triangle edge vectors + } + } - const _f0 = /*@__PURE__*/new Vector3(); + 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 _f1 = /*@__PURE__*/new Vector3(); + const _vector$b = /*@__PURE__*/ new Vector3(); - const _f2 = /*@__PURE__*/new Vector3(); + const _box$3 = /*@__PURE__*/ new Box3(); - const _center = /*@__PURE__*/new Vector3(); + // triangle centered vertices - const _extents = /*@__PURE__*/new Vector3(); + const _v0$2 = /*@__PURE__*/ new Vector3(); + const _v1$7 = /*@__PURE__*/ new Vector3(); + const _v2$4 = /*@__PURE__*/ new Vector3(); - const _triangleNormal = /*@__PURE__*/new Vector3(); + // triangle edge vectors - const _testAxis = /*@__PURE__*/new Vector3(); + const _f0 = /*@__PURE__*/ new Vector3(); + const _f1 = /*@__PURE__*/ new Vector3(); + const _f2 = /*@__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 _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 ) { - 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 + for ( let i = 0, j = axes.length - 3; i <= j; i += 3 ) { - 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 + _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 + if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > 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 _box$2 = /*@__PURE__*/ new Box3(); + const _v1$6 = /*@__PURE__*/ new Vector3(); + const _v2$3 = /*@__PURE__*/ new Vector3(); - const _toFarthestPoint = /*@__PURE__*/new Vector3(); + class Sphere { - const _toPoint = /*@__PURE__*/new Vector3(); + constructor( center = new Vector3(), radius = - 1 ) { - class Sphere { - constructor(center = new Vector3(), radius = -1) { this.center = center; this.radius = radius; + } - set(center, radius) { - this.center.copy(center); + set( center, radius ) { + + this.center.copy( center ); this.radius = radius; + return this; + } - setFromPoints(points, optionalCenter) { + setFromPoints( points, optionalCenter ) { + const center = this.center; - if (optionalCenter !== undefined) { - center.copy(optionalCenter); + if ( optionalCenter !== undefined ) { + + center.copy( optionalCenter ); + } else { - _box$2.setFromPoints(points).getCenter(center); + + _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])); + for ( let i = 0, il = points.length; i < il; i ++ ) { + + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); + } - this.radius = Math.sqrt(maxRadiusSq); + this.radius = Math.sqrt( maxRadiusSq ); + return this; + } - copy(sphere) { - this.center.copy(sphere.center); + copy( sphere ) { + + this.center.copy( sphere.center ); this.radius = sphere.radius; + return this; + } isEmpty() { - return this.radius < 0; + + return ( this.radius < 0 ); + } makeEmpty() { - this.center.set(0, 0, 0); - this.radius = -1; + + this.center.set( 0, 0, 0 ); + this.radius = - 1; + return this; + } - containsPoint(point) { - return point.distanceToSquared(this.center) <= this.radius * this.radius; + containsPoint( point ) { + + return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); + } - distanceToPoint(point) { - return point.distanceTo(this.center) - this.radius; + distanceToPoint( point ) { + + return ( point.distanceTo( this.center ) - this.radius ); + } - intersectsSphere(sphere) { + intersectsSphere( sphere ) { + const radiusSum = this.radius + sphere.radius; - return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum; + + return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); + } - intersectsBox(box) { - return box.intersectsSphere(this); + intersectsBox( box ) { + + return box.intersectsSphere( this ); + } - intersectsPlane(plane) { - return Math.abs(plane.distanceToPoint(this.center)) <= this.radius; + intersectsPlane( plane ) { + + return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; + } - clampPoint(point, target) { - const deltaLengthSq = this.center.distanceToSquared(point); - target.copy(point); + 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 ); - 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()) { + 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); + target.set( this.center, this.center ); + target.expandByScalar( this.radius ); + return target; + } - applyMatrix4(matrix) { - this.center.applyMatrix4(matrix); + applyMatrix4( matrix ) { + + this.center.applyMatrix4( matrix ); this.radius = this.radius * matrix.getMaxScaleOnAxis(); + return this; + } - translate(offset) { - this.center.add(offset); + 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); + expandByPoint( point ) { + + 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 ) ) { + + // calculate the minimal sphere + + const length = Math.sqrt( lengthSq ); - const lengthSq = _toPoint.lengthSq(); + const delta = ( length - this.radius ) * 0.5; - 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. + this.center.addScaledVector( _v1$6, delta / length ); + + this.radius += delta; - this.center.add(_toPoint.multiplyScalar(missingRadiusHalf / length)); - this.radius += missingRadiusHalf; } 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 (this.center.equals(sphere.center) === true) { - _toFarthestPoint.set(0, 0, 1).multiplyScalar(sphere.radius); + union( sphere ) { + + if ( sphere.isEmpty() ) { + + return this; + + } + + if ( this.isEmpty() ) { + + this.copy( sphere ); + + 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$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); - } + equals( sphere ) { - } + return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); - const _vector$a = /*@__PURE__*/new Vector3(); + } - const _segCenter = /*@__PURE__*/new Vector3(); + clone() { - const _segDir = /*@__PURE__*/new Vector3(); + return new this.constructor().copy( this ); - const _diff = /*@__PURE__*/new Vector3(); + } - const _edge1 = /*@__PURE__*/new Vector3(); + } - const _edge2 = /*@__PURE__*/new Vector3(); + const _vector$a = /*@__PURE__*/ new Vector3(); + const _segCenter = /*@__PURE__*/ new Vector3(); + const _segDir = /*@__PURE__*/ new Vector3(); + const _diff = /*@__PURE__*/ new Vector3(); - const _normal$1 = /*@__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)) { + + 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); + 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); + 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; + at( t, target ) { + + return target.copy( this.direction ).multiplyScalar( t ).add( this.origin ); + } - recast(t) { - this.origin.copy(this.at(t, _vector$a)); + lookAt( v ) { + + this.direction.copy( v ).sub( this.origin ).normalize(); + return this; + } - closestPointToPoint(point, target) { - target.subVectors(point, this.origin); - const directionDistance = target.dot(this.direction); + recast( t ) { - if (directionDistance < 0) { - return target.copy(this.origin); - } + this.origin.copy( this.at( t, _vector$a ) ); - return target.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); - } + return this; - 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 + closestPointToPoint( point, target ) { + target.subVectors( point, this.origin ); - if (directionDistance < 0) { - return this.origin.distanceToSquared(point); - } + const directionDistance = target.dot( this.direction ); - _vector$a.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); + if ( directionDistance < 0 ) { - return _vector$a.distanceToSquared(point); - } + 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 + + 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 ) { - 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 // defined by v0 and v1 // It can also set two optional targets : // - The closest point on the ray // - The closest point on the segment - _segCenter.copy(v0).add(v1).multiplyScalar(0.5); - - _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); + _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); + const det = Math.abs( 1 - a01 * a01 ); let s0, s1, sqrDist, extDet; - if (det > 0) { + 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) { + 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; + 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; + 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; + + s1 = - segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + } + } else { - if (s1 <= -extDet) { + + 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) { + + 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; + 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; + + s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); + s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + } + } + } else { + // Ray and segment are parallel. - s1 = a01 > 0 ? -segExtent : segExtent; - s0 = Math.max(0, -(a01 * s1 + b0)); - sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; + + 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 ( optionalPointOnRay ) { + + optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin ); + } - if (optionalPointOnSegment) { - optionalPointOnSegment.copy(_segDir).multiplyScalar(s1).add(_segCenter); + 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); + intersectSphere( sphere, target ) { - const d2 = _vector$a.dot(_vector$a) - tca * tca; + _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 t0 = tca - thc; // t1 = second intersect point - exit point on back of sphere + if ( d2 > radius2 ) return null; + + const thc = Math.sqrt( radius2 - d2 ); + + // 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 ); - return this.at(t0, target); } - intersectsSphere(sphere) { - return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius; + intersectsSphere( sphere ) { + + return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius ); + } - distanceToPlane(plane) { - const denominator = plane.normal.dot(this.direction); + distanceToPlane( plane ) { + + const denominator = plane.normal.dot( this.direction ); + + if ( denominator === 0 ) { - if (denominator === 0) { // line is coplanar, return origin - if (plane.distanceToPoint(this.origin) === 0) { + 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; // Return if the ray never intersects the plane + const t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; + + // Return if the ray never intersects the plane return t >= 0 ? t : null; + } - intersectPlane(plane, target) { - const t = this.distanceToPlane(plane); + intersectPlane( plane, target ) { + + const t = this.distanceToPlane( plane ); + + if ( t === null ) { - if (t === null) { return null; + } - return this.at(t, target); + return this.at( t, target ); + } - intersectsPlane(plane) { + intersectsPlane( plane ) { + // check if the ray lies on the plane first - const distToPoint = plane.distanceToPoint(this.origin); - if (distToPoint === 0) { + const distToPoint = plane.distanceToPoint( this.origin ); + + if ( distToPoint === 0 ) { + return true; + } - const denominator = plane.normal.dot(this.direction); + const denominator = plane.normal.dot( this.direction ); + + if ( denominator * distToPoint < 0 ) { - 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) { + 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; + if ( invdirx >= 0 ) { + + tmin = ( box.min.x - origin.x ) * invdirx; + tmax = ( box.max.x - origin.x ) * invdirx; + } else { - tmin = (box.max.x - origin.x) * invdirx; - tmax = (box.min.x - origin.x) * invdirx; + + 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; + if ( invdiry >= 0 ) { + + tymin = ( box.min.y - origin.y ) * invdiry; + tymax = ( box.max.y - origin.y ) * invdiry; + } else { - tymin = (box.max.y - origin.y) * invdiry; - tymax = (box.min.y - origin.y) * invdiry; + + 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 ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; + + if ( tymin > tmin || isNaN( tmin ) ) tmin = tymin; + + if ( tymax < tmax || isNaN( tmax ) ) tmax = tymax; - if (tymin > tmin || tmin !== tmin) tmin = tymin; - if (tymax < tmax || tmax !== tmax) tmax = tymax; + if ( invdirz >= 0 ) { + + tzmin = ( box.min.z - origin.z ) * invdirz; + tzmax = ( box.max.z - origin.z ) * invdirz; - if (invdirz >= 0) { - tzmin = (box.min.z - origin.z) * invdirz; - tzmax = (box.max.z - origin.z) * invdirz; } else { - tzmin = (box.max.z - origin.z) * invdirz; - tzmax = (box.min.z - origin.z) * invdirz; + + 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 ( ( 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 ( tmax < 0 ) return null; + + return this.at( tmin >= 0 ? tmin : tmax, target ); - if (tmax < 0) return null; - return this.at(tmin >= 0 ? tmin : tmax, target); } - intersectsBox(box) { - return this.intersectBox(box, _vector$a) !== null; + intersectsBox( box ) { + + return this.intersectBox( box, _vector$a ) !== null; + } - intersectTriangle(a, b, c, backfaceCulling, target) { + 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); - _edge2.subVectors(c, 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); + // |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; + if ( DdN > 0 ) { + + if ( backfaceCulling ) return null; sign = 1; - } else if (DdN < 0) { - sign = -1; - DdN = -DdN; + + } else if ( DdN < 0 ) { + + sign = - 1; + DdN = - DdN; + } else { + return null; + } - _diff.subVectors(this.origin, a); + _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 ) { - if (DdQxE2 < 0) { return null; + } - const DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff)); // b2 < 0, no intersection + const DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) ); + + // b2 < 0, no intersection + if ( DdE1xQ < 0 ) { - if (DdE1xQ < 0) { return null; - } // b1+b2 > 1, no intersection + } + + // b1+b2 > 1, no intersection + if ( DdQxE2 + DdE1xQ > DdN ) { - 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 ) { - if (QdN < 0) { return null; - } // Ray intersects triangle. + } + + // Ray intersects triangle. + return this.at( QdN / DdN, target ); - return this.at(QdN / DdN, target); } - applyMatrix4(matrix4) { - this.origin.applyMatrix4(matrix4); - this.direction.transformDirection(matrix4); + 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); + equals( ray ) { + + return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); + } clone() { - return new this.constructor().copy(this); + + return new this.constructor().copy( this ); + } } class Matrix4 { + constructor() { - this.isMatrix4 = true; - this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; - if (arguments.length > 0) { - console.error('THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.'); - } - } + Matrix4.prototype.isMatrix4 = true; - set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) { - const te = this.elements; - te[0] = n11; - te[4] = n12; - te[8] = n13; - te[12] = n14; - te[1] = n21; - te[5] = n22; - te[9] = n23; - te[13] = n24; - te[2] = n31; - te[6] = n32; - te[10] = n33; - te[14] = n34; - te[3] = n41; - te[7] = n42; - te[11] = n43; - te[15] = n44; - return this; - } + this.elements = [ - identity() { - this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - return this; - } + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + + ]; - clone() { - return new Matrix4().fromArray(this.elements); } - copy(m) { + set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { + const te = this.elements; - const me = m.elements; - te[0] = me[0]; - te[1] = me[1]; - te[2] = me[2]; - te[3] = me[3]; - te[4] = me[4]; - te[5] = me[5]; - te[6] = me[6]; - te[7] = me[7]; - te[8] = me[8]; - te[9] = me[9]; - te[10] = me[10]; - te[11] = me[11]; - te[12] = me[12]; - te[13] = me[13]; - te[14] = me[14]; - te[15] = me[15]; - return this; - } - - copyPosition(m) { - const te = this.elements, - me = m.elements; - te[12] = me[12]; - te[13] = me[13]; - te[14] = me[14]; - return this; - } - setFromMatrix3(m) { - const me = m.elements; - this.set(me[0], me[3], me[6], 0, me[1], me[4], me[7], 0, me[2], me[5], me[8], 0, 0, 0, 0, 1); - return this; - } + te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; + te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; + te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; + te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; - 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; + identity() { - const scaleX = 1 / _v1$5.setFromMatrixColumn(m, 0).length(); + this.set( - const scaleY = 1 / _v1$5.setFromMatrixColumn(m, 1).length(); + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 - const scaleZ = 1 / _v1$5.setFromMatrixColumn(m, 2).length(); + ); - te[0] = me[0] * scaleX; - te[1] = me[1] * scaleX; - te[2] = me[2] * scaleX; - te[3] = 0; - te[4] = me[4] * scaleY; - te[5] = me[5] * scaleY; - te[6] = me[6] * scaleY; - te[7] = 0; - te[8] = me[8] * scaleZ; - te[9] = me[9] * scaleZ; - te[10] = me[10] * scaleZ; - te[11] = 0; - te[12] = 0; - te[13] = 0; - te[14] = 0; - te[15] = 1; return this; + } - makeRotationFromEuler(euler) { - if (!(euler && euler.isEuler)) { - console.error('THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.'); - } + clone() { - const te = this.elements; - const x = euler.x, - y = euler.y, - z = euler.z; - const a = Math.cos(x), - b = Math.sin(x); - const c = Math.cos(y), - d = Math.sin(y); - const e = Math.cos(z), - f = Math.sin(z); - - if (euler.order === 'XYZ') { - const ae = a * e, - af = a * f, - be = b * e, - bf = b * f; - te[0] = c * e; - te[4] = -c * f; - te[8] = d; - te[1] = af + be * d; - te[5] = ae - bf * d; - te[9] = -b * c; - te[2] = bf - ae * d; - te[6] = be + af * d; - te[10] = a * c; - } else if (euler.order === 'YXZ') { - const ce = c * e, - cf = c * f, - de = d * e, - df = d * f; - te[0] = ce + df * b; - te[4] = de * b - cf; - te[8] = a * d; - te[1] = a * f; - te[5] = a * e; - te[9] = -b; - te[2] = cf * b - de; - te[6] = df + ce * b; - te[10] = a * c; - } else if (euler.order === 'ZXY') { - const ce = c * e, - cf = c * f, - de = d * e, - df = d * f; - te[0] = ce - df * b; - te[4] = -a * f; - te[8] = de + cf * b; - te[1] = cf + de * b; - te[5] = a * e; - te[9] = df - ce * b; - te[2] = -a * d; - te[6] = b; - te[10] = a * c; - } else if (euler.order === 'ZYX') { - const ae = a * e, - af = a * f, - be = b * e, - bf = b * f; - te[0] = c * e; - te[4] = be * d - af; - te[8] = ae * d + bf; - te[1] = c * f; - te[5] = bf * d + ae; - te[9] = af * d - be; - te[2] = -d; - te[6] = b * c; - te[10] = a * c; - } else if (euler.order === 'YZX') { - const ac = a * c, - ad = a * d, - bc = b * c, - bd = b * d; - te[0] = c * e; - te[4] = bd - ac * f; - te[8] = bc * f + ad; - te[1] = f; - te[5] = a * e; - te[9] = -b * e; - te[2] = -d * e; - te[6] = ad * f + bc; - te[10] = ac - bd * f; - } else if (euler.order === 'XZY') { - const ac = a * c, - ad = a * d, - bc = b * c, - bd = b * d; - te[0] = c * e; - te[4] = -f; - te[8] = d * e; - te[1] = ac * f + bd; - te[5] = a * e; - te[9] = ad * f - bc; - te[2] = bc * f - ad; - te[6] = b * e; - te[10] = bd * f + ac; - } // bottom row - - - te[3] = 0; - te[7] = 0; - te[11] = 0; // last column - - te[12] = 0; - te[13] = 0; - te[14] = 0; - te[15] = 1; - return this; - } - - makeRotationFromQuaternion(q) { - return this.compose(_zero, q, _one); - } - - lookAt(eye, target, up) { - const te = this.elements; + return new Matrix4().fromArray( this.elements ); - _z.subVectors(eye, target); + } - if (_z.lengthSq() === 0) { - // eye and target are in the same position - _z.z = 1; - } + copy( m ) { - _z.normalize(); + const te = this.elements; + const me = m.elements; - _x.crossVectors(up, _z); + te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; + te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; + te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; + te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; - if (_x.lengthSq() === 0) { - // up and z are parallel - if (Math.abs(up.z) === 1) { - _z.x += 0.0001; - } else { - _z.z += 0.0001; - } + return this; - _z.normalize(); + } - _x.crossVectors(up, _z); - } + copyPosition( m ) { - _x.normalize(); + const te = this.elements, me = m.elements; - _y.crossVectors(_z, _x); + te[ 12 ] = me[ 12 ]; + te[ 13 ] = me[ 13 ]; + te[ 14 ] = me[ 14 ]; - te[0] = _x.x; - te[4] = _y.x; - te[8] = _z.x; - te[1] = _x.y; - te[5] = _y.y; - te[9] = _z.y; - te[2] = _x.z; - te[6] = _y.z; - te[10] = _z.z; return this; - } - - multiply(m, n) { - if (n !== undefined) { - console.warn('THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.'); - return this.multiplyMatrices(m, n); - } - return this.multiplyMatrices(this, m); } - premultiply(m) { - return this.multiplyMatrices(m, this); - } - - multiplyMatrices(a, b) { - const ae = a.elements; - const be = b.elements; - const te = this.elements; - const a11 = ae[0], - a12 = ae[4], - a13 = ae[8], - a14 = ae[12]; - const a21 = ae[1], - a22 = ae[5], - a23 = ae[9], - a24 = ae[13]; - const a31 = ae[2], - a32 = ae[6], - a33 = ae[10], - a34 = ae[14]; - const a41 = ae[3], - a42 = ae[7], - a43 = ae[11], - a44 = ae[15]; - const b11 = be[0], - b12 = be[4], - b13 = be[8], - b14 = be[12]; - const b21 = be[1], - b22 = be[5], - b23 = be[9], - b24 = be[13]; - const b31 = be[2], - b32 = be[6], - b33 = be[10], - b34 = be[14]; - const b41 = be[3], - b42 = be[7], - b43 = be[11], - b44 = be[15]; - te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; - te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; - te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; - te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; - te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; - te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; - te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; - te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; - te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; - te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; - te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; - te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; - te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; - te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; - te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; - te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; - return this; - } - - multiplyScalar(s) { - const te = this.elements; - te[0] *= s; - te[4] *= s; - te[8] *= s; - te[12] *= s; - te[1] *= s; - te[5] *= s; - te[9] *= s; - te[13] *= s; - te[2] *= s; - te[6] *= s; - te[10] *= s; - te[14] *= s; - te[3] *= s; - te[7] *= s; - te[11] *= s; - te[15] *= s; - return this; - } + setFromMatrix3( m ) { - determinant() { - const te = this.elements; - const n11 = te[0], - n12 = te[4], - n13 = te[8], - n14 = te[12]; - const n21 = te[1], - n22 = te[5], - n23 = te[9], - n24 = te[13]; - const n31 = te[2], - n32 = te[6], - n33 = te[10], - n34 = te[14]; - const n41 = te[3], - n42 = te[7], - n43 = te[11], - n44 = te[15]; //TODO: make this more efficient - //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) + const me = m.elements; - 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); - } + this.set( - transpose() { - const te = this.elements; - let tmp; - tmp = te[1]; - te[1] = te[4]; - te[4] = tmp; - tmp = te[2]; - te[2] = te[8]; - te[8] = tmp; - tmp = te[6]; - te[6] = te[9]; - te[9] = tmp; - tmp = te[3]; - te[3] = te[12]; - te[12] = tmp; - tmp = te[7]; - te[7] = te[13]; - te[13] = tmp; - tmp = te[11]; - te[11] = te[14]; - te[14] = tmp; - return this; - } - - setPosition(x, y, z) { - const te = this.elements; + 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 - if (x.isVector3) { - te[12] = x.x; - te[13] = x.y; - te[14] = x.z; - } else { - te[12] = x; - te[13] = y; - te[14] = z; - } + ); return this; - } - invert() { - // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm - const te = this.elements, - n11 = te[0], - n21 = te[1], - n31 = te[2], - n41 = te[3], - n12 = te[4], - n22 = te[5], - n32 = te[6], - n42 = te[7], - n13 = te[8], - n23 = te[9], - n33 = te[10], - n43 = te[11], - n14 = te[12], - n24 = te[13], - n34 = te[14], - n44 = te[15], - t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, - t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, - t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, - t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; - const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; - if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - const detInv = 1 / det; - te[0] = t11 * detInv; - te[1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * detInv; - te[2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * detInv; - te[3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * detInv; - te[4] = t12 * detInv; - te[5] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * detInv; - te[6] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * detInv; - te[7] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * detInv; - te[8] = t13 * detInv; - te[9] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * detInv; - te[10] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * detInv; - te[11] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * detInv; - te[12] = t14 * detInv; - te[13] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * detInv; - te[14] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * detInv; - te[15] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv; - return this; - } - - scale(v) { - const te = this.elements; - const x = v.x, - y = v.y, - z = v.z; - te[0] *= x; - te[4] *= y; - te[8] *= z; - te[1] *= x; - te[5] *= y; - te[9] *= z; - te[2] *= x; - te[6] *= y; - te[10] *= z; - te[3] *= x; - te[7] *= y; - te[11] *= z; - return this; } - getMaxScaleOnAxis() { - const te = this.elements; - const scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2]; - const scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6]; - const scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10]; - return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq)); - } + extractBasis( xAxis, yAxis, zAxis ) { - makeTranslation(x, y, z) { - this.set(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1); - return this; - } + xAxis.setFromMatrixColumn( this, 0 ); + yAxis.setFromMatrixColumn( this, 1 ); + zAxis.setFromMatrixColumn( this, 2 ); - makeRotationX(theta) { - const c = Math.cos(theta), - s = Math.sin(theta); - this.set(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1); return this; - } - makeRotationY(theta) { - const c = Math.cos(theta), - s = Math.sin(theta); - this.set(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1); - return this; } - makeRotationZ(theta) { - const c = Math.cos(theta), - s = Math.sin(theta); - this.set(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - return this; - } + makeBasis( xAxis, yAxis, zAxis ) { - makeRotationAxis(axis, angle) { - // Based on http://www.gamedev.net/reference/articles/article1199.asp - const c = Math.cos(angle); - const s = Math.sin(angle); - const t = 1 - c; - const x = axis.x, - y = axis.y, - z = axis.z; - const tx = t * x, - ty = t * y; - this.set(tx * x + c, tx * y - s * z, tx * z + s * y, 0, tx * y + s * z, ty * y + c, ty * z - s * x, 0, tx * z - s * y, ty * z + s * x, t * z * z + c, 0, 0, 0, 0, 1); - return this; - } + 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 + ); - makeScale(x, y, z) { - this.set(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1); return this; - } - makeShear(xy, xz, yx, yz, zx, zy) { - this.set(1, yx, zx, 0, xy, 1, zy, 0, xz, yz, 1, 0, 0, 0, 0, 1); - return this; } - compose(position, quaternion, scale) { - const te = this.elements; - const x = quaternion._x, - y = quaternion._y, - z = quaternion._z, - w = quaternion._w; - const x2 = x + x, - y2 = y + y, - z2 = z + z; - const xx = x * x2, - xy = x * y2, - xz = x * z2; - const yy = y * y2, - yz = y * z2, - zz = z * z2; - const wx = w * x2, - wy = w * y2, - wz = w * z2; - const sx = scale.x, - sy = scale.y, - sz = scale.z; - te[0] = (1 - (yy + zz)) * sx; - te[1] = (xy + wz) * sx; - te[2] = (xz - wy) * sx; - te[3] = 0; - te[4] = (xy - wz) * sy; - te[5] = (1 - (xx + zz)) * sy; - te[6] = (yz + wx) * sy; - te[7] = 0; - te[8] = (xz + wy) * sz; - te[9] = (yz - wx) * sz; - te[10] = (1 - (xx + yy)) * sz; - te[11] = 0; - te[12] = position.x; - te[13] = position.y; - te[14] = position.z; - te[15] = 1; - return this; - } - - decompose(position, quaternion, scale) { - const te = this.elements; + extractRotation( m ) { - let sx = _v1$5.set(te[0], te[1], te[2]).length(); + // this method does not support reflection matrices - const sy = _v1$5.set(te[4], te[5], te[6]).length(); + const te = this.elements; + const me = m.elements; - const sz = _v1$5.set(te[8], te[9], te[10]).length(); // if determine is negative, we need to invert one scale + 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; + te[ 3 ] = 0; - 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 + te[ 4 ] = me[ 4 ] * scaleY; + te[ 5 ] = me[ 5 ] * scaleY; + te[ 6 ] = me[ 6 ] * scaleY; + te[ 7 ] = 0; - _m1$2.copy(this); + te[ 8 ] = me[ 8 ] * scaleZ; + te[ 9 ] = me[ 9 ] * scaleZ; + te[ 10 ] = me[ 10 ] * scaleZ; + te[ 11 ] = 0; + + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; - const invSX = 1 / sx; - const invSY = 1 / sy; - const invSZ = 1 / sz; - _m1$2.elements[0] *= invSX; - _m1$2.elements[1] *= invSX; - _m1$2.elements[2] *= invSX; - _m1$2.elements[4] *= invSY; - _m1$2.elements[5] *= invSY; - _m1$2.elements[6] *= invSY; - _m1$2.elements[8] *= invSZ; - _m1$2.elements[9] *= invSZ; - _m1$2.elements[10] *= invSZ; - quaternion.setFromRotationMatrix(_m1$2); - scale.x = sx; - scale.y = sy; - scale.z = sz; return this; + } - makePerspective(left, right, top, bottom, near, far) { - if (far === undefined) { - console.warn('THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.'); - } + makeRotationFromEuler( euler ) { const te = this.elements; - const x = 2 * near / (right - left); - const y = 2 * near / (top - bottom); - const a = (right + left) / (right - left); - const b = (top + bottom) / (top - bottom); - const c = -(far + near) / (far - near); - const d = -2 * far * near / (far - near); - te[0] = x; - te[4] = 0; - te[8] = a; - te[12] = 0; - te[1] = 0; - te[5] = y; - te[9] = b; - te[13] = 0; - te[2] = 0; - te[6] = 0; - te[10] = c; - te[14] = d; - te[3] = 0; - te[7] = 0; - te[11] = -1; - te[15] = 0; - return this; - } - - makeOrthographic(left, right, top, bottom, near, far) { - const te = this.elements; - const w = 1.0 / (right - left); - const h = 1.0 / (top - bottom); - const p = 1.0 / (far - near); - const x = (right + left) * w; - const y = (top + bottom) * h; - const z = (far + near) * p; - te[0] = 2 * w; - te[4] = 0; - te[8] = 0; - te[12] = -x; - te[1] = 0; - te[5] = 2 * h; - te[9] = 0; - te[13] = -y; - te[2] = 0; - te[6] = 0; - te[10] = -2 * p; - te[14] = -z; - te[3] = 0; - te[7] = 0; - te[11] = 0; - te[15] = 1; - return this; - } - - equals(matrix) { - const te = this.elements; - const me = matrix.elements; - for (let i = 0; i < 16; i++) { - if (te[i] !== me[i]) return false; - } + const x = euler.x, y = euler.y, z = euler.z; + const a = Math.cos( x ), b = Math.sin( x ); + const c = Math.cos( y ), d = Math.sin( y ); + const e = Math.cos( z ), f = Math.sin( z ); - return true; - } + if ( euler.order === 'XYZ' ) { - fromArray(array, offset = 0) { - for (let i = 0; i < 16; i++) { - this.elements[i] = array[i + offset]; - } + const ae = a * e, af = a * f, be = b * e, bf = b * f; - return this; - } + te[ 0 ] = c * e; + te[ 4 ] = - c * f; + te[ 8 ] = d; - toArray(array = [], offset = 0) { - const te = this.elements; - array[offset] = te[0]; - array[offset + 1] = te[1]; - array[offset + 2] = te[2]; - array[offset + 3] = te[3]; - array[offset + 4] = te[4]; - array[offset + 5] = te[5]; - array[offset + 6] = te[6]; - array[offset + 7] = te[7]; - array[offset + 8] = te[8]; - array[offset + 9] = te[9]; - array[offset + 10] = te[10]; - array[offset + 11] = te[11]; - array[offset + 12] = te[12]; - array[offset + 13] = te[13]; - array[offset + 14] = te[14]; - array[offset + 15] = te[15]; - return array; - } + te[ 1 ] = af + be * d; + te[ 5 ] = ae - bf * d; + te[ 9 ] = - b * c; - } + te[ 2 ] = bf - ae * d; + te[ 6 ] = be + af * d; + te[ 10 ] = a * c; - const _v1$5 = /*@__PURE__*/new Vector3(); + } else if ( euler.order === 'YXZ' ) { - const _m1$2 = /*@__PURE__*/new Matrix4(); + const ce = c * e, cf = c * f, de = d * e, df = d * f; - const _zero = /*@__PURE__*/new Vector3(0, 0, 0); + te[ 0 ] = ce + df * b; + te[ 4 ] = de * b - cf; + te[ 8 ] = a * d; - const _one = /*@__PURE__*/new Vector3(1, 1, 1); + te[ 1 ] = a * f; + te[ 5 ] = a * e; + te[ 9 ] = - b; - const _x = /*@__PURE__*/new Vector3(); + te[ 2 ] = cf * b - de; + te[ 6 ] = df + ce * b; + te[ 10 ] = a * c; - const _y = /*@__PURE__*/new Vector3(); + } else if ( euler.order === 'ZXY' ) { - const _z = /*@__PURE__*/new Vector3(); + const ce = c * e, cf = c * f, de = d * e, df = d * f; - const _matrix$1 = /*@__PURE__*/new Matrix4(); + te[ 0 ] = ce - df * b; + te[ 4 ] = - a * f; + te[ 8 ] = de + cf * b; - const _quaternion$3 = /*@__PURE__*/new Quaternion(); + te[ 1 ] = cf + de * b; + te[ 5 ] = a * e; + te[ 9 ] = df - ce * b; - class Euler { - constructor(x = 0, y = 0, z = 0, order = Euler.DefaultOrder) { - this.isEuler = true; - this._x = x; - this._y = y; - this._z = z; - this._order = order; - } + te[ 2 ] = - a * d; + te[ 6 ] = b; + te[ 10 ] = a * c; - get x() { - return this._x; - } + } else if ( euler.order === 'ZYX' ) { - set x(value) { - this._x = value; + const ae = a * e, af = a * f, be = b * e, bf = b * f; - this._onChangeCallback(); - } + te[ 0 ] = c * e; + te[ 4 ] = be * d - af; + te[ 8 ] = ae * d + bf; - get y() { - return this._y; - } + te[ 1 ] = c * f; + te[ 5 ] = bf * d + ae; + te[ 9 ] = af * d - be; - set y(value) { - this._y = value; + te[ 2 ] = - d; + te[ 6 ] = b * c; + te[ 10 ] = a * c; - this._onChangeCallback(); - } + } else if ( euler.order === 'YZX' ) { - get z() { - return this._z; - } + const ac = a * c, ad = a * d, bc = b * c, bd = b * d; - set z(value) { - this._z = value; + te[ 0 ] = c * e; + te[ 4 ] = bd - ac * f; + te[ 8 ] = bc * f + ad; - this._onChangeCallback(); - } + te[ 1 ] = f; + te[ 5 ] = a * e; + te[ 9 ] = - b * e; - get order() { - return this._order; - } + te[ 2 ] = - d * e; + te[ 6 ] = ad * f + bc; + te[ 10 ] = ac - bd * f; - set order(value) { - this._order = value; + } else if ( euler.order === 'XZY' ) { - this._onChangeCallback(); - } + const ac = a * c, ad = a * d, bc = b * c, bd = b * d; - set(x, y, z, order = this._order) { - this._x = x; - this._y = y; - this._z = z; - this._order = order; + te[ 0 ] = c * e; + te[ 4 ] = - f; + te[ 8 ] = d * e; - this._onChangeCallback(); + te[ 1 ] = ac * f + bd; + te[ 5 ] = a * e; + te[ 9 ] = ad * f - bc; - return this; - } + te[ 2 ] = bc * f - ad; + te[ 6 ] = b * e; + te[ 10 ] = bd * f + ac; - 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; + // bottom row + te[ 3 ] = 0; + te[ 7 ] = 0; + te[ 11 ] = 0; - this._onChangeCallback(); + // last column + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; return this; + } - setFromRotationMatrix(m, order = this._order, update = true) { - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - const te = m.elements; - const m11 = te[0], - m12 = te[4], - m13 = te[8]; - const m21 = te[1], - m22 = te[5], - m23 = te[9]; - const m31 = te[2], - m32 = te[6], - m33 = te[10]; - - switch (order) { - case 'XYZ': - this._y = Math.asin(clamp(m13, -1, 1)); + makeRotationFromQuaternion( q ) { - if (Math.abs(m13) < 0.9999999) { - this._x = Math.atan2(-m23, m33); - this._z = Math.atan2(-m12, m11); - } else { - this._x = Math.atan2(m32, m22); - this._z = 0; - } + return this.compose( _zero, q, _one ); - break; + } - case 'YXZ': - this._x = Math.asin(-clamp(m23, -1, 1)); + lookAt( eye, target, up ) { - if (Math.abs(m23) < 0.9999999) { - this._y = Math.atan2(m13, m33); - this._z = Math.atan2(m21, m22); - } else { - this._y = Math.atan2(-m31, m11); - this._z = 0; - } + const te = this.elements; - break; + _z.subVectors( eye, target ); - case 'ZXY': - this._x = Math.asin(clamp(m32, -1, 1)); + if ( _z.lengthSq() === 0 ) { - if (Math.abs(m32) < 0.9999999) { - this._y = Math.atan2(-m31, m33); - this._z = Math.atan2(-m12, m22); - } else { - this._y = 0; - this._z = Math.atan2(m21, m11); - } + // eye and target are in the same position - break; + _z.z = 1; - case 'ZYX': - this._y = Math.asin(-clamp(m31, -1, 1)); + } - if (Math.abs(m31) < 0.9999999) { - this._x = Math.atan2(m32, m33); - this._z = Math.atan2(m21, m11); - } else { - this._x = 0; - this._z = Math.atan2(-m12, m22); - } + _z.normalize(); + _x.crossVectors( up, _z ); - break; + if ( _x.lengthSq() === 0 ) { - case 'YZX': - this._z = Math.asin(clamp(m21, -1, 1)); + // up and z are parallel - if (Math.abs(m21) < 0.9999999) { - this._x = Math.atan2(-m23, m22); - this._y = Math.atan2(-m31, m11); - } else { - this._x = 0; - this._y = Math.atan2(m13, m33); - } + if ( Math.abs( up.z ) === 1 ) { - break; + _z.x += 0.0001; - case 'XZY': - this._z = Math.asin(-clamp(m12, -1, 1)); + } else { - if (Math.abs(m12) < 0.9999999) { - this._x = Math.atan2(m32, m22); - this._y = Math.atan2(m13, m11); - } else { - this._x = Math.atan2(-m23, m33); - this._y = 0; - } + _z.z += 0.0001; - break; + } + + _z.normalize(); + _x.crossVectors( up, _z ); - default: - console.warn('THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order); } - this._order = order; - if (update === true) this._onChangeCallback(); - return this; - } + _x.normalize(); + _y.crossVectors( _z, _x ); - setFromQuaternion(q, order, update) { - _matrix$1.makeRotationFromQuaternion(q); + te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x; + te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y; + te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z; - return this.setFromRotationMatrix(_matrix$1, order, update); - } + return this; - 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); + multiply( m ) { - return this.setFromQuaternion(_quaternion$3, newOrder); - } + return this.multiplyMatrices( this, m ); - 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]; + premultiply( m ) { - this._onChangeCallback(); + return this.multiplyMatrices( m, this ); - return this; } - toArray(array = [], offset = 0) { - array[offset] = this._x; - array[offset + 1] = this._y; - array[offset + 2] = this._z; - array[offset + 3] = this._order; - return array; - } + multiplyMatrices( a, b ) { - _onChange(callback) { - this._onChangeCallback = callback; - return this; - } + const ae = a.elements; + const be = b.elements; + const te = this.elements; - _onChangeCallback() {} + const a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; + const a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; + const a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; + const a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; - *[Symbol.iterator]() { - yield this._x; - yield this._y; - yield this._z; - yield this._order; - } // @deprecated since r138, 02cf0df1cb4575d5842fef9c85bb5a89fe020d53 + const b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; + const b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; + const b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; + const b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; + te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; + te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; + te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; + te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; - toVector3() { - console.error('THREE.Euler: .toVector3() has been removed. Use Vector3.setFromEuler() instead'); - } + te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; + te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; + te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; + te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; - } + te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; + te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; + te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; + te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; - Euler.DefaultOrder = 'XYZ'; - Euler.RotationOrders = ['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX']; + te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; + te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; + te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; + te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; - class Layers { - constructor() { - this.mask = 1 | 0; - } + return this; - set(channel) { - this.mask = (1 << channel | 0) >>> 0; } - enable(channel) { - this.mask |= 1 << channel | 0; - } + multiplyScalar( s ) { - enableAll() { - this.mask = 0xffffffff | 0; - } + const te = this.elements; - toggle(channel) { - this.mask ^= 1 << channel | 0; - } + te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; + te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; + te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; + te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; - disable(channel) { - this.mask &= ~(1 << channel | 0); - } + return this; - disableAll() { - this.mask = 0; } - test(layers) { - return (this.mask & layers.mask) !== 0; - } + determinant() { - isEnabled(channel) { - return (this.mask & (1 << channel | 0)) !== 0; - } + const te = this.elements; - } + const n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; + const n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; + const n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; + const n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; - let _object3DId = 0; + //TODO: make this more efficient + //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) - const _v1$4 = /*@__PURE__*/new Vector3(); + 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 + ) + + ); - const _q1 = /*@__PURE__*/new Quaternion(); + } - const _m1$1 = /*@__PURE__*/new Matrix4(); + transpose() { - const _target = /*@__PURE__*/new Vector3(); + const te = this.elements; + let tmp; - const _position$3 = /*@__PURE__*/new Vector3(); + tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; + tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; + tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; - const _scale$2 = /*@__PURE__*/new Vector3(); + tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; + tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; + tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; - const _quaternion$2 = /*@__PURE__*/new Quaternion(); + return this; - const _xAxis = /*@__PURE__*/new Vector3(1, 0, 0); + } - const _yAxis = /*@__PURE__*/new Vector3(0, 1, 0); + setPosition( x, y, z ) { - const _zAxis = /*@__PURE__*/new Vector3(0, 0, 1); + const te = this.elements; - const _addedEvent = { - type: 'added' - }; - const _removedEvent = { - type: 'removed' - }; + if ( x.isVector3 ) { - class Object3D extends EventDispatcher { - constructor() { - super(); - this.isObject3D = true; - Object.defineProperty(this, 'id', { - value: _object3DId++ - }); - this.uuid = generateUUID(); - this.name = ''; - this.type = 'Object3D'; - this.parent = null; - this.children = []; - this.up = Object3D.DefaultUp.clone(); - const position = new Vector3(); - const rotation = new Euler(); - const quaternion = new Quaternion(); - const scale = new Vector3(1, 1, 1); + te[ 12 ] = x.x; + te[ 13 ] = x.y; + te[ 14 ] = x.z; - function onRotationChange() { - quaternion.setFromEuler(rotation, false); - } + } else { - function onQuaternionChange() { - rotation.setFromQuaternion(quaternion, undefined, false); - } + te[ 12 ] = x; + te[ 13 ] = y; + te[ 14 ] = z; - rotation._onChange(onRotationChange); + } - quaternion._onChange(onQuaternionChange); + return this; - Object.defineProperties(this, { - position: { - configurable: true, - enumerable: true, - value: position - }, - rotation: { - configurable: true, - enumerable: true, - value: rotation - }, - quaternion: { - configurable: true, - enumerable: true, - value: quaternion - }, - scale: { - configurable: true, - enumerable: true, - value: scale - }, - modelViewMatrix: { - value: new Matrix4() - }, - normalMatrix: { - value: new Matrix3() - } - }); - this.matrix = new Matrix4(); - this.matrixWorld = new Matrix4(); - this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; - this.matrixWorldNeedsUpdate = false; - this.layers = new Layers(); - this.visible = true; - this.castShadow = false; - this.receiveShadow = false; - this.frustumCulled = true; - this.renderOrder = 0; - this.animations = []; - this.userData = {}; } - onBeforeRender() {} + invert() { - onAfterRender() {} + // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm + const te = this.elements, - applyMatrix4(matrix) { - if (this.matrixAutoUpdate) this.updateMatrix(); - this.matrix.premultiply(matrix); - this.matrix.decompose(this.position, this.quaternion, this.scale); - } + 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 ], - applyQuaternion(q) { - this.quaternion.premultiply(q); - return this; - } + 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; - setRotationFromAxisAngle(axis, angle) { - // assumes axis is normalized - this.quaternion.setFromAxisAngle(axis, angle); - } + const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; - setRotationFromEuler(euler) { - this.quaternion.setFromEuler(euler, true); - } + if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); - setRotationFromMatrix(m) { - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - this.quaternion.setFromRotationMatrix(m); - } + const detInv = 1 / det; - setRotationFromQuaternion(q) { - // assumes q is normalized - this.quaternion.copy(q); - } + te[ 0 ] = t11 * detInv; + te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv; + te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv; + te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv; - rotateOnAxis(axis, angle) { - // rotate object on axis in object space - // axis is assumed to be normalized - _q1.setFromAxisAngle(axis, angle); + te[ 4 ] = t12 * detInv; + te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv; + te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv; + te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv; - this.quaternion.multiply(_q1); - return this; - } + te[ 8 ] = t13 * detInv; + te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv; + te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv; + te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv; - 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); + te[ 12 ] = t14 * detInv; + te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv; + te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv; + te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv; - this.quaternion.premultiply(_q1); return this; - } - rotateX(angle) { - return this.rotateOnAxis(_xAxis, angle); } - rotateY(angle) { - return this.rotateOnAxis(_yAxis, angle); - } + scale( v ) { - rotateZ(angle) { - return this.rotateOnAxis(_zAxis, angle); - } + const te = this.elements; + const x = v.x, y = v.y, z = v.z; - 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); + te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; + te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; + te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; + te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; - 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); - } + getMaxScaleOnAxis() { - localToWorld(vector) { - return vector.applyMatrix4(this.matrixWorld); - } + const te = this.elements; - worldToLocal(vector) { - return vector.applyMatrix4(_m1$1.copy(this.matrixWorld).invert()); - } + const scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; + const scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; + const scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; - 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); - } + return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); - const parent = this.parent; - this.updateWorldMatrix(true, false); + } - _position$3.setFromMatrixPosition(this.matrixWorld); + makeTranslation( x, y, z ) { - if (this.isCamera || this.isLight) { - _m1$1.lookAt(_position$3, _target, this.up); - } else { - _m1$1.lookAt(_target, _position$3, this.up); - } + this.set( - this.quaternion.setFromRotationMatrix(_m1$1); + 1, 0, 0, x, + 0, 1, 0, y, + 0, 0, 1, z, + 0, 0, 0, 1 - if (parent) { - _m1$1.extractRotation(parent.matrixWorld); + ); - _q1.setFromRotationMatrix(_m1$1); + return this; - this.quaternion.premultiply(_q1.invert()); - } } - add(object) { - if (arguments.length > 1) { - for (let i = 0; i < arguments.length; i++) { - this.add(arguments[i]); - } + makeRotationX( theta ) { - return this; - } + const c = Math.cos( theta ), s = Math.sin( theta ); - if (object === this) { - console.error('THREE.Object3D.add: object can\'t be added as a child of itself.', object); - return this; - } + this.set( - if (object && object.isObject3D) { - if (object.parent !== null) { - object.parent.remove(object); - } + 1, 0, 0, 0, + 0, c, - s, 0, + 0, s, c, 0, + 0, 0, 0, 1 - 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]); - } + makeRotationY( theta ) { - return this; - } + const c = Math.cos( theta ), s = Math.sin( theta ); - const index = this.children.indexOf(object); + this.set( - if (index !== -1) { - object.parent = null; - this.children.splice(index, 1); - object.dispatchEvent(_removedEvent); - } + c, 0, s, 0, + 0, 1, 0, 0, + - s, 0, c, 0, + 0, 0, 0, 1 + + ); return this; + } - removeFromParent() { - const parent = this.parent; + makeRotationZ( theta ) { - if (parent !== null) { - parent.remove(this); - } + const c = Math.cos( theta ), s = Math.sin( theta ); - return this; - } + this.set( - clear() { - for (let i = 0; i < this.children.length; i++) { - const object = this.children[i]; - object.parent = null; - object.dispatchEvent(_removedEvent); - } + c, - s, 0, 0, + s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + + ); - 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); + makeRotationAxis( axis, angle ) { - _m1$1.copy(this.matrixWorld).invert(); + // Based on http://www.gamedev.net/reference/articles/article1199.asp + + const c = Math.cos( angle ); + const s = Math.sin( angle ); + const t = 1 - c; + const x = axis.x, y = axis.y, z = axis.z; + const tx = t * x, ty = t * y; - if (object.parent !== null) { - object.parent.updateWorldMatrix(true, false); + this.set( - _m1$1.multiply(object.parent.matrixWorld); - } + 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 + + ); - 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); - } + makeScale( x, y, z ) { - getObjectByProperty(name, value) { - if (this[name] === value) return this; + this.set( - for (let i = 0, l = this.children.length; i < l; i++) { - const child = this.children[i]; - const object = child.getObjectByProperty(name, value); + x, 0, 0, 0, + 0, y, 0, 0, + 0, 0, z, 0, + 0, 0, 0, 1 - if (object !== undefined) { - return object; - } - } + ); - return undefined; - } + return this; - 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; - } + makeShear( xy, xz, yx, yz, zx, zy ) { - getWorldScale(target) { - this.updateWorldMatrix(true, false); - this.matrixWorld.decompose(_position$3, _quaternion$2, target); - return target; - } + this.set( - getWorldDirection(target) { - this.updateWorldMatrix(true, false); - const e = this.matrixWorld.elements; - return target.set(e[8], e[9], e[10]).normalize(); - } + 1, yx, zx, 0, + xy, 1, zy, 0, + xz, yz, 1, 0, + 0, 0, 0, 1 - raycast() {} + ); - traverse(callback) { - callback(this); - const children = this.children; + return this; - 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); - } - } + compose( position, quaternion, scale ) { - traverseAncestors(callback) { - const parent = this.parent; + const te = this.elements; - if (parent !== null) { - callback(parent); - parent.traverseAncestors(callback); - } - } + const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; + const x2 = x + x, y2 = y + y, z2 = z + z; + const xx = x * x2, xy = x * y2, xz = x * z2; + const yy = y * y2, yz = y * z2, zz = z * z2; + const wx = w * x2, wy = w * y2, wz = w * z2; - updateMatrix() { - this.matrix.compose(this.position, this.quaternion, this.scale); - this.matrixWorldNeedsUpdate = true; - } + const sx = scale.x, sy = scale.y, sz = scale.z; - updateMatrixWorld(force) { - if (this.matrixAutoUpdate) this.updateMatrix(); + te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; + te[ 1 ] = ( xy + wz ) * sx; + te[ 2 ] = ( xz - wy ) * sx; + te[ 3 ] = 0; - if (this.matrixWorldNeedsUpdate || force) { - if (this.parent === null) { - this.matrixWorld.copy(this.matrix); - } else { - this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); - } + te[ 4 ] = ( xy - wz ) * sy; + te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; + te[ 6 ] = ( yz + wx ) * sy; + te[ 7 ] = 0; - this.matrixWorldNeedsUpdate = false; - force = true; - } // update children + te[ 8 ] = ( xz + wy ) * sz; + te[ 9 ] = ( yz - wx ) * sz; + te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; + te[ 11 ] = 0; + te[ 12 ] = position.x; + te[ 13 ] = position.y; + te[ 14 ] = position.z; + te[ 15 ] = 1; - const children = this.children; + return this; - for (let i = 0, l = children.length; i < l; i++) { - children[i].updateMatrixWorld(force); - } } - updateWorldMatrix(updateParents, updateChildren) { - const parent = this.parent; + decompose( position, quaternion, scale ) { - if (updateParents === true && parent !== null) { - parent.updateWorldMatrix(true, false); - } + const te = this.elements; - if (this.matrixAutoUpdate) this.updateMatrix(); + 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(); - if (this.parent === null) { - this.matrixWorld.copy(this.matrix); - } else { - this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); - } // update children + // 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 ]; - if (updateChildren === true) { - const children = this.children; + // scale the rotation part + _m1$2.copy( this ); - for (let i = 0, l = children.length; i < l; i++) { - children[i].updateWorldMatrix(false, true); - } - } - } + const invSX = 1 / sx; + const invSY = 1 / sy; + const invSZ = 1 / sz; - toJSON(meta) { - // meta is a string when called from JSON.stringify - const isRootObject = meta === undefined || typeof meta === 'string'; - const output = {}; // meta is a hash used to collect geometries, materials. - // not providing it implies that this is the root object - // being serialized. + _m1$2.elements[ 0 ] *= invSX; + _m1$2.elements[ 1 ] *= invSX; + _m1$2.elements[ 2 ] *= invSX; - if (isRootObject) { - // initialize meta obj - meta = { - geometries: {}, - materials: {}, - textures: {}, - images: {}, - shapes: {}, - skeletons: {}, - animations: {}, - nodes: {} - }; - output.metadata = { - version: 4.5, - type: 'Object', - generator: 'Object3D.toJSON' - }; - } // standard Object3D serialization + _m1$2.elements[ 4 ] *= invSY; + _m1$2.elements[ 5 ] *= invSY; + _m1$2.elements[ 6 ] *= invSY; + _m1$2.elements[ 8 ] *= invSZ; + _m1$2.elements[ 9 ] *= invSZ; + _m1$2.elements[ 10 ] *= invSZ; - const object = {}; - object.uuid = this.uuid; - object.type = this.type; - if (this.name !== '') object.name = this.name; - if (this.castShadow === true) object.castShadow = true; - if (this.receiveShadow === true) object.receiveShadow = true; - if (this.visible === false) object.visible = false; - if (this.frustumCulled === false) object.frustumCulled = false; - if (this.renderOrder !== 0) object.renderOrder = this.renderOrder; - if (JSON.stringify(this.userData) !== '{}') object.userData = this.userData; - object.layers = this.layers.mask; - object.matrix = this.matrix.toArray(); - if (this.matrixAutoUpdate === false) object.matrixAutoUpdate = false; // object specific properties + quaternion.setFromRotationMatrix( _m1$2 ); - if (this.isInstancedMesh) { - object.type = 'InstancedMesh'; - object.count = this.count; - object.instanceMatrix = this.instanceMatrix.toJSON(); - if (this.instanceColor !== null) object.instanceColor = this.instanceColor.toJSON(); - } // + scale.x = sx; + scale.y = sy; + scale.z = sz; + return this; - function serialize(library, element) { - if (library[element.uuid] === undefined) { - library[element.uuid] = element.toJSON(meta); - } + } - return element.uuid; - } + makePerspective( left, right, top, bottom, near, far ) { - if (this.isScene) { - if (this.background) { - if (this.background.isColor) { - object.background = this.background.toJSON(); - } else if (this.background.isTexture) { - object.background = this.background.toJSON(meta).uuid; - } - } + const te = this.elements; + const x = 2 * near / ( right - left ); + const y = 2 * near / ( top - bottom ); - if (this.environment && this.environment.isTexture) { - object.environment = this.environment.toJSON(meta).uuid; - } - } else if (this.isMesh || this.isLine || this.isPoints) { - object.geometry = serialize(meta.geometries, this.geometry); - const parameters = this.geometry.parameters; + const a = ( right + left ) / ( right - left ); + const b = ( top + bottom ) / ( top - bottom ); + const c = - ( far + near ) / ( far - near ); + const d = - 2 * far * near / ( far - near ); - if (parameters !== undefined && parameters.shapes !== undefined) { - const shapes = parameters.shapes; + te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; + te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; + te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; + te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0; - if (Array.isArray(shapes)) { - for (let i = 0, l = shapes.length; i < l; i++) { - const shape = shapes[i]; - serialize(meta.shapes, shape); - } - } else { - serialize(meta.shapes, shapes); - } - } - } + return this; - 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; - } - } + makeOrthographic( left, right, top, bottom, near, far ) { - if (this.material !== undefined) { - if (Array.isArray(this.material)) { - const uuids = []; + const te = this.elements; + const w = 1.0 / ( right - left ); + const h = 1.0 / ( top - bottom ); + const p = 1.0 / ( far - near ); - for (let i = 0, l = this.material.length; i < l; i++) { - uuids.push(serialize(meta.materials, this.material[i])); - } + const x = ( right + left ) * w; + const y = ( top + bottom ) * h; + const z = ( far + near ) * p; - object.material = uuids; - } else { - object.material = serialize(meta.materials, this.material); - } - } // + te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x; + te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y; + te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z; + te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; + return this; - 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); - } - } // + equals( matrix ) { + const te = this.elements; + const me = matrix.elements; - if (this.animations.length > 0) { - object.animations = []; + for ( let i = 0; i < 16; i ++ ) { - for (let i = 0; i < this.animations.length; i++) { - const animation = this.animations[i]; - object.animations.push(serialize(meta.animations, animation)); - } - } + if ( te[ i ] !== me[ i ] ) return false; - if (isRootObject) { - const geometries = extractFromCache(meta.geometries); - const materials = extractFromCache(meta.materials); - const textures = extractFromCache(meta.textures); - const images = extractFromCache(meta.images); - const shapes = extractFromCache(meta.shapes); - const skeletons = extractFromCache(meta.skeletons); - const animations = extractFromCache(meta.animations); - const nodes = extractFromCache(meta.nodes); - if (geometries.length > 0) output.geometries = geometries; - if (materials.length > 0) output.materials = materials; - if (textures.length > 0) output.textures = textures; - if (images.length > 0) output.images = images; - if (shapes.length > 0) output.shapes = shapes; - if (skeletons.length > 0) output.skeletons = skeletons; - if (animations.length > 0) output.animations = animations; - if (nodes.length > 0) output.nodes = nodes; } - output.object = object; - return output; // extract data from the cache hash - // remove metadata on each item - // and return as array - - function extractFromCache(cache) { - const values = []; - - for (const key in cache) { - const data = cache[key]; - delete data.metadata; - values.push(data); - } + return true; - return values; - } } - clone(recursive) { - return new this.constructor().copy(this, recursive); - } + fromArray( array, offset = 0 ) { - copy(source, recursive = true) { - this.name = source.name; - this.up.copy(source.up); - this.position.copy(source.position); - this.rotation.order = source.rotation.order; - this.quaternion.copy(source.quaternion); - this.scale.copy(source.scale); - this.matrix.copy(source.matrix); - this.matrixWorld.copy(source.matrixWorld); - this.matrixAutoUpdate = source.matrixAutoUpdate; - this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; - this.layers.mask = source.layers.mask; - this.visible = source.visible; - this.castShadow = source.castShadow; - this.receiveShadow = source.receiveShadow; - this.frustumCulled = source.frustumCulled; - this.renderOrder = source.renderOrder; - this.userData = JSON.parse(JSON.stringify(source.userData)); + for ( let i = 0; i < 16; i ++ ) { + + this.elements[ i ] = array[ i + offset ]; - if (recursive === true) { - for (let i = 0; i < source.children.length; i++) { - const child = source.children[i]; - this.add(child.clone()); - } } return this; + } - } + toArray( array = [], offset = 0 ) { - Object3D.DefaultUp = new Vector3(0, 1, 0); - Object3D.DefaultMatrixAutoUpdate = true; + const te = this.elements; - const _v0$1 = /*@__PURE__*/new Vector3(); + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; + array[ offset + 3 ] = te[ 3 ]; - const _v1$3 = /*@__PURE__*/new Vector3(); + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; - const _v2$2 = /*@__PURE__*/new Vector3(); + array[ offset + 8 ] = te[ 8 ]; + array[ offset + 9 ] = te[ 9 ]; + array[ offset + 10 ] = te[ 10 ]; + array[ offset + 11 ] = te[ 11 ]; - const _v3$1 = /*@__PURE__*/new Vector3(); + array[ offset + 12 ] = te[ 12 ]; + array[ offset + 13 ] = te[ 13 ]; + array[ offset + 14 ] = te[ 14 ]; + array[ offset + 15 ] = te[ 15 ]; - const _vab = /*@__PURE__*/new Vector3(); + return array; - const _vac = /*@__PURE__*/new Vector3(); + } - const _vbc = /*@__PURE__*/new Vector3(); + } - const _vap = /*@__PURE__*/new Vector3(); + 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 _vbp = /*@__PURE__*/new Vector3(); + const _matrix$1 = /*@__PURE__*/ new Matrix4(); + const _quaternion$3 = /*@__PURE__*/ new Quaternion(); - const _vcp = /*@__PURE__*/new Vector3(); + class Euler { - class Triangle { - constructor(a = new Vector3(), b = new Vector3(), c = new Vector3()) { - this.a = a; - this.b = b; - this.c = c; - } + constructor( x = 0, y = 0, z = 0, order = Euler.DEFAULT_ORDER ) { - static getNormal(a, b, c, target) { - target.subVectors(c, b); + this.isEuler = true; - _v0$1.subVectors(a, b); + this._x = x; + this._y = y; + this._z = z; + this._order = order; - target.cross(_v0$1); - const targetLengthSq = target.lengthSq(); + } - if (targetLengthSq > 0) { - return target.multiplyScalar(1 / Math.sqrt(targetLengthSq)); - } + get x() { - return target.set(0, 0, 0); - } // static/instance method to calculate barycentric coordinates - // based on: http://www.blackpawn.com/texts/pointinpoly/default.html + return this._x; + } - static getBarycoord(point, a, b, c, target) { - _v0$1.subVectors(c, a); + set x( value ) { - _v1$3.subVectors(b, a); + this._x = value; + this._onChangeCallback(); - _v2$2.subVectors(point, a); + } - const dot00 = _v0$1.dot(_v0$1); + get y() { - const dot01 = _v0$1.dot(_v1$3); + return this._y; - const dot02 = _v0$1.dot(_v2$2); + } - const dot11 = _v1$3.dot(_v1$3); + set y( value ) { - const dot12 = _v1$3.dot(_v2$2); + this._y = value; + this._onChangeCallback(); - const denom = dot00 * dot11 - dot01 * dot01; // 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); - } + get z() { - 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 + return this._z; - 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; - } + set z( value ) { - static getUV(point, p1, p2, p3, uv1, uv2, uv3, target) { - this.getBarycoord(point, p1, p2, p3, _v3$1); - target.set(0, 0); - target.addScaledVector(uv1, _v3$1.x); - target.addScaledVector(uv2, _v3$1.y); - target.addScaledVector(uv3, _v3$1.z); - return target; - } + this._z = value; + this._onChangeCallback(); - static isFrontFacing(a, b, c, direction) { - _v0$1.subVectors(c, b); + } - _v1$3.subVectors(a, b); // strictly front facing + get order() { + return this._order; - 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; - } + set order( value ) { - setFromPointsAndIndices(points, i0, i1, i2) { - this.a.copy(points[i0]); - this.b.copy(points[i1]); - this.c.copy(points[i2]); - return this; - } + this._order = value; + this._onChangeCallback(); - 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); - } + set( x, y, z, order = this._order ) { - copy(triangle) { - this.a.copy(triangle.a); - this.b.copy(triangle.b); - this.c.copy(triangle.c); - return this; - } + this._x = x; + this._y = y; + this._z = z; + this._order = order; - getArea() { - _v0$1.subVectors(this.c, this.b); + this._onChangeCallback(); - _v1$3.subVectors(this.a, this.b); + return this; - return _v0$1.cross(_v1$3).length() * 0.5; } - getMidpoint(target) { - return target.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3); - } + clone() { - getNormal(target) { - return Triangle.getNormal(this.a, this.b, this.c, target); - } + return new this.constructor( this._x, this._y, this._z, this._order ); - 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); - } + copy( euler ) { - getUV(point, uv1, uv2, uv3, target) { - return Triangle.getUV(point, this.a, this.b, this.c, uv1, uv2, uv3, target); - } + this._x = euler._x; + this._y = euler._y; + this._z = euler._z; + this._order = euler._order; - containsPoint(point) { - return Triangle.containsPoint(point, this.a, this.b, this.c); - } + this._onChangeCallback(); - isFrontFacing(direction) { - return Triangle.isFrontFacing(this.a, this.b, this.c, direction); - } + return this; - 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, - // 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. + setFromRotationMatrix( m, order = this._order, update = true ) { - _vab.subVectors(b, a); + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - _vac.subVectors(c, a); + const te = m.elements; + const m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; + const m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; + const m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; - _vap.subVectors(p, a); + switch ( order ) { - const d1 = _vab.dot(_vap); + case 'XYZ': - const d2 = _vac.dot(_vap); + this._y = Math.asin( clamp( m13, - 1, 1 ) ); - if (d1 <= 0 && d2 <= 0) { - // vertex region of A; barycentric coords (1, 0, 0) - return target.copy(a); - } + if ( Math.abs( m13 ) < 0.9999999 ) { - _vbp.subVectors(p, b); + this._x = Math.atan2( - m23, m33 ); + this._z = Math.atan2( - m12, m11 ); - const d3 = _vab.dot(_vbp); + } else { - const d4 = _vac.dot(_vbp); + this._x = Math.atan2( m32, m22 ); + this._z = 0; - if (d3 >= 0 && d4 <= d3) { - // vertex region of B; barycentric coords (0, 1, 0) - return target.copy(b); - } + } - const vc = d1 * d4 - d3 * d2; + break; - if (vc <= 0 && d1 >= 0 && d3 <= 0) { - v = d1 / (d1 - d3); // edge region of AB; barycentric coords (1-v, v, 0) + case 'YXZ': - return target.copy(a).addScaledVector(_vab, v); - } + this._x = Math.asin( - clamp( m23, - 1, 1 ) ); - _vcp.subVectors(p, c); + if ( Math.abs( m23 ) < 0.9999999 ) { - const d5 = _vab.dot(_vcp); + this._y = Math.atan2( m13, m33 ); + this._z = Math.atan2( m21, m22 ); - const d6 = _vac.dot(_vcp); + } else { - if (d6 >= 0 && d5 <= d6) { - // vertex region of C; barycentric coords (0, 0, 1) - return target.copy(c); - } + this._y = Math.atan2( - m31, m11 ); + this._z = 0; - 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) + break; - return target.copy(a).addScaledVector(_vac, w); - } + case 'ZXY': - const va = d3 * d6 - d5 * d4; + this._x = Math.asin( clamp( m32, - 1, 1 ) ); - if (va <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) { - _vbc.subVectors(c, b); + if ( Math.abs( m32 ) < 0.9999999 ) { - w = (d4 - d3) / (d4 - d3 + (d5 - d6)); // edge region of BC; barycentric coords (0, 1-w, w) + this._y = Math.atan2( - m31, m33 ); + this._z = Math.atan2( - m12, m22 ); - return target.copy(b).addScaledVector(_vbc, w); // edge region of BC - } // face region + } else { + this._y = 0; + this._z = Math.atan2( m21, m11 ); - 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); - } + break; - equals(triangle) { - return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c); - } + case 'ZYX': - } + this._y = Math.asin( - clamp( m31, - 1, 1 ) ); - let materialId = 0; + if ( Math.abs( m31 ) < 0.9999999 ) { - class Material extends EventDispatcher { - constructor() { - super(); - this.isMaterial = true; - Object.defineProperty(this, 'id', { - value: materialId++ - }); - this.uuid = generateUUID(); - this.name = ''; - this.type = 'Material'; - this.blending = NormalBlending; - this.side = FrontSide; - this.vertexColors = false; - this.opacity = 1; - this.transparent = false; - this.blendSrc = SrcAlphaFactor; - this.blendDst = OneMinusSrcAlphaFactor; - this.blendEquation = AddEquation; - this.blendSrcAlpha = null; - this.blendDstAlpha = null; - this.blendEquationAlpha = null; - this.depthFunc = LessEqualDepth; - this.depthTest = true; - this.depthWrite = true; - this.stencilWriteMask = 0xff; - this.stencilFunc = AlwaysStencilFunc; - this.stencilRef = 0; - this.stencilFuncMask = 0xff; - this.stencilFail = KeepStencilOp; - this.stencilZFail = KeepStencilOp; - this.stencilZPass = KeepStencilOp; - this.stencilWrite = false; - this.clippingPlanes = null; - this.clipIntersection = false; - this.clipShadows = false; - this.shadowSide = null; - this.colorWrite = true; - this.precision = null; // override the renderer's default precision for this material + this._x = Math.atan2( m32, m33 ); + this._z = Math.atan2( m21, m11 ); - this.polygonOffset = false; - this.polygonOffsetFactor = 0; - this.polygonOffsetUnits = 0; - this.dithering = false; - this.alphaToCoverage = false; - this.premultipliedAlpha = false; - this.visible = true; - this.toneMapped = true; - this.userData = {}; - this.version = 0; - this._alphaTest = 0; - } + } else { - get alphaTest() { - return this._alphaTest; - } + this._x = 0; + this._z = Math.atan2( - m12, m22 ); - set alphaTest(value) { - if (this._alphaTest > 0 !== value > 0) { - this.version++; - } + } - this._alphaTest = value; - } + break; - onBuild() {} + case 'YZX': - onBeforeRender() {} + this._z = Math.asin( clamp( m21, - 1, 1 ) ); - onBeforeCompile() {} + if ( Math.abs( m21 ) < 0.9999999 ) { - customProgramCacheKey() { - return this.onBeforeCompile.toString(); - } + this._x = Math.atan2( - m23, m22 ); + this._y = Math.atan2( - m31, m11 ); + + } else { - setValues(values) { - if (values === undefined) return; + this._x = 0; + this._y = Math.atan2( m13, m33 ); - 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 + break; + case 'XZY': - if (key === 'shading') { - console.warn('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.'); - this.flatShading = newValue === FlatShading ? true : false; - continue; - } + this._z = Math.asin( - clamp( m12, - 1, 1 ) ); - const currentValue = this[key]; + if ( Math.abs( m12 ) < 0.9999999 ) { - if (currentValue === undefined) { - console.warn('THREE.' + this.type + ': \'' + key + '\' is not a property of this material.'); - continue; - } + this._x = Math.atan2( m32, m22 ); + this._y = Math.atan2( m13, m11 ); - if (currentValue && currentValue.isColor) { - currentValue.set(newValue); - } else if (currentValue && currentValue.isVector3 && newValue && newValue.isVector3) { - currentValue.copy(newValue); - } else { - this[key] = newValue; - } - } - } + } else { - toJSON(meta) { - const isRootObject = meta === undefined || typeof meta === 'string'; + this._x = Math.atan2( - m23, m33 ); + this._y = 0; - if (isRootObject) { - meta = { - textures: {}, - images: {} - }; - } + } - const data = { - metadata: { - version: 4.5, - type: 'Material', - generator: 'Material.toJSON' - } - }; // standard Material serialization + break; - data.uuid = this.uuid; - data.type = this.type; - if (this.name !== '') data.name = this.name; - if (this.color && this.color.isColor) data.color = this.color.getHex(); - if (this.roughness !== undefined) data.roughness = this.roughness; - if (this.metalness !== undefined) data.metalness = this.metalness; - if (this.sheen !== undefined) data.sheen = this.sheen; - if (this.sheenColor && this.sheenColor.isColor) data.sheenColor = this.sheenColor.getHex(); - if (this.sheenRoughness !== undefined) data.sheenRoughness = this.sheenRoughness; - if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex(); - if (this.emissiveIntensity && this.emissiveIntensity !== 1) data.emissiveIntensity = this.emissiveIntensity; - if (this.specular && this.specular.isColor) data.specular = this.specular.getHex(); - if (this.specularIntensity !== undefined) data.specularIntensity = this.specularIntensity; - if (this.specularColor && this.specularColor.isColor) data.specularColor = this.specularColor.getHex(); - if (this.shininess !== undefined) data.shininess = this.shininess; - if (this.clearcoat !== undefined) data.clearcoat = this.clearcoat; - if (this.clearcoatRoughness !== undefined) data.clearcoatRoughness = this.clearcoatRoughness; - - if (this.clearcoatMap && this.clearcoatMap.isTexture) { - data.clearcoatMap = this.clearcoatMap.toJSON(meta).uuid; - } - - if (this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture) { - data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON(meta).uuid; - } - - if (this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture) { - data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON(meta).uuid; - data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); - } + default: - if (this.iridescence !== undefined) data.iridescence = this.iridescence; - if (this.iridescenceIOR !== undefined) data.iridescenceIOR = this.iridescenceIOR; - if (this.iridescenceThicknessRange !== undefined) data.iridescenceThicknessRange = this.iridescenceThicknessRange; + console.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order ); - 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; - } + this._order = order; - 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 ( update === true ) this._onChangeCallback(); - if (this.lightMap && this.lightMap.isTexture) { - data.lightMap = this.lightMap.toJSON(meta).uuid; - data.lightMapIntensity = this.lightMapIntensity; - } + return this; - 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; - } + setFromQuaternion( q, order, update ) { - if (this.normalMap && this.normalMap.isTexture) { - data.normalMap = this.normalMap.toJSON(meta).uuid; - data.normalMapType = this.normalMapType; - data.normalScale = this.normalScale.toArray(); - } + _matrix$1.makeRotationFromQuaternion( q ); - if (this.displacementMap && this.displacementMap.isTexture) { - data.displacementMap = this.displacementMap.toJSON(meta).uuid; - data.displacementScale = this.displacementScale; - data.displacementBias = this.displacementBias; - } + return this.setFromRotationMatrix( _matrix$1, order, update ); - 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.attenuationColor !== undefined) data.attenuationColor = this.attenuationColor.getHex(); - if (this.size !== undefined) data.size = this.size; - if (this.shadowSide !== null) data.shadowSide = this.shadowSide; - if (this.sizeAttenuation !== undefined) data.sizeAttenuation = this.sizeAttenuation; - if (this.blending !== NormalBlending) data.blending = this.blending; - if (this.side !== FrontSide) data.side = this.side; - if (this.vertexColors) data.vertexColors = true; - if (this.opacity < 1) data.opacity = this.opacity; - if (this.transparent === true) data.transparent = this.transparent; - data.depthFunc = this.depthFunc; - data.depthTest = this.depthTest; - data.depthWrite = this.depthWrite; - data.colorWrite = this.colorWrite; - data.stencilWrite = this.stencilWrite; - data.stencilWriteMask = this.stencilWriteMask; - data.stencilFunc = this.stencilFunc; - data.stencilRef = this.stencilRef; - data.stencilFuncMask = this.stencilFuncMask; - data.stencilFail = this.stencilFail; - data.stencilZFail = this.stencilZFail; - data.stencilZPass = this.stencilZPass; // rotation (SpriteMaterial) - - if (this.rotation !== undefined && this.rotation !== 0) data.rotation = this.rotation; - if (this.polygonOffset === true) data.polygonOffset = true; - if (this.polygonOffsetFactor !== 0) data.polygonOffsetFactor = this.polygonOffsetFactor; - if (this.polygonOffsetUnits !== 0) data.polygonOffsetUnits = this.polygonOffsetUnits; - if (this.linewidth !== undefined && this.linewidth !== 1) data.linewidth = this.linewidth; - if (this.dashSize !== undefined) data.dashSize = this.dashSize; - if (this.gapSize !== undefined) data.gapSize = this.gapSize; - if (this.scale !== undefined) data.scale = this.scale; - if (this.dithering === true) data.dithering = true; - if (this.alphaTest > 0) data.alphaTest = this.alphaTest; - if (this.alphaToCoverage === true) data.alphaToCoverage = this.alphaToCoverage; - if (this.premultipliedAlpha === true) data.premultipliedAlpha = this.premultipliedAlpha; - if (this.wireframe === true) data.wireframe = this.wireframe; - if (this.wireframeLinewidth > 1) data.wireframeLinewidth = this.wireframeLinewidth; - if (this.wireframeLinecap !== 'round') data.wireframeLinecap = this.wireframeLinecap; - if (this.wireframeLinejoin !== 'round') data.wireframeLinejoin = this.wireframeLinejoin; - if (this.flatShading === true) data.flatShading = this.flatShading; - 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 - - function extractFromCache(cache) { - const values = []; + } - for (const key in cache) { - const data = cache[key]; - delete data.metadata; - values.push(data); - } + setFromVector3( v, order = this._order ) { - return values; - } + return this.set( v.x, v.y, v.z, order ); - 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; - } + } + + reorder( newOrder ) { + + // WARNING: this discards revolution information -bhouston + + _quaternion$3.setFromEuler( this ); + + return this.setFromQuaternion( _quaternion$3, newOrder ); - return data; } - clone() { - return new this.constructor().copy(this); + equals( euler ) { + + return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); + } - copy(source) { - this.name = source.name; - this.blending = source.blending; - this.side = source.side; - this.vertexColors = source.vertexColors; - this.opacity = source.opacity; - this.transparent = source.transparent; - this.blendSrc = source.blendSrc; - this.blendDst = source.blendDst; - this.blendEquation = source.blendEquation; - this.blendSrcAlpha = source.blendSrcAlpha; - this.blendDstAlpha = source.blendDstAlpha; - this.blendEquationAlpha = source.blendEquationAlpha; - this.depthFunc = source.depthFunc; - this.depthTest = source.depthTest; - this.depthWrite = source.depthWrite; - this.stencilWriteMask = source.stencilWriteMask; - this.stencilFunc = source.stencilFunc; - this.stencilRef = source.stencilRef; - this.stencilFuncMask = source.stencilFuncMask; - this.stencilFail = source.stencilFail; - this.stencilZFail = source.stencilZFail; - this.stencilZPass = source.stencilZPass; - this.stencilWrite = source.stencilWrite; - const srcPlanes = source.clippingPlanes; - let dstPlanes = null; + fromArray( array ) { - if (srcPlanes !== null) { - const n = srcPlanes.length; - dstPlanes = new Array(n); + this._x = array[ 0 ]; + this._y = array[ 1 ]; + this._z = array[ 2 ]; + if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; - for (let i = 0; i !== n; ++i) { - dstPlanes[i] = srcPlanes[i].clone(); - } - } + this._onChangeCallback(); - this.clippingPlanes = dstPlanes; - this.clipIntersection = source.clipIntersection; - this.clipShadows = source.clipShadows; - this.shadowSide = source.shadowSide; - this.colorWrite = source.colorWrite; - this.precision = source.precision; - this.polygonOffset = source.polygonOffset; - this.polygonOffsetFactor = source.polygonOffsetFactor; - this.polygonOffsetUnits = source.polygonOffsetUnits; - this.dithering = source.dithering; - this.alphaTest = source.alphaTest; - this.alphaToCoverage = source.alphaToCoverage; - this.premultipliedAlpha = source.premultipliedAlpha; - this.visible = source.visible; - this.toneMapped = source.toneMapped; - this.userData = JSON.parse(JSON.stringify(source.userData)); return this; - } - dispose() { - this.dispatchEvent({ - type: 'dispose' - }); } - set needsUpdate(value) { - if (value === true) this.version++; - } // @deprecated since r131, f5803c62cc4a29d90744e9dc7811d086e354c1d8 + toArray( array = [], offset = 0 ) { + array[ offset ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._order; + + return array; - get vertexTangents() { - console.warn('THREE.' + this.type + ': .vertexTangents has been removed.'); - return false; } - set vertexTangents(value) { - console.warn('THREE.' + this.type + ': .vertexTangents has been removed.'); + _onChange( callback ) { + + this._onChangeCallback = callback; + + return this; + } - } + _onChangeCallback() {} - Material.fromType = function - /*type*/ - () { - // TODO: Behavior added in Materials.js - return null; - }; + *[ Symbol.iterator ]() { - class MeshBasicMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshBasicMaterial = true; - this.type = 'MeshBasicMaterial'; - this.color = new Color(0xffffff); // emissive + yield this._x; + yield this._y; + yield this._z; + yield this._order; - this.map = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; - this.specularMap = null; - this.alphaMap = null; - this.envMap = null; - this.combine = MultiplyOperation; - this.reflectivity = 1; - this.refractionRatio = 0.98; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; - this.fog = true; - 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.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; } } - const _vector$9 = /*@__PURE__*/new Vector3(); + Euler.DEFAULT_ORDER = 'XYZ'; - const _vector2$1 = /*@__PURE__*/new Vector2(); + class Layers { - class BufferAttribute { - constructor(array, itemSize, normalized) { - if (Array.isArray(array)) { - throw new TypeError('THREE.BufferAttribute: array should be a Typed Array.'); - } + constructor() { + + this.mask = 1 | 0; - this.isBufferAttribute = true; - this.name = ''; - this.array = array; - this.itemSize = itemSize; - this.count = array !== undefined ? array.length / itemSize : 0; - this.normalized = normalized === true; - this.usage = StaticDrawUsage; - this.updateRange = { - offset: 0, - count: -1 - }; - this.version = 0; } - onUploadCallback() {} + set( channel ) { - set needsUpdate(value) { - if (value === true) this.version++; - } + this.mask = ( 1 << channel | 0 ) >>> 0; - setUsage(value) { - this.usage = value; - return this; } - copy(source) { - this.name = source.name; - this.array = new source.array.constructor(source.array); - this.itemSize = source.itemSize; - this.count = source.count; - this.normalized = source.normalized; - this.usage = source.usage; - return this; + enable( channel ) { + + this.mask |= 1 << channel | 0; + } - copyAt(index1, attribute, index2) { - index1 *= this.itemSize; - index2 *= attribute.itemSize; + enableAll() { - for (let i = 0, l = this.itemSize; i < l; i++) { - this.array[index1 + i] = attribute.array[index2 + i]; - } + this.mask = 0xffffffff | 0; - return this; } - copyArray(array) { - this.array.set(array); - return this; + toggle( channel ) { + + this.mask ^= 1 << channel | 0; + } - copyColorsArray(colors) { - const array = this.array; - let offset = 0; + disable( channel ) { - for (let i = 0, l = colors.length; i < l; i++) { - let color = colors[i]; + this.mask &= ~ ( 1 << channel | 0 ); - 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; - } + disableAll() { + + this.mask = 0; - return this; } - copyVector2sArray(vectors) { - const array = this.array; - let offset = 0; + test( layers ) { - for (let i = 0, l = vectors.length; i < l; i++) { - let vector = vectors[i]; + return ( this.mask & layers.mask ) !== 0; - if (vector === undefined) { - console.warn('THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i); - vector = new Vector2(); - } + } - array[offset++] = vector.x; - array[offset++] = vector.y; - } + isEnabled( channel ) { + + return ( this.mask & ( 1 << channel | 0 ) ) !== 0; - 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]; + let _object3DId = 0; - if (vector === undefined) { - console.warn('THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i); - vector = new Vector3(); - } + const _v1$4 = /*@__PURE__*/ new Vector3(); + const _q1 = /*@__PURE__*/ new Quaternion(); + const _m1$1 = /*@__PURE__*/ new Matrix4(); + const _target = /*@__PURE__*/ new Vector3(); - array[offset++] = vector.x; - array[offset++] = vector.y; - array[offset++] = vector.z; - } + const _position$3 = /*@__PURE__*/ new Vector3(); + const _scale$2 = /*@__PURE__*/ new Vector3(); + const _quaternion$2 = /*@__PURE__*/ new Quaternion(); - return this; - } + const _xAxis = /*@__PURE__*/ new Vector3( 1, 0, 0 ); + const _yAxis = /*@__PURE__*/ new Vector3( 0, 1, 0 ); + const _zAxis = /*@__PURE__*/ new Vector3( 0, 0, 1 ); - copyVector4sArray(vectors) { - const array = this.array; - let offset = 0; + const _addedEvent = { type: 'added' }; + const _removedEvent = { type: 'removed' }; - for (let i = 0, l = vectors.length; i < l; i++) { - let vector = vectors[i]; + class Object3D extends EventDispatcher { - if (vector === undefined) { - console.warn('THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i); - vector = new Vector4(); - } + constructor() { - array[offset++] = vector.x; - array[offset++] = vector.y; - array[offset++] = vector.z; - array[offset++] = vector.w; - } + super(); - return this; - } + this.isObject3D = true; - applyMatrix3(m) { - if (this.itemSize === 2) { - for (let i = 0, l = this.count; i < l; i++) { - _vector2$1.fromBufferAttribute(this, i); + Object.defineProperty( this, 'id', { value: _object3DId ++ } ); - _vector2$1.applyMatrix3(m); + this.uuid = generateUUID(); - 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); + this.name = ''; + this.type = 'Object3D'; - _vector$9.applyMatrix3(m); + this.parent = null; + this.children = []; - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); - } - } + this.up = Object3D.DEFAULT_UP.clone(); - return this; - } + const position = new Vector3(); + const rotation = new Euler(); + const quaternion = new Quaternion(); + const scale = new Vector3( 1, 1, 1 ); - applyMatrix4(m) { - for (let i = 0, l = this.count; i < l; i++) { - _vector$9.fromBufferAttribute(this, i); + function onRotationChange() { - _vector$9.applyMatrix4(m); + quaternion.setFromEuler( rotation, false ); - 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); + function onQuaternionChange() { - _vector$9.applyNormalMatrix(m); + rotation.setFromQuaternion( quaternion, undefined, false ); - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } - return this; - } + rotation._onChange( onRotationChange ); + quaternion._onChange( onQuaternionChange ); + + Object.defineProperties( this, { + position: { + configurable: true, + enumerable: true, + value: position + }, + rotation: { + configurable: true, + enumerable: true, + value: rotation + }, + quaternion: { + configurable: true, + enumerable: true, + value: quaternion + }, + scale: { + configurable: true, + enumerable: true, + value: scale + }, + modelViewMatrix: { + value: new Matrix4() + }, + normalMatrix: { + value: new Matrix3() + } + } ); + + this.matrix = new Matrix4(); + this.matrixWorld = new Matrix4(); - transformDirection(m) { - for (let i = 0, l = this.count; i < l; i++) { - _vector$9.fromBufferAttribute(this, i); + this.matrixAutoUpdate = Object3D.DEFAULT_MATRIX_AUTO_UPDATE; + this.matrixWorldNeedsUpdate = false; - _vector$9.transformDirection(m); + this.matrixWorldAutoUpdate = Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; // checked by the renderer - this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); - } + this.layers = new Layers(); + this.visible = true; - return this; - } + this.castShadow = false; + this.receiveShadow = false; - set(value, offset = 0) { - this.array.set(value, offset); - return this; - } + this.frustumCulled = true; + this.renderOrder = 0; - getX(index) { - return this.array[index * this.itemSize]; - } + this.animations = []; - setX(index, x) { - this.array[index * this.itemSize] = x; - return this; - } + this.userData = {}; - getY(index) { - return this.array[index * this.itemSize + 1]; } - setY(index, y) { - this.array[index * this.itemSize + 1] = y; - return this; - } + onBeforeRender( /* renderer, scene, camera, geometry, material, group */ ) {} - getZ(index) { - return this.array[index * this.itemSize + 2]; - } + onAfterRender( /* renderer, scene, camera, geometry, material, group */ ) {} - setZ(index, z) { - this.array[index * this.itemSize + 2] = z; - return this; - } + applyMatrix4( matrix ) { - getW(index) { - return this.array[index * this.itemSize + 3]; - } + if ( this.matrixAutoUpdate ) this.updateMatrix(); - setW(index, w) { - this.array[index * this.itemSize + 3] = w; - return this; - } + this.matrix.premultiply( matrix ); - setXY(index, x, y) { - index *= this.itemSize; - this.array[index + 0] = x; - this.array[index + 1] = y; - return this; - } + this.matrix.decompose( this.position, this.quaternion, this.scale ); - setXYZ(index, x, y, z) { - index *= this.itemSize; - this.array[index + 0] = x; - this.array[index + 1] = y; - this.array[index + 2] = z; - return this; } - setXYZW(index, x, y, z, w) { - index *= this.itemSize; - this.array[index + 0] = x; - this.array[index + 1] = y; - this.array[index + 2] = z; - this.array[index + 3] = w; - return this; - } + applyQuaternion( q ) { + + this.quaternion.premultiply( q ); - onUpload(callback) { - this.onUploadCallback = callback; return this; - } - clone() { - return new this.constructor(this.array, this.itemSize).copy(this); } - toJSON() { - const data = { - itemSize: this.itemSize, - type: this.array.constructor.name, - array: Array.prototype.slice.call(this.array), - normalized: this.normalized - }; - if (this.name !== '') data.name = this.name; - if (this.usage !== StaticDrawUsage) data.usage = this.usage; - if (this.updateRange.offset !== 0 || this.updateRange.count !== -1) data.updateRange = this.updateRange; - return data; - } + setRotationFromAxisAngle( axis, angle ) { - } // + // assumes axis is normalized + this.quaternion.setFromAxisAngle( axis, angle ); - 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); - } + setRotationFromEuler( euler ) { - } + this.quaternion.setFromEuler( euler, true ); - class Uint8ClampedBufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Uint8ClampedArray(array), itemSize, normalized); } - } + setRotationFromMatrix( m ) { - class Int16BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Int16Array(array), itemSize, normalized); - } + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - } + this.quaternion.setFromRotationMatrix( m ); - class Uint16BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Uint16Array(array), itemSize, normalized); } - } + setRotationFromQuaternion( q ) { - class Int32BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Int32Array(array), itemSize, normalized); - } + // assumes q is normalized - } + this.quaternion.copy( q ); - class Uint32BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Uint32Array(array), itemSize, normalized); } - } + rotateOnAxis( axis, angle ) { - class Float16BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Uint16Array(array), itemSize, normalized); - this.isFloat16BufferAttribute = true; - } + // rotate object on axis in object space + // axis is assumed to be normalized - } + _q1.setFromAxisAngle( axis, angle ); - class Float32BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Float32Array(array), itemSize, normalized); - } + this.quaternion.multiply( _q1 ); - } + return this; - class Float64BufferAttribute extends BufferAttribute { - constructor(array, itemSize, normalized) { - super(new Float64Array(array), itemSize, normalized); } - } // + rotateOnWorldAxis( axis, angle ) { - let _id$1 = 0; + // rotate object on axis in world space + // axis is assumed to be normalized + // method assumes no rotated parent - const _m1 = /*@__PURE__*/new Matrix4(); + _q1.setFromAxisAngle( axis, angle ); - const _obj = /*@__PURE__*/new Object3D(); + this.quaternion.premultiply( _q1 ); - const _offset = /*@__PURE__*/new Vector3(); + return this; - const _box$1 = /*@__PURE__*/new Box3(); + } - const _boxMorphTargets = /*@__PURE__*/new Box3(); + rotateX( angle ) { - const _vector$8 = /*@__PURE__*/new Vector3(); + return this.rotateOnAxis( _xAxis, angle ); - class BufferGeometry extends EventDispatcher { - constructor() { - super(); - this.isBufferGeometry = true; - Object.defineProperty(this, 'id', { - value: _id$1++ - }); - this.uuid = generateUUID(); - this.name = ''; - this.type = 'BufferGeometry'; - this.index = null; - this.attributes = {}; - this.morphAttributes = {}; - this.morphTargetsRelative = false; - this.groups = []; - this.boundingBox = null; - this.boundingSphere = null; - this.drawRange = { - start: 0, - count: Infinity - }; - this.userData = {}; } - getIndex() { - return this.index; - } + rotateY( angle ) { - setIndex(index) { - if (Array.isArray(index)) { - this.index = new (arrayNeedsUint32(index) ? Uint32BufferAttribute : Uint16BufferAttribute)(index, 1); - } else { - this.index = index; - } + return this.rotateOnAxis( _yAxis, angle ); - return this; } - getAttribute(name) { - return this.attributes[name]; - } + rotateZ( angle ) { + + return this.rotateOnAxis( _zAxis, angle ); - setAttribute(name, attribute) { - this.attributes[name] = attribute; - return this; } - deleteAttribute(name) { - delete this.attributes[name]; + 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 ); + + this.position.add( _v1$4.multiplyScalar( distance ) ); + return this; - } - hasAttribute(name) { - return this.attributes[name] !== undefined; } - addGroup(start, count, materialIndex = 0) { - this.groups.push({ - start: start, - count: count, - materialIndex: materialIndex - }); - } + translateX( distance ) { - clearGroups() { - this.groups = []; - } + return this.translateOnAxis( _xAxis, distance ); - setDrawRange(start, count) { - this.drawRange.start = start; - this.drawRange.count = count; } - applyMatrix4(matrix) { - const position = this.attributes.position; + translateY( distance ) { - if (position !== undefined) { - position.applyMatrix4(matrix); - position.needsUpdate = true; - } + return this.translateOnAxis( _yAxis, distance ); - const normal = this.attributes.normal; + } - if (normal !== undefined) { - const normalMatrix = new Matrix3().getNormalMatrix(matrix); - normal.applyNormalMatrix(normalMatrix); - normal.needsUpdate = true; - } + translateZ( distance ) { - const tangent = this.attributes.tangent; + return this.translateOnAxis( _zAxis, distance ); - if (tangent !== undefined) { - tangent.transformDirection(matrix); - tangent.needsUpdate = true; - } + } - if (this.boundingBox !== null) { - this.computeBoundingBox(); - } + localToWorld( vector ) { - if (this.boundingSphere !== null) { - this.computeBoundingSphere(); - } + this.updateWorldMatrix( true, false ); + + return vector.applyMatrix4( this.matrixWorld ); - return this; } - applyQuaternion(q) { - _m1.makeRotationFromQuaternion(q); + worldToLocal( vector ) { - this.applyMatrix4(_m1); - return this; - } + this.updateWorldMatrix( true, false ); - rotateX(angle) { - // rotate geometry around world x-axis - _m1.makeRotationX(angle); + return vector.applyMatrix4( _m1$1.copy( this.matrixWorld ).invert() ); - this.applyMatrix4(_m1); - return this; } - rotateY(angle) { - // rotate geometry around world y-axis - _m1.makeRotationY(angle); + lookAt( x, y, z ) { - this.applyMatrix4(_m1); - return this; - } + // This method does not support objects having non-uniformly-scaled parent(s) - rotateZ(angle) { - // rotate geometry around world z-axis - _m1.makeRotationZ(angle); + if ( x.isVector3 ) { - this.applyMatrix4(_m1); - return this; - } + _target.copy( x ); - translate(x, y, z) { - // translate geometry - _m1.makeTranslation(x, y, z); + } else { - this.applyMatrix4(_m1); - return this; - } + _target.set( x, y, z ); - scale(x, y, z) { - // scale geometry - _m1.makeScale(x, y, z); + } - this.applyMatrix4(_m1); - return this; - } + const parent = this.parent; - lookAt(vector) { - _obj.lookAt(vector); + this.updateWorldMatrix( true, false ); - _obj.updateMatrix(); + _position$3.setFromMatrixPosition( this.matrixWorld ); - this.applyMatrix4(_obj.matrix); - return this; - } + if ( this.isCamera || this.isLight ) { - center() { - this.computeBoundingBox(); - this.boundingBox.getCenter(_offset).negate(); - this.translate(_offset.x, _offset.y, _offset.z); - return this; - } + _m1$1.lookAt( _position$3, _target, this.up ); - setFromPoints(points) { - const position = []; + } else { + + _m1$1.lookAt( _target, _position$3, this.up ); - 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; - } + this.quaternion.setFromRotationMatrix( _m1$1 ); - computeBoundingBox() { - if (this.boundingBox === null) { - this.boundingBox = new Box3(); - } + if ( parent ) { - const position = this.attributes.position; - const morphAttributesPosition = this.morphAttributes.position; + _m1$1.extractRotation( parent.matrixWorld ); + _q1.setFromRotationMatrix( _m1$1 ); + this.quaternion.premultiply( _q1.invert() ); - 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 - - if (morphAttributesPosition) { - for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { - const morphAttribute = morphAttributesPosition[i]; + } - _box$1.setFromBufferAttribute(morphAttribute); + add( object ) { - if (this.morphTargetsRelative) { - _vector$8.addVectors(this.boundingBox.min, _box$1.min); + if ( arguments.length > 1 ) { - this.boundingBox.expandByPoint(_vector$8); + for ( let i = 0; i < arguments.length; i ++ ) { - _vector$8.addVectors(this.boundingBox.max, _box$1.max); + this.add( arguments[ i ] ); - this.boundingBox.expandByPoint(_vector$8); - } else { - this.boundingBox.expandByPoint(_box$1.min); - this.boundingBox.expandByPoint(_box$1.max); - } - } } - } 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); - } - } + return this; - computeBoundingSphere() { - if (this.boundingSphere === null) { - this.boundingSphere = new Sphere(); } - const position = this.attributes.position; - const morphAttributesPosition = this.morphAttributes.position; + if ( object === this ) { + + console.error( 'THREE.Object3D.add: object can\'t be added as a child of itself.', object ); + return this; - 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; + if ( object && object.isObject3D ) { - _box$1.setFromBufferAttribute(position); // process morph attributes if present + if ( object.parent !== null ) { + object.parent.remove( object ); - if (morphAttributesPosition) { - for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { - const morphAttribute = morphAttributesPosition[i]; + } - _boxMorphTargets.setFromBufferAttribute(morphAttribute); + object.parent = this; + this.children.push( object ); - if (this.morphTargetsRelative) { - _vector$8.addVectors(_box$1.min, _boxMorphTargets.min); + object.dispatchEvent( _addedEvent ); - _box$1.expandByPoint(_vector$8); + } else { - _vector$8.addVectors(_box$1.max, _boxMorphTargets.max); + console.error( 'THREE.Object3D.add: object not an instance of THREE.Object3D.', object ); - _box$1.expandByPoint(_vector$8); - } else { - _box$1.expandByPoint(_boxMorphTargets.min); + } - _box$1.expandByPoint(_boxMorphTargets.max); - } - } - } + return this; - _box$1.getCenter(center); // second, try to find a boundingSphere with a radius smaller than the - // boundingSphere of the boundingBox: sqrt(3) smaller in the best case + } + remove( object ) { - let maxRadiusSq = 0; + if ( arguments.length > 1 ) { - for (let i = 0, il = position.count; i < il; i++) { - _vector$8.fromBufferAttribute(position, i); + for ( let i = 0; i < arguments.length; i ++ ) { - maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8)); - } // process morph attributes if present + this.remove( arguments[ i ] ); + } - if (morphAttributesPosition) { - for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { - const morphAttribute = morphAttributesPosition[i]; - const morphTargetsRelative = this.morphTargetsRelative; + return this; - for (let j = 0, jl = morphAttribute.count; j < jl; j++) { - _vector$8.fromBufferAttribute(morphAttribute, j); + } - if (morphTargetsRelative) { - _offset.fromBufferAttribute(position, j); + const index = this.children.indexOf( object ); - _vector$8.add(_offset); - } + if ( index !== - 1 ) { - maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8)); - } - } - } + object.parent = null; + this.children.splice( index, 1 ); - this.boundingSphere.radius = Math.sqrt(maxRadiusSq); + object.dispatchEvent( _removedEvent ); - 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 - // (per vertex tangents) + return this; - 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; + removeFromParent() { - if (this.hasAttribute('tangent') === false) { - this.setAttribute('tangent', new BufferAttribute(new Float32Array(4 * nVertices), 4)); - } + const parent = this.parent; - const tangents = this.getAttribute('tangent').array; - const tan1 = [], - tan2 = []; + if ( parent !== null ) { - for (let i = 0; i < nVertices; i++) { - tan1[i] = new Vector3(); - tan2[i] = new Vector3(); - } + parent.remove( this ); - 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(); - - function handleTriangle(a, b, c) { - vA.fromArray(positions, a * 3); - vB.fromArray(positions, b * 3); - vC.fromArray(positions, c * 3); - uvA.fromArray(uvs, a * 2); - uvB.fromArray(uvs, b * 2); - uvC.fromArray(uvs, c * 2); - vB.sub(vA); - 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 - - if (!isFinite(r)) return; - sdir.copy(vB).multiplyScalar(uvC.y).addScaledVector(vC, -uvB.y).multiplyScalar(r); - tdir.copy(vC).multiplyScalar(uvB.x).addScaledVector(vB, -uvC.x).multiplyScalar(r); - tan1[a].add(sdir); - tan1[b].add(sdir); - tan1[c].add(sdir); - tan2[a].add(tdir); - tan2[b].add(tdir); - tan2[c].add(tdir); } - let groups = this.groups; + return this; - 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; + clear() { - for (let j = start, jl = start + count; j < jl; j += 3) { - handleTriangle(indices[j + 0], indices[j + 1], indices[j + 2]); - } - } + for ( let i = 0; i < this.children.length; i ++ ) { - const tmp = new Vector3(), - tmp2 = new Vector3(); - const n = new Vector3(), - n2 = new Vector3(); + const object = this.children[ i ]; - function handleVertex(v) { - n.fromArray(normals, v * 3); - n2.copy(n); - const t = tan1[v]; // Gram-Schmidt orthogonalize + object.parent = null; - tmp.copy(t); - tmp.sub(n.multiplyScalar(n.dot(t))).normalize(); // Calculate handedness + object.dispatchEvent( _removedEvent ); - tmp2.crossVectors(n2, t); - const test = tmp2.dot(tan2[v]); - const w = test < 0.0 ? -1.0 : 1.0; - tangents[v * 4] = tmp.x; - tangents[v * 4 + 1] = tmp.y; - 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; + this.children.length = 0; + + return this; + - for (let j = start, jl = start + count; j < jl; j += 3) { - handleVertex(indices[j + 0]); - handleVertex(indices[j + 1]); - handleVertex(indices[j + 2]); - } - } } - computeVertexNormals() { - const index = this.index; - const positionAttribute = this.getAttribute('position'); + attach( object ) { - if (positionAttribute !== undefined) { - let normalAttribute = this.getAttribute('normal'); + // adds object as a child of this, while maintaining the object's world transform - 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(); - const nA = new Vector3(), - nB = new Vector3(), - nC = new Vector3(); - const cb = new Vector3(), - ab = new Vector3(); // indexed elements - - if (index) { - for (let i = 0, il = index.count; i < il; i += 3) { - const vA = index.getX(i + 0); - const vB = index.getX(i + 1); - const vC = index.getX(i + 2); - pA.fromBufferAttribute(positionAttribute, vA); - pB.fromBufferAttribute(positionAttribute, vB); - pC.fromBufferAttribute(positionAttribute, vC); - cb.subVectors(pC, pB); - ab.subVectors(pA, pB); - cb.cross(ab); - nA.fromBufferAttribute(normalAttribute, vA); - nB.fromBufferAttribute(normalAttribute, vB); - nC.fromBufferAttribute(normalAttribute, vC); - nA.add(cb); - nB.add(cb); - nC.add(cb); - normalAttribute.setXYZ(vA, nA.x, nA.y, nA.z); - normalAttribute.setXYZ(vB, nB.x, nB.y, nB.z); - normalAttribute.setXYZ(vC, nC.x, nC.y, nC.z); - } - } else { - // non-indexed elements (unconnected triangle soup) - for (let i = 0, il = positionAttribute.count; i < il; i += 3) { - pA.fromBufferAttribute(positionAttribute, i + 0); - pB.fromBufferAttribute(positionAttribute, i + 1); - pC.fromBufferAttribute(positionAttribute, i + 2); - cb.subVectors(pC, pB); - ab.subVectors(pA, pB); - cb.cross(ab); - normalAttribute.setXYZ(i + 0, cb.x, cb.y, cb.z); - normalAttribute.setXYZ(i + 1, cb.x, cb.y, cb.z); - normalAttribute.setXYZ(i + 2, cb.x, cb.y, cb.z); - } - } + // Note: This method does not support scene graphs having non-uniformly-scaled nodes(s) - this.normalizeNormals(); - normalAttribute.needsUpdate = true; - } - } + this.updateWorldMatrix( true, false ); - merge(geometry, offset) { - if (!(geometry && geometry.isBufferGeometry)) { - console.error('THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry); - return; - } + _m1$1.copy( this.matrixWorld ).invert(); - if (offset === undefined) { - offset = 0; - console.warn('THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.'); - } + if ( object.parent !== null ) { - const attributes = this.attributes; + object.parent.updateWorldMatrix( true, false ); - 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); + _m1$1.multiply( object.parent.matrixWorld ); - for (let i = 0, j = attributeOffset; i < length; i++, j++) { - attributeArray1[j] = attributeArray2[i]; - } } - return this; - } + object.applyMatrix4( _m1$1 ); - normalizeNormals() { - const normals = this.attributes.normal; + this.add( object ); - for (let i = 0, il = normals.count; i < il; i++) { - _vector$8.fromBufferAttribute(normals, i); + object.updateWorldMatrix( false, true ); - _vector$8.normalize(); + return this; - normals.setXYZ(i, _vector$8.x, _vector$8.y, _vector$8.z); - } } - toNonIndexed() { - function convertBufferAttribute(attribute, indices) { - const array = attribute.array; - const itemSize = attribute.itemSize; - const normalized = attribute.normalized; - const array2 = new array.constructor(indices.length * itemSize); - let index = 0, - index2 = 0; + getObjectById( id ) { - 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; - } + return this.getObjectByProperty( 'id', id ); - for (let j = 0; j < itemSize; j++) { - array2[index2++] = array[index++]; - } - } + } - return new BufferAttribute(array2, itemSize, normalized); - } // + getObjectByName( name ) { + return this.getObjectByProperty( 'name', name ); - 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 + getObjectByProperty( name, value ) { - for (const name in attributes) { - const attribute = attributes[name]; - const newAttribute = convertBufferAttribute(attribute, indices); - geometry2.setAttribute(name, newAttribute); - } // morph attributes + if ( this[ name ] === value ) return this; + for ( let i = 0, l = this.children.length; i < l; i ++ ) { - const morphAttributes = this.morphAttributes; + const child = this.children[ i ]; + const object = child.getObjectByProperty( name, value ); - for (const name in morphAttributes) { - const morphArray = []; - const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes + if ( object !== undefined ) { + + return object; - for (let i = 0, il = morphAttribute.length; i < il; i++) { - const attribute = morphAttribute[i]; - const newAttribute = convertBufferAttribute(attribute, indices); - morphArray.push(newAttribute); } - geometry2.morphAttributes[name] = morphArray; } - geometry2.morphTargetsRelative = this.morphTargetsRelative; // groups + return undefined; - 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); - } + getObjectsByProperty( name, value ) { - return geometry2; - } + let result = []; - toJSON() { - const data = { - metadata: { - version: 4.5, - type: 'BufferGeometry', - generator: 'BufferGeometry.toJSON' - } - }; // standard BufferGeometry serialization + if ( this[ name ] === value ) result.push( this ); - 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; + for ( let i = 0, l = this.children.length; i < l; i ++ ) { - if (this.parameters !== undefined) { - const parameters = this.parameters; + const childResult = this.children[ i ].getObjectsByProperty( name, value ); + + if ( childResult.length > 0 ) { + + result = result.concat( childResult ); - 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 + } + return result; - 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) - }; - } + getWorldPosition( target ) { - const attributes = this.attributes; + this.updateWorldMatrix( true, false ); - for (const key in attributes) { - const attribute = attributes[key]; - data.data.attributes[key] = attribute.toJSON(data.data); - } + return target.setFromMatrixPosition( this.matrixWorld ); - const morphAttributes = {}; - let hasMorphAttributes = false; + } - for (const key in this.morphAttributes) { - const attributeArray = this.morphAttributes[key]; - const array = []; + getWorldQuaternion( target ) { - for (let i = 0, il = attributeArray.length; i < il; i++) { - const attribute = attributeArray[i]; - array.push(attribute.toJSON(data.data)); - } + this.updateWorldMatrix( true, false ); - if (array.length > 0) { - morphAttributes[key] = array; - hasMorphAttributes = true; - } - } + this.matrixWorld.decompose( _position$3, target, _scale$2 ); - if (hasMorphAttributes) { - data.data.morphAttributes = morphAttributes; - data.data.morphTargetsRelative = this.morphTargetsRelative; - } + return target; - const groups = this.groups; + } - if (groups.length > 0) { - data.data.groups = JSON.parse(JSON.stringify(groups)); - } + getWorldScale( target ) { - const boundingSphere = this.boundingSphere; + this.updateWorldMatrix( true, false ); - if (boundingSphere !== null) { - data.data.boundingSphere = { - center: boundingSphere.center.toArray(), - radius: boundingSphere.radius - }; - } + this.matrixWorld.decompose( _position$3, _quaternion$2, target ); - return data; - } + return target; - 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 - - const data = {}; // name + getWorldDirection( target ) { - this.name = source.name; // index + this.updateWorldMatrix( true, false ); - const index = source.index; + const e = this.matrixWorld.elements; - if (index !== null) { - this.setIndex(index.clone(data)); - } // attributes + return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize(); + } - const attributes = source.attributes; + raycast( /* raycaster, intersects */ ) {} - for (const name in attributes) { - const attribute = attributes[name]; - this.setAttribute(name, attribute.clone(data)); - } // morph attributes + traverse( callback ) { + callback( this ); - const morphAttributes = source.morphAttributes; + const children = this.children; - for (const name in morphAttributes) { - const array = []; - const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes + for ( let i = 0, l = children.length; i < l; i ++ ) { - for (let i = 0, l = morphAttribute.length; i < l; i++) { - array.push(morphAttribute[i].clone(data)); - } + children[ i ].traverse( callback ); - this.morphAttributes[name] = array; } - this.morphTargetsRelative = source.morphTargetsRelative; // groups + } - const groups = source.groups; + traverseVisible( callback ) { - for (let i = 0, l = groups.length; i < l; i++) { - const group = groups[i]; - this.addGroup(group.start, group.count, group.materialIndex); - } // bounding box + if ( this.visible === false ) return; + callback( this ); - const boundingBox = source.boundingBox; + const children = this.children; - if (boundingBox !== null) { - this.boundingBox = boundingBox.clone(); - } // bounding sphere + for ( let i = 0, l = children.length; i < l; i ++ ) { + children[ i ].traverseVisible( callback ); - const boundingSphere = source.boundingSphere; - - if (boundingSphere !== null) { - this.boundingSphere = boundingSphere.clone(); - } // draw range - - - this.drawRange.start = source.drawRange.start; - this.drawRange.count = source.drawRange.count; // 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' - }); - } + traverseAncestors( callback ) { - } + const parent = this.parent; - const _inverseMatrix$2 = /*@__PURE__*/new Matrix4(); + if ( parent !== null ) { - const _ray$2 = /*@__PURE__*/new Ray(); + callback( parent ); - const _sphere$3 = /*@__PURE__*/new Sphere(); + parent.traverseAncestors( callback ); - const _vA$1 = /*@__PURE__*/new Vector3(); + } - const _vB$1 = /*@__PURE__*/new Vector3(); + } - const _vC$1 = /*@__PURE__*/new Vector3(); + updateMatrix() { - const _tempA = /*@__PURE__*/new Vector3(); + this.matrix.compose( this.position, this.quaternion, this.scale ); - const _tempB = /*@__PURE__*/new Vector3(); + this.matrixWorldNeedsUpdate = true; - const _tempC = /*@__PURE__*/new Vector3(); + } - const _morphA = /*@__PURE__*/new Vector3(); + updateMatrixWorld( force ) { - const _morphB = /*@__PURE__*/new Vector3(); + if ( this.matrixAutoUpdate ) this.updateMatrix(); - const _morphC = /*@__PURE__*/new Vector3(); + if ( this.matrixWorldNeedsUpdate || force ) { - const _uvA$1 = /*@__PURE__*/new Vector2(); + if ( this.parent === null ) { - const _uvB$1 = /*@__PURE__*/new Vector2(); + this.matrixWorld.copy( this.matrix ); - const _uvC$1 = /*@__PURE__*/new Vector2(); + } else { - const _intersectionPoint = /*@__PURE__*/new Vector3(); + this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - const _intersectionPointWorld = /*@__PURE__*/new Vector3(); + } - class Mesh extends Object3D { - constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()) { - super(); - this.isMesh = true; - this.type = 'Mesh'; - this.geometry = geometry; - this.material = material; - this.updateMorphTargets(); - } + this.matrixWorldNeedsUpdate = false; - copy(source, recursive) { - super.copy(source, recursive); + force = true; - if (source.morphTargetInfluences !== undefined) { - this.morphTargetInfluences = source.morphTargetInfluences.slice(); } - if (source.morphTargetDictionary !== undefined) { - this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary); - } + // update children - this.material = source.material; - this.geometry = source.geometry; - return this; - } + const children = this.children; - updateMorphTargets() { - const geometry = this.geometry; - const morphAttributes = geometry.morphAttributes; - const keys = Object.keys(morphAttributes); + for ( let i = 0, l = children.length; i < l; i ++ ) { - if (keys.length > 0) { - const morphAttribute = morphAttributes[keys[0]]; + const child = children[ i ]; - if (morphAttribute !== undefined) { - this.morphTargetInfluences = []; - this.morphTargetDictionary = {}; + if ( child.matrixWorldAutoUpdate === true || force === true ) { + + child.updateMatrixWorld( force ); - for (let m = 0, ml = morphAttribute.length; m < ml; m++) { - const name = morphAttribute[m].name || String(m); - this.morphTargetInfluences.push(0); - this.morphTargetDictionary[name] = m; - } } + } - } - 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 (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + updateWorldMatrix( updateParents, updateChildren ) { - _sphere$3.copy(geometry.boundingSphere); + const parent = this.parent; - _sphere$3.applyMatrix4(matrixWorld); + if ( updateParents === true && parent !== null && parent.matrixWorldAutoUpdate === true ) { - if (raycaster.ray.intersectsSphere(_sphere$3) === false) return; // + parent.updateWorldMatrix( true, false ); - _inverseMatrix$2.copy(matrixWorld).invert(); + } - _ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2); // Check boundingBox before continuing + if ( this.matrixAutoUpdate ) this.updateMatrix(); + if ( this.parent === null ) { - if (geometry.boundingBox !== null) { - if (_ray$2.intersectsBox(geometry.boundingBox) === false) return; - } + this.matrixWorld.copy( this.matrix ); - let intersection; - const index = geometry.index; - const position = geometry.attributes.position; - const morphPosition = geometry.morphAttributes.position; - const morphTargetsRelative = geometry.morphTargetsRelative; - const uv = geometry.attributes.uv; - const uv2 = geometry.attributes.uv2; - const groups = geometry.groups; - const drawRange = geometry.drawRange; + } else { - 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 + this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - intersection.face.materialIndex = group.materialIndex; - intersects.push(intersection); - } - } - } - } 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); + // update children - if (intersection) { - intersection.faceIndex = Math.floor(i / 3); // triangle number in indexed buffer semantics + if ( updateChildren === true ) { - 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); + const children = this.children; - if (intersection) { - intersection.faceIndex = Math.floor(j / 3); // triangle number in non-indexed buffer semantics + for ( let i = 0, l = children.length; i < l; i ++ ) { - intersection.face.materialIndex = group.materialIndex; - intersects.push(intersection); - } - } - } - } else { - const start = Math.max(0, drawRange.start); - const end = Math.min(position.count, drawRange.start + drawRange.count); + const child = children[ i ]; - 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 ( child.matrixWorldAutoUpdate === true ) { - if (intersection) { - intersection.faceIndex = Math.floor(i / 3); // triangle number in non-indexed buffer semantics + child.updateWorldMatrix( false, true ); - intersects.push(intersection); - } } + } + } - } - } + } - function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) { - let intersect; + toJSON( meta ) { - if (material.side === BackSide) { - intersect = ray.intersectTriangle(pC, pB, pA, true, point); - } else { - intersect = ray.intersectTriangle(pA, pB, pC, material.side !== DoubleSide, point); - } + // meta is a string when called from JSON.stringify + const isRootObject = ( meta === undefined || typeof meta === 'string' ); - if (intersect === null) return null; + const output = {}; - _intersectionPointWorld.copy(point); + // meta is a hash used to collect geometries, materials. + // not providing it implies that this is the root object + // being serialized. + if ( isRootObject ) { - _intersectionPointWorld.applyMatrix4(object.matrixWorld); + // initialize meta obj + meta = { + geometries: {}, + materials: {}, + textures: {}, + images: {}, + shapes: {}, + skeletons: {}, + animations: {}, + nodes: {} + }; - const distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld); - if (distance < raycaster.near || distance > raycaster.far) return null; - return { - distance: distance, - point: _intersectionPointWorld.clone(), - object: object - }; - } + output.metadata = { + version: 4.5, + type: 'Object', + generator: 'Object3D.toJSON' + }; - function checkBufferGeometryIntersection(object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c) { - _vA$1.fromBufferAttribute(position, a); + } - _vB$1.fromBufferAttribute(position, b); + // standard Object3D serialization - _vC$1.fromBufferAttribute(position, c); + const object = {}; - const morphInfluences = object.morphTargetInfluences; + object.uuid = this.uuid; + object.type = this.type; - if (morphPosition && morphInfluences) { - _morphA.set(0, 0, 0); + if ( this.name !== '' ) object.name = this.name; + if ( this.castShadow === true ) object.castShadow = true; + if ( this.receiveShadow === true ) object.receiveShadow = true; + if ( this.visible === false ) object.visible = false; + if ( this.frustumCulled === false ) object.frustumCulled = false; + if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; + if ( Object.keys( this.userData ).length > 0 ) object.userData = this.userData; - _morphB.set(0, 0, 0); + object.layers = this.layers.mask; + object.matrix = this.matrix.toArray(); - _morphC.set(0, 0, 0); + if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; - for (let i = 0, il = morphPosition.length; i < il; i++) { - const influence = morphInfluences[i]; - const morphAttribute = morphPosition[i]; - if (influence === 0) continue; + // object specific properties - _tempA.fromBufferAttribute(morphAttribute, a); + if ( this.isInstancedMesh ) { - _tempB.fromBufferAttribute(morphAttribute, b); + object.type = 'InstancedMesh'; + object.count = this.count; + object.instanceMatrix = this.instanceMatrix.toJSON(); + if ( this.instanceColor !== null ) object.instanceColor = this.instanceColor.toJSON(); - _tempC.fromBufferAttribute(morphAttribute, c); + } - if (morphTargetsRelative) { - _morphA.addScaledVector(_tempA, influence); + // - _morphB.addScaledVector(_tempB, influence); + function serialize( library, element ) { - _morphC.addScaledVector(_tempC, influence); - } else { - _morphA.addScaledVector(_tempA.sub(_vA$1), influence); + if ( library[ element.uuid ] === undefined ) { - _morphB.addScaledVector(_tempB.sub(_vB$1), influence); + library[ element.uuid ] = element.toJSON( meta ); - _morphC.addScaledVector(_tempC.sub(_vC$1), influence); } + + return element.uuid; + } - _vA$1.add(_morphA); + if ( this.isScene ) { - _vB$1.add(_morphB); + if ( this.background ) { - _vC$1.add(_morphC); - } + if ( this.background.isColor ) { - if (object.isSkinnedMesh) { - object.boneTransform(a, _vA$1); - object.boneTransform(b, _vB$1); - object.boneTransform(c, _vC$1); - } + object.background = this.background.toJSON(); - const intersection = checkIntersection(object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint); + } else if ( this.background.isTexture ) { - if (intersection) { - if (uv) { - _uvA$1.fromBufferAttribute(uv, a); + object.background = this.background.toJSON( meta ).uuid; - _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 ( this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true ) { - if (uv2) { - _uvA$1.fromBufferAttribute(uv2, a); + object.environment = this.environment.toJSON( meta ).uuid; - _uvB$1.fromBufferAttribute(uv2, b); + } - _uvC$1.fromBufferAttribute(uv2, c); + } else if ( this.isMesh || this.isLine || this.isPoints ) { - intersection.uv2 = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2()); - } + object.geometry = serialize( meta.geometries, this.geometry ); - const face = { - a: a, - b: b, - c: c, - normal: new Vector3(), - materialIndex: 0 - }; - Triangle.getNormal(_vA$1, _vB$1, _vC$1, face.normal); - intersection.face = face; - } + const parameters = this.geometry.parameters; - return intersection; - } + if ( parameters !== undefined && parameters.shapes !== undefined ) { - class BoxGeometry extends BufferGeometry { - constructor(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) { - super(); - this.type = 'BoxGeometry'; - this.parameters = { - width: width, - height: height, - depth: depth, - widthSegments: widthSegments, - heightSegments: heightSegments, - depthSegments: depthSegments - }; - const scope = this; // segments + const shapes = parameters.shapes; - widthSegments = Math.floor(widthSegments); - heightSegments = Math.floor(heightSegments); - depthSegments = Math.floor(depthSegments); // buffers + if ( Array.isArray( shapes ) ) { - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // helper variables + for ( let i = 0, l = shapes.length; i < l; i ++ ) { - let numberOfVertices = 0; - let groupStart = 0; // build each side of the box geometry + const shape = shapes[ i ]; - buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px + serialize( meta.shapes, shape ); - 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 + } else { - buildPlane('x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3); // ny + serialize( meta.shapes, shapes ); - 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; - const widthHalf = width / 2; - const heightHalf = height / 2; - const depthHalf = depth / 2; - const gridX1 = gridX + 1; - const gridY1 = gridY + 1; - let vertexCounter = 0; - let groupCount = 0; - const vector = new Vector3(); // generate vertices, normals and uvs + if ( this.isSkinnedMesh ) { - for (let iy = 0; iy < gridY1; iy++) { - const y = iy * segmentHeight - heightHalf; + object.bindMode = this.bindMode; + object.bindMatrix = this.bindMatrix.toArray(); - for (let ix = 0; ix < gridX1; ix++) { - const x = ix * segmentWidth - widthHalf; // set values to correct vector component + if ( this.skeleton !== undefined ) { - vector[u] = x * udir; - vector[v] = y * vdir; - vector[w] = depthHalf; // now apply vector to vertex buffer + serialize( meta.skeletons, this.skeleton ); - vertices.push(vector.x, vector.y, vector.z); // set values to correct vector component + object.skeleton = this.skeleton.uuid; - vector[u] = 0; - vector[v] = 0; - vector[w] = depth > 0 ? 1 : -1; // now apply vector to normal buffer + } - normals.push(vector.x, vector.y, vector.z); // uvs + } - uvs.push(ix / gridX); - uvs.push(1 - iy / gridY); // counters + if ( this.material !== undefined ) { - vertexCounter += 1; - } - } // indices - // 1. you need three indices to draw a single face - // 2. a single segment consists of two faces - // 3. so we need to generate six (2*3) indices per segment + if ( Array.isArray( this.material ) ) { + const uuids = []; - 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 + for ( let i = 0, l = this.material.length; i < l; i ++ ) { - indices.push(a, b, d); - indices.push(b, c, d); // increase counter + uuids.push( serialize( meta.materials, this.material[ i ] ) ); - groupCount += 6; } - } // add a group to the geometry. this will ensure multi material support + object.material = uuids; + + } else { - scope.addGroup(groupStart, groupCount, materialIndex); // calculate new start value for groups + object.material = serialize( meta.materials, this.material ); - 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); - } + // - } + if ( this.children.length > 0 ) { - /** - * Uniform Utilities - */ - function cloneUniforms(src) { - const dst = {}; + object.children = []; - for (const u in src) { - dst[u] = {}; + for ( let i = 0; i < this.children.length; i ++ ) { - for (const p in src[u]) { - const property = src[u][p]; + object.children.push( this.children[ i ].toJSON( meta ).object ); - 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)) { - dst[u][p] = property.slice(); - } else { - dst[u][p] = property; } - } - } - 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; - } // Legacy + // - const UniformsUtils = { - clone: cloneUniforms, - merge: mergeUniforms - }; + if ( this.animations.length > 0 ) { - var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; + object.animations = []; - var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; + for ( let i = 0; i < this.animations.length; i ++ ) { - class ShaderMaterial extends Material { - constructor(parameters) { - super(); - this.isShaderMaterial = true; - this.type = 'ShaderMaterial'; - this.defines = {}; - this.uniforms = {}; - this.vertexShader = default_vertex; - this.fragmentShader = default_fragment; - this.linewidth = 1; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.fog = false; // set to use scene fog + const animation = this.animations[ i ]; - this.lights = false; // set to use scene lights + object.animations.push( serialize( meta.animations, animation ) ); - this.clipping = false; // set to use user-defined clipping planes + } - this.extensions = { - derivatives: false, - // set to use derivatives - fragDepth: false, - // set to use fragment depth values - drawBuffers: false, - // set to use draw buffers - shaderTextureLOD: false // set to use shader texture LOD + } - }; // 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. + if ( isRootObject ) { - this.defaultAttributeValues = { - 'color': [1, 1, 1], - 'uv': [0, 0], - 'uv2': [0, 0] - }; - this.index0AttributeName = undefined; - this.uniformsNeedUpdate = false; - this.glslVersion = null; + const geometries = extractFromCache( meta.geometries ); + const materials = extractFromCache( meta.materials ); + const textures = extractFromCache( meta.textures ); + const images = extractFromCache( meta.images ); + const shapes = extractFromCache( meta.shapes ); + const skeletons = extractFromCache( meta.skeletons ); + const animations = extractFromCache( meta.animations ); + const nodes = extractFromCache( meta.nodes ); - if (parameters !== undefined) { - if (parameters.attributes !== undefined) { - console.error('THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.'); - } + if ( geometries.length > 0 ) output.geometries = geometries; + if ( materials.length > 0 ) output.materials = materials; + if ( textures.length > 0 ) output.textures = textures; + if ( images.length > 0 ) output.images = images; + if ( shapes.length > 0 ) output.shapes = shapes; + if ( skeletons.length > 0 ) output.skeletons = skeletons; + if ( animations.length > 0 ) output.animations = animations; + if ( nodes.length > 0 ) output.nodes = nodes; - this.setValues(parameters); } - } - copy(source) { - super.copy(source); - this.fragmentShader = source.fragmentShader; - this.vertexShader = source.vertexShader; - this.uniforms = cloneUniforms(source.uniforms); - this.defines = Object.assign({}, source.defines); - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.fog = source.fog; - this.lights = source.lights; - this.clipping = source.clipping; - this.extensions = Object.assign({}, source.extensions); - this.glslVersion = source.glslVersion; - return this; - } + output.object = object; - toJSON(meta) { - const data = super.toJSON(meta); - data.glslVersion = this.glslVersion; - data.uniforms = {}; + return output; - for (const name in this.uniforms) { - const uniform = this.uniforms[name]; - const value = uniform.value; + // 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 ); - if (value && value.isTexture) { - data.uniforms[name] = { - type: 't', - value: value.toJSON(meta).uuid - }; - } else if (value && value.isColor) { - data.uniforms[name] = { - type: 'c', - value: value.getHex() - }; - } else if (value && value.isVector2) { - data.uniforms[name] = { - type: 'v2', - value: value.toArray() - }; - } else if (value && value.isVector3) { - data.uniforms[name] = { - type: 'v3', - value: value.toArray() - }; - } else if (value && value.isVector4) { - data.uniforms[name] = { - type: 'v4', - value: value.toArray() - }; - } else if (value && value.isMatrix3) { - data.uniforms[name] = { - type: 'm3', - value: value.toArray() - }; - } else if (value && value.isMatrix4) { - data.uniforms[name] = { - type: 'm4', - value: value.toArray() - }; - } else { - data.uniforms[name] = { - value: value - }; // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far } - } - if (Object.keys(this.defines).length > 0) data.defines = this.defines; - data.vertexShader = this.vertexShader; - data.fragmentShader = this.fragmentShader; - const extensions = {}; + return values; - 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; } - } + clone( recursive ) { - class Camera extends Object3D { - constructor() { - super(); - this.isCamera = true; - this.type = 'Camera'; - this.matrixWorldInverse = new Matrix4(); - this.projectionMatrix = new Matrix4(); - this.projectionMatrixInverse = new Matrix4(); - } + return new this.constructor().copy( this, recursive ); - copy(source, recursive) { - super.copy(source, recursive); - this.matrixWorldInverse.copy(source.matrixWorldInverse); - this.projectionMatrix.copy(source.projectionMatrix); - this.projectionMatrixInverse.copy(source.projectionMatrixInverse); - return this; } - getWorldDirection(target) { - this.updateWorldMatrix(true, false); - const e = this.matrixWorld.elements; - return target.set(-e[8], -e[9], -e[10]).normalize(); - } + copy( source, recursive = true ) { - updateMatrixWorld(force) { - super.updateMatrixWorld(force); - this.matrixWorldInverse.copy(this.matrixWorld).invert(); - } + this.name = source.name; - updateWorldMatrix(updateParents, updateChildren) { - super.updateWorldMatrix(updateParents, updateChildren); - this.matrixWorldInverse.copy(this.matrixWorld).invert(); - } + this.up.copy( source.up ); - clone() { - return new this.constructor().copy(this); - } + this.position.copy( source.position ); + this.rotation.order = source.rotation.order; + this.quaternion.copy( source.quaternion ); + this.scale.copy( source.scale ); - } + this.matrix.copy( source.matrix ); + this.matrixWorld.copy( source.matrixWorld ); - class PerspectiveCamera extends Camera { - constructor(fov = 50, aspect = 1, near = 0.1, far = 2000) { - super(); - this.isPerspectiveCamera = true; - this.type = 'PerspectiveCamera'; - this.fov = fov; - this.zoom = 1; - this.near = near; - this.far = far; - this.focus = 10; - this.aspect = aspect; - this.view = null; - this.filmGauge = 35; // width of the film (default in millimeters) + this.matrixAutoUpdate = source.matrixAutoUpdate; + this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; - this.filmOffset = 0; // horizontal film offset (same unit as gauge) + this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; - this.updateProjectionMatrix(); - } + this.layers.mask = source.layers.mask; + this.visible = source.visible; + + this.castShadow = source.castShadow; + this.receiveShadow = source.receiveShadow; + + this.frustumCulled = source.frustumCulled; + this.renderOrder = source.renderOrder; + + this.userData = JSON.parse( JSON.stringify( source.userData ) ); + + if ( recursive === true ) { + + for ( let i = 0; i < source.children.length; i ++ ) { + + const child = source.children[ i ]; + this.add( child.clone() ); + + } + + } - copy(source, recursive) { - super.copy(source, recursive); - this.fov = source.fov; - this.zoom = source.zoom; - this.near = source.near; - this.far = source.far; - this.focus = source.focus; - this.aspect = source.aspect; - this.view = source.view === null ? null : Object.assign({}, source.view); - this.filmGauge = source.filmGauge; - this.filmOffset = source.filmOffset; return this; + } - /** - * Sets the FOV by focal length in respect to the current .filmGauge. - * - * The default film gauge is 35, so that the focal length can be specified for - * a 35mm (full frame) camera. - * - * Values for focal length and film gauge must have the same unit. - */ + } - setFocalLength(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. - */ + Object3D.DEFAULT_UP = /*@__PURE__*/ new Vector3( 0, 1, 0 ); + Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true; + Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = 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(); - getFocalLength() { - const vExtentSlope = Math.tan(DEG2RAD * 0.5 * this.fov); - return 0.5 * this.getFilmHeight() / vExtentSlope; - } + 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(); - getEffectiveFOV() { - return RAD2DEG * 2 * Math.atan(Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom); - } + class Triangle { - getFilmWidth() { - // film not completely covered in portrait format (aspect < 1) - return this.filmGauge * Math.min(this.aspect, 1); - } + constructor( a = new Vector3(), b = new Vector3(), c = new Vector3() ) { + + this.a = a; + this.b = b; + this.c = c; - 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. - * - * For example, if you have 3x2 monitors and each monitor is 1920x1080 and - * the monitors are in grid like this - * - * +---+---+---+ - * | A | B | C | - * +---+---+---+ - * | D | E | F | - * +---+---+---+ - * - * then for each monitor you would call it like this - * - * const w = 1920; - * const h = 1080; - * const fullWidth = w * 3; - * const fullHeight = h * 2; - * - * --A-- - * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); - * --B-- - * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); - * --C-- - * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); - * --D-- - * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); - * --E-- - * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); - * --F-- - * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); - * - * Note there is no reason monitors have to be the same size or in a grid. - */ + static getNormal( a, b, c, target ) { - setViewOffset(fullWidth, fullHeight, x, y, width, height) { - this.aspect = fullWidth / fullHeight; + target.subVectors( c, b ); + _v0$1.subVectors( a, b ); + target.cross( _v0$1 ); - if (this.view === null) { - this.view = { - enabled: true, - fullWidth: 1, - fullHeight: 1, - offsetX: 0, - offsetY: 0, - width: 1, - height: 1 - }; - } + const targetLengthSq = target.lengthSq(); + if ( targetLengthSq > 0 ) { - this.view.enabled = true; - this.view.fullWidth = fullWidth; - this.view.fullHeight = fullHeight; - this.view.offsetX = x; - this.view.offsetY = y; - this.view.width = width; - this.view.height = height; - this.updateProjectionMatrix(); - } + return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); - clearViewOffset() { - if (this.view !== null) { - this.view.enabled = false; } - this.updateProjectionMatrix(); + return target.set( 0, 0, 0 ); + } - updateProjectionMatrix() { - const near = this.near; - let top = near * Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom; - let height = 2 * top; - let width = this.aspect * height; - let left = -0.5 * width; - const view = this.view; + // 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 ); + + // 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 ); - if (this.view !== null && this.view.enabled) { - const fullWidth = view.fullWidth, - 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(); + 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 + return target.set( 1 - u - v, v, u ); + } - toJSON(meta) { - const data = super.toJSON(meta); - data.object.fov = this.fov; - data.object.zoom = this.zoom; - data.object.near = this.near; - data.object.far = this.far; - data.object.focus = this.focus; - data.object.aspect = this.aspect; - if (this.view !== null) data.object.view = Object.assign({}, this.view); - data.object.filmGauge = this.filmGauge; - data.object.filmOffset = this.filmOffset; - return data; + 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 ) { - const fov = 90, - aspect = 1; + this.getBarycoord( point, p1, p2, p3, _v3$1 ); - class CubeCamera extends Object3D { - constructor(near, far, renderTarget) { - super(); - this.type = 'CubeCamera'; + target.set( 0, 0 ); + target.addScaledVector( uv1, _v3$1.x ); + target.addScaledVector( uv2, _v3$1.y ); + target.addScaledVector( uv3, _v3$1.z ); - if (renderTarget.isWebGLCubeRenderTarget !== true) { - console.error('THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter.'); - return; - } + return target; - 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)); - 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)); - 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)); - 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)); - 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)); - 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)); - this.add(cameraNZ); } - update(renderer, scene) { - if (this.parent === null) this.updateMatrixWorld(); - const renderTarget = this.renderTarget; - const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = this.children; - const currentRenderTarget = renderer.getRenderTarget(); - const currentToneMapping = renderer.toneMapping; - const currentXrEnabled = renderer.xr.enabled; - renderer.toneMapping = NoToneMapping; - renderer.xr.enabled = false; - const generateMipmaps = renderTarget.texture.generateMipmaps; - renderTarget.texture.generateMipmaps = false; - renderer.setRenderTarget(renderTarget, 0); - renderer.render(scene, cameraPX); - renderer.setRenderTarget(renderTarget, 1); - renderer.render(scene, cameraNX); - renderer.setRenderTarget(renderTarget, 2); - renderer.render(scene, cameraPY); - renderer.setRenderTarget(renderTarget, 3); - renderer.render(scene, cameraNY); - renderer.setRenderTarget(renderTarget, 4); - renderer.render(scene, cameraPZ); - renderTarget.texture.generateMipmaps = generateMipmaps; - renderer.setRenderTarget(renderTarget, 5); - renderer.render(scene, cameraNZ); - renderer.setRenderTarget(currentRenderTarget); - renderer.toneMapping = currentToneMapping; - renderer.xr.enabled = currentXrEnabled; - renderTarget.texture.needsPMREMUpdate = true; - } + static isFrontFacing( a, b, c, direction ) { - } + _v0$1.subVectors( c, b ); + _v1$3.subVectors( a, b ); + + // strictly front facing + return ( _v0$1.cross( _v1$3 ).dot( direction ) < 0 ) ? true : false; - class CubeTexture extends Texture { - constructor(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding) { - images = images !== undefined ? images : []; - mapping = mapping !== undefined ? mapping : CubeReflectionMapping; - super(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); - this.isCubeTexture = true; - this.flipY = false; } - get images() { - return this.image; + set( a, b, c ) { + + this.a.copy( a ); + this.b.copy( b ); + this.c.copy( c ); + + return this; + } - set images(value) { - this.image = value; + 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 ) { - class WebGLCubeRenderTarget extends WebGLRenderTarget { - constructor(size, options = {}) { - super(size, size, options); - this.isWebGLCubeRenderTarget = true; - const image = { - width: size, - height: size, - 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) - // 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). + this.a.fromBufferAttribute( attribute, i0 ); + this.b.fromBufferAttribute( attribute, i1 ); + this.c.fromBufferAttribute( attribute, i2 ); - this.texture.isRenderTargetTexture = true; - this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; - this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; - } + return this; - fromEquirectangularTexture(renderer, texture) { - this.texture.type = texture.type; - this.texture.encoding = texture.encoding; - this.texture.generateMipmaps = texture.generateMipmaps; - this.texture.minFilter = texture.minFilter; - this.texture.magFilter = texture.magFilter; - const shader = { - uniforms: { - tEquirect: { - value: null - } - }, - vertexShader: - /* glsl */ - ` + } - varying vec3 vWorldDirection; + clone() { - vec3 transformDirection( in vec3 dir, in mat4 matrix ) { + return new this.constructor().copy( this ); - return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); + } - } + copy( triangle ) { - void main() { + this.a.copy( triangle.a ); + this.b.copy( triangle.b ); + this.c.copy( triangle.c ); - vWorldDirection = transformDirection( position, modelMatrix ); + return this; - #include - #include + } - } - `, - fragmentShader: - /* glsl */ - ` + getArea() { - uniform sampler2D tEquirect; + _v0$1.subVectors( this.c, this.b ); + _v1$3.subVectors( this.a, this.b ); - varying vec3 vWorldDirection; + return _v0$1.cross( _v1$3 ).length() * 0.5; - #include + } - void main() { + getMidpoint( target ) { - vec3 direction = normalize( vWorldDirection ); + return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); - vec2 sampleUV = equirectUv( direction ); + } - gl_FragColor = texture2D( tEquirect, sampleUV ); + getNormal( target ) { - } - ` - }; - const geometry = new BoxGeometry(5, 5, 5); - const material = new ShaderMaterial({ - name: 'CubemapFromEquirect', - uniforms: cloneUniforms(shader.uniforms), - vertexShader: shader.vertexShader, - fragmentShader: shader.fragmentShader, - side: BackSide, - blending: NoBlending - }); - material.uniforms.tEquirect.value = texture; - const mesh = new Mesh(geometry, material); - const currentMinFilter = texture.minFilter; // Avoid blurred poles + return Triangle.getNormal( this.a, this.b, this.c, target ); - if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; - const camera = new CubeCamera(1, 10, this); - camera.update(renderer, mesh); - texture.minFilter = currentMinFilter; - mesh.geometry.dispose(); - mesh.material.dispose(); - return this; } - clear(renderer, color, depth, stencil) { - const currentRenderTarget = renderer.getRenderTarget(); + getPlane( target ) { - for (let i = 0; i < 6; i++) { - renderer.setRenderTarget(this, i); - renderer.clear(color, depth, stencil); - } + return target.setFromCoplanarPoints( this.a, this.b, this.c ); - renderer.setRenderTarget(currentRenderTarget); } - } + getBarycoord( point, target ) { - const _vector1 = /*@__PURE__*/new Vector3(); + return Triangle.getBarycoord( point, this.a, this.b, this.c, target ); - const _vector2 = /*@__PURE__*/new Vector3(); + } - const _normalMatrix = /*@__PURE__*/new Matrix3(); + getUV( point, uv1, uv2, uv3, target ) { - class Plane { - constructor(normal = new Vector3(1, 0, 0), constant = 0) { - this.isPlane = true; // normal is assumed to be normalized + return Triangle.getUV( point, this.a, this.b, this.c, uv1, uv2, uv3, target ); - this.normal = normal; - this.constant = constant; } - set(normal, constant) { - this.normal.copy(normal); - this.constant = constant; - return this; - } + containsPoint( point ) { - setComponents(x, y, z, w) { - this.normal.set(x, y, z); - this.constant = w; - return this; - } + return Triangle.containsPoint( point, this.a, this.b, this.c ); - 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)? + isFrontFacing( direction ) { + return Triangle.isFrontFacing( this.a, this.b, this.c, direction ); - this.setFromNormalAndCoplanarPoint(normal, a); - return this; } - copy(plane) { - this.normal.copy(plane.normal); - this.constant = plane.constant; - return this; - } + intersectsBox( box ) { - 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; - } + return box.intersectsTriangle( this ); - negate() { - this.constant *= -1; - this.normal.negate(); - return this; } - distanceToPoint(point) { - return this.normal.dot(point) + this.constant; - } + closestPointToPoint( p, target ) { - distanceToSphere(sphere) { - return this.distanceToPoint(sphere.center) - sphere.radius; - } + const a = this.a, b = this.b, c = this.c; + let v, w; - projectPoint(point, target) { - return target.copy(this.normal).multiplyScalar(-this.distanceToPoint(point)).add(point); - } + // 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. - intersectLine(line, target) { - const direction = line.delta(_vector1); - const denominator = this.normal.dot(direction); + _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 ) { - 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. + // 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 ); - return null; } - const t = -(line.start.dot(this.normal) + this.constant) / denominator; + 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) + return target.copy( a ).addScaledVector( _vab, v ); - if (t < 0 || t > 1) { - return null; } - return target.copy(direction).multiplyScalar(t).add(line.start); - } + _vcp.subVectors( p, c ); + const d5 = _vab.dot( _vcp ); + const d6 = _vac.dot( _vcp ); + if ( d6 >= 0 && d5 <= d6 ) { - 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; - } + // vertex region of C; barycentric coords (0, 0, 1) + return target.copy( c ); - intersectsBox(box) { - return box.intersectsPlane(this); - } + } - intersectsSphere(sphere) { - return sphere.intersectsPlane(this); - } + const vb = d5 * d2 - d1 * d6; + if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { - coplanarPoint(target) { - return target.copy(this.normal).multiplyScalar(-this.constant); - } + w = d2 / ( d2 - d6 ); + // edge region of AC; barycentric coords (1-w, 0, w) + return target.copy( a ).addScaledVector( _vac, w ); - 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; - } + const va = d3 * d6 - d5 * d4; + if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { - translate(offset) { - this.constant -= offset.dot(this.normal); - return this; - } + _vbc.subVectors( c, b ); + 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 + v = vb * denom; + w = vc * denom; + + return target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w ); - equals(plane) { - return plane.normal.equals(this.normal) && plane.constant === this.constant; } - clone() { - return new this.constructor().copy(this); + equals( triangle ) { + + return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); + } } - const _sphere$2 = /*@__PURE__*/new Sphere(); + let materialId = 0; - const _vector$7 = /*@__PURE__*/new Vector3(); + class Material extends EventDispatcher { + + constructor() { + + super(); + + this.isMaterial = true; + + Object.defineProperty( this, 'id', { value: materialId ++ } ); + + this.uuid = generateUUID(); + + this.name = ''; + this.type = 'Material'; + + this.blending = NormalBlending; + this.side = FrontSide; + this.vertexColors = false; + + this.opacity = 1; + this.transparent = false; + + this.blendSrc = SrcAlphaFactor; + this.blendDst = OneMinusSrcAlphaFactor; + this.blendEquation = AddEquation; + this.blendSrcAlpha = null; + this.blendDstAlpha = null; + this.blendEquationAlpha = null; + + this.depthFunc = LessEqualDepth; + this.depthTest = true; + this.depthWrite = true; + + this.stencilWriteMask = 0xff; + this.stencilFunc = AlwaysStencilFunc; + this.stencilRef = 0; + this.stencilFuncMask = 0xff; + this.stencilFail = KeepStencilOp; + this.stencilZFail = KeepStencilOp; + this.stencilZPass = KeepStencilOp; + this.stencilWrite = false; + + this.clippingPlanes = null; + this.clipIntersection = false; + this.clipShadows = false; + + this.shadowSide = null; + + this.colorWrite = true; + + this.precision = null; // override the renderer's default precision for this material + + this.polygonOffset = false; + this.polygonOffsetFactor = 0; + this.polygonOffsetUnits = 0; + + this.dithering = false; + + this.alphaToCoverage = false; + this.premultipliedAlpha = false; + this.forceSinglePass = false; + + this.visible = true; + + this.toneMapped = true; + + this.userData = {}; + + this.version = 0; + + this._alphaTest = 0; - 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); - planes[1].copy(p1); - planes[2].copy(p2); - planes[3].copy(p3); - planes[4].copy(p4); - planes[5].copy(p5); - return this; + get alphaTest() { + + return this._alphaTest; + } - copy(frustum) { - const planes = this.planes; + set alphaTest( value ) { + + if ( this._alphaTest > 0 !== value > 0 ) { + + this.version ++; - for (let i = 0; i < 6; i++) { - planes[i].copy(frustum.planes[i]); } - return this; + this._alphaTest = value; + } - setFromProjectionMatrix(m) { - const planes = this.planes; - const me = m.elements; - const me0 = me[0], - me1 = me[1], - me2 = me[2], - me3 = me[3]; - const me4 = me[4], - me5 = me[5], - me6 = me[6], - me7 = me[7]; - const me8 = me[8], - me9 = me[9], - me10 = me[10], - me11 = me[11]; - const me12 = me[12], - me13 = me[13], - me14 = me[14], - me15 = me[15]; - planes[0].setComponents(me3 - me0, me7 - me4, me11 - me8, me15 - me12).normalize(); - planes[1].setComponents(me3 + me0, me7 + me4, me11 + me8, me15 + me12).normalize(); - planes[2].setComponents(me3 + me1, me7 + me5, me11 + me9, me15 + me13).normalize(); - planes[3].setComponents(me3 - me1, me7 - me5, me11 - me9, me15 - me13).normalize(); - planes[4].setComponents(me3 - me2, me7 - me6, me11 - me10, me15 - me14).normalize(); - planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize(); - return this; - } - - intersectsObject(object) { - const geometry = object.geometry; - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + onBuild( /* shaderobject, renderer */ ) {} + + onBeforeRender( /* renderer, scene, camera, geometry, object, group */ ) {} + + onBeforeCompile( /* shaderobject, renderer */ ) {} - _sphere$2.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld); + customProgramCacheKey() { + + return this.onBeforeCompile.toString(); - return this.intersectsSphere(_sphere$2); } - intersectsSprite(sprite) { - _sphere$2.center.set(0, 0, 0); + setValues( values ) { - _sphere$2.radius = 0.7071067811865476; + if ( values === undefined ) return; - _sphere$2.applyMatrix4(sprite.matrixWorld); + for ( const key in values ) { - return this.intersectsSphere(_sphere$2); - } + const newValue = values[ key ]; - intersectsSphere(sphere) { - const planes = this.planes; - const center = sphere.center; - const negRadius = -sphere.radius; + if ( newValue === undefined ) { - for (let i = 0; i < 6; i++) { - const distance = planes[i].distanceToPoint(center); + console.warn( 'THREE.Material: \'' + key + '\' parameter is undefined.' ); + continue; - if (distance < negRadius) { - return false; } - } - - return true; - } - intersectsBox(box) { - const planes = this.planes; + const currentValue = this[ key ]; - for (let i = 0; i < 6; i++) { - const plane = planes[i]; // corner at max distance + if ( currentValue === undefined ) { - _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; + console.warn( 'THREE.' + this.type + ': \'' + key + '\' is not a property of this material.' ); + continue; - if (plane.distanceToPoint(_vector$7) < 0) { - return false; } - } - return true; - } + if ( currentValue && currentValue.isColor ) { - containsPoint(point) { - const planes = this.planes; + currentValue.set( newValue ); + + } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { + + currentValue.copy( newValue ); + + } else { + + this[ key ] = newValue; - for (let i = 0; i < 6; i++) { - if (planes[i].distanceToPoint(point) < 0) { - return false; } + } - return true; } - clone() { - return new this.constructor().copy(this); - } + toJSON( meta ) { - } + const isRootObject = ( meta === undefined || typeof meta === 'string' ); - function WebGLAnimation() { - let context = null; - let isAnimating = false; - let animationLoop = null; - let requestId = null; + if ( isRootObject ) { - function onAnimationFrame(time, frame) { - animationLoop(time, frame); - requestId = context.requestAnimationFrame(onAnimationFrame); - } + meta = { + textures: {}, + images: {} + }; - return { - start: function () { - if (isAnimating === true) return; - if (animationLoop === null) return; - requestId = context.requestAnimationFrame(onAnimationFrame); - isAnimating = true; - }, - stop: function () { - context.cancelAnimationFrame(requestId); - isAnimating = false; - }, - setAnimationLoop: function (callback) { - animationLoop = callback; - }, - setContext: function (value) { - context = value; } - }; - } - function WebGLAttributes(gl, capabilities) { - const isWebGL2 = capabilities.isWebGL2; - const buffers = new WeakMap(); + const data = { + metadata: { + version: 4.5, + type: 'Material', + generator: 'Material.toJSON' + } + }; - function createBuffer(attribute, bufferType) { - const array = attribute.array; - const usage = attribute.usage; - const buffer = gl.createBuffer(); - gl.bindBuffer(bufferType, buffer); - gl.bufferData(bufferType, array, usage); - attribute.onUploadCallback(); - let type; + // standard Material serialization + data.uuid = this.uuid; + data.type = this.type; - if (array instanceof Float32Array) { - type = gl.FLOAT; - } else if (array instanceof Uint16Array) { - if (attribute.isFloat16BufferAttribute) { - if (isWebGL2) { - type = gl.HALF_FLOAT; - } else { - throw new Error('THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2.'); - } - } else { - type = gl.UNSIGNED_SHORT; - } - } else if (array instanceof Int16Array) { - type = gl.SHORT; - } else if (array instanceof Uint32Array) { - type = gl.UNSIGNED_INT; - } else if (array instanceof Int32Array) { - type = gl.INT; - } else if (array instanceof Int8Array) { - type = gl.BYTE; - } else if (array instanceof Uint8Array) { - type = gl.UNSIGNED_BYTE; - } else if (array instanceof Uint8ClampedArray) { - type = gl.UNSIGNED_BYTE; - } else { - throw new Error('THREE.WebGLAttributes: Unsupported buffer data format: ' + array); - } + if ( this.name !== '' ) data.name = this.name; - return { - buffer: buffer, - type: type, - bytesPerElement: array.BYTES_PER_ELEMENT, - version: attribute.version - }; - } + if ( this.color && this.color.isColor ) data.color = this.color.getHex(); - function updateBuffer(buffer, attribute, bufferType) { - const array = attribute.array; - const updateRange = attribute.updateRange; - gl.bindBuffer(bufferType, buffer); + if ( this.roughness !== undefined ) data.roughness = this.roughness; + if ( this.metalness !== undefined ) data.metalness = this.metalness; - if (updateRange.count === -1) { - // Not using update ranges - gl.bufferSubData(bufferType, 0, array); - } else { - if (isWebGL2) { - gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array, updateRange.offset, updateRange.count); - } else { - gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array.subarray(updateRange.offset, updateRange.offset + updateRange.count)); - } + if ( this.sheen !== undefined ) data.sheen = this.sheen; + if ( this.sheenColor && this.sheenColor.isColor ) data.sheenColor = this.sheenColor.getHex(); + if ( this.sheenRoughness !== undefined ) data.sheenRoughness = this.sheenRoughness; + if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); + if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; - updateRange.count = -1; // reset range - } - } // + if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); + if ( this.specularIntensity !== undefined ) data.specularIntensity = this.specularIntensity; + if ( this.specularColor && this.specularColor.isColor ) data.specularColor = this.specularColor.getHex(); + if ( this.shininess !== undefined ) data.shininess = this.shininess; + if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat; + if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness; + if ( this.clearcoatMap && this.clearcoatMap.isTexture ) { - function get(attribute) { - if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; - return buffers.get(attribute); - } + data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid; + + } - function remove(attribute) { - if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; - const data = buffers.get(attribute); + if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) { + + data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid; - if (data) { - gl.deleteBuffer(data.buffer); - buffers.delete(attribute); } - } - function update(attribute, bufferType) { - if (attribute.isGLBufferAttribute) { - const cached = buffers.get(attribute); + if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) { - if (!cached || cached.version < attribute.version) { - buffers.set(attribute, { - buffer: attribute.buffer, - type: attribute.type, - bytesPerElement: attribute.elementSize, - version: attribute.version - }); - } + data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid; + data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); - return; } - if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; - const data = buffers.get(attribute); + 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 (data === undefined) { - buffers.set(attribute, createBuffer(attribute, bufferType)); - } else if (data.version < attribute.version) { - updateBuffer(data.buffer, attribute, bufferType); - data.version = attribute.version; } - } - return { - get: get, - remove: remove, - update: update - }; - } + if ( this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture ) { - class PlaneGeometry extends BufferGeometry { - constructor(width = 1, height = 1, widthSegments = 1, heightSegments = 1) { - super(); - this.type = 'PlaneGeometry'; - this.parameters = { - width: width, - height: height, - widthSegments: widthSegments, - heightSegments: heightSegments - }; - const width_half = width / 2; - const height_half = height / 2; - const gridX = Math.floor(widthSegments); - const gridY = Math.floor(heightSegments); - const gridX1 = gridX + 1; - const gridY1 = gridY + 1; - const segment_width = width / gridX; - const segment_height = height / gridY; // + data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON( meta ).uuid; - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; + } - for (let iy = 0; iy < gridY1; iy++) { - const y = iy * segment_height - height_half; + 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; - for (let ix = 0; ix < gridX1; ix++) { - const x = ix * segment_width - width_half; - vertices.push(x, -y, 0); - normals.push(0, 0, 1); - uvs.push(ix / gridX); - uvs.push(1 - iy / gridY); - } } - for (let iy = 0; iy < gridY; iy++) { - for (let ix = 0; ix < gridX; ix++) { - const a = ix + gridX1 * iy; - const b = ix + gridX1 * (iy + 1); - const c = ix + 1 + gridX1 * (iy + 1); - const d = ix + 1 + gridX1 * iy; - indices.push(a, b, d); - indices.push(b, c, d); - } + if ( this.aoMap && this.aoMap.isTexture ) { + + data.aoMap = this.aoMap.toJSON( meta ).uuid; + data.aoMapIntensity = this.aoMapIntensity; + } - this.setIndex(indices); - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - } + if ( this.bumpMap && this.bumpMap.isTexture ) { - static fromJSON(data) { - return new PlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments); - } + data.bumpMap = this.bumpMap.toJSON( meta ).uuid; + data.bumpScale = this.bumpScale; - } + } - var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; + if ( this.normalMap && this.normalMap.isTexture ) { - var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; + data.normalMap = this.normalMap.toJSON( meta ).uuid; + data.normalMapType = this.normalMapType; + data.normalScale = this.normalScale.toArray(); - var alphatest_fragment = "#ifdef USE_ALPHATEST\n\tif ( diffuseColor.a < alphaTest ) discard;\n#endif"; + } - var alphatest_pars_fragment = "#ifdef USE_ALPHATEST\n\tuniform float alphaTest;\n#endif"; + if ( this.displacementMap && this.displacementMap.isTexture ) { - var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\t#endif\n#endif"; + data.displacementMap = this.displacementMap.toJSON( meta ).uuid; + data.displacementScale = this.displacementScale; + data.displacementBias = this.displacementBias; - var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; + } - var begin_vertex = "vec3 transformed = vec3( position );"; + 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; - var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; + 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; - var bsdfs = "vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\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 dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( V * D );\n}\n#ifdef USE_IRIDESCENCE\nvec3 BRDF_GGX_Iridescence( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float iridescence, const in vec3 iridescenceFresnel, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\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 dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = mix(F_Schlick( f0, f90, dotVH ), iridescenceFresnel, iridescence);\n\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( V * D );\n}\n#endif\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\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"; + if ( this.envMap && this.envMap.isTexture ) { - var iridescence_fragment = "#ifdef USE_IRIDESCENCE\nconst mat3 XYZ_TO_REC709 = mat3(\n 3.2404542, -0.9692660, 0.0556434,\n -1.5371385, 1.8760108, -0.2040259,\n -0.4985314, 0.0415560, 1.0572252\n);\nvec3 Fresnel0ToIor( vec3 fresnel0 ) {\n vec3 sqrtF0 = sqrt( fresnel0 );\n return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n}\nvec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n return pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n}\nfloat IorToFresnel0( float transmittedIor, float incidentIor ) {\n return pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n}\nvec3 evalSensitivity( float OPD, vec3 shift ) {\n float phase = 2.0 * PI * OPD * 1.0e-9;\n vec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n vec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n vec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n vec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( -pow2( phase ) * var );\n xyz.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 xyz /= 1.0685e-7;\n vec3 srgb = XYZ_TO_REC709 * xyz;\n return srgb;\n}\nvec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n vec3 I;\n float iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n float sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n float cosTheta2Sq = 1.0 - sinTheta2Sq;\n if ( cosTheta2Sq < 0.0 ) {\n return vec3( 1.0 );\n }\n float cosTheta2 = sqrt( cosTheta2Sq );\n float R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\n float R12 = F_Schlick( R0, 1.0, cosTheta1 );\n float R21 = R12;\n float T121 = 1.0 - R12;\n float phi12 = 0.0;\n if ( iridescenceIOR < outsideIOR ) phi12 = PI;\n float phi21 = PI - phi12;\n vec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) ); vec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n vec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n vec3 phi23 = vec3( 0.0 );\n if ( baseIOR[0] < iridescenceIOR ) phi23[0] = PI;\n if ( baseIOR[1] < iridescenceIOR ) phi23[1] = PI;\n if ( baseIOR[2] < iridescenceIOR ) phi23[2] = PI;\n float OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n vec3 phi = vec3( phi21 ) + phi23;\n vec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n vec3 r123 = sqrt( R123 );\n vec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n vec3 C0 = R12 + Rs;\n I = C0;\n vec3 Cm = Rs - T121;\n for ( int m = 1; m <= 2; ++m ) {\n Cm *= r123;\n vec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n I += Cm * Sm;\n }\n return max( I, vec3( 0.0 ) );\n}\n#endif"; + data.envMap = this.envMap.toJSON( meta ).uuid; - var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 ) * 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"; + if ( this.combine !== undefined ) data.combine = this.combine; - var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; + } - var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; + if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity; + if ( this.reflectivity !== undefined ) data.reflectivity = this.reflectivity; + if ( this.refractionRatio !== undefined ) data.refractionRatio = this.refractionRatio; - var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif"; + if ( this.gradientMap && this.gradientMap.isTexture ) { - var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif"; + data.gradientMap = this.gradientMap.toJSON( meta ).uuid; - var color_fragment = "#if defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#elif defined( USE_COLOR )\n\tdiffuseColor.rgb *= vColor;\n#endif"; + } - var color_pars_fragment = "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR )\n\tvarying vec3 vColor;\n#endif"; + 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 && this.attenuationDistance !== Infinity ) data.attenuationDistance = this.attenuationDistance; + if ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex(); - var 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"; + if ( this.size !== undefined ) data.size = this.size; + if ( this.shadowSide !== null ) data.shadowSide = this.shadowSide; + if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; - var 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"; + if ( this.blending !== NormalBlending ) data.blending = this.blending; + if ( this.side !== FrontSide ) data.side = this.side; + if ( this.vertexColors ) data.vertexColors = true; - 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 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat 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 linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}"; + if ( this.opacity < 1 ) data.opacity = this.opacity; + if ( this.transparent === true ) data.transparent = this.transparent; - 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"; + data.depthFunc = this.depthFunc; + data.depthTest = this.depthTest; + data.depthWrite = this.depthWrite; + data.colorWrite = this.colorWrite; - 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"; + data.stencilWrite = this.stencilWrite; + data.stencilWriteMask = this.stencilWriteMask; + data.stencilFunc = this.stencilFunc; + data.stencilRef = this.stencilRef; + data.stencilFuncMask = this.stencilFuncMask; + data.stencilFail = this.stencilFail; + data.stencilZFail = this.stencilZFail; + data.stencilZPass = this.stencilZPass; - var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif"; + // rotation (SpriteMaterial) + if ( this.rotation !== undefined && this.rotation !== 0 ) data.rotation = this.rotation; - var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif"; + if ( this.polygonOffset === true ) data.polygonOffset = true; + if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor; + if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits; - var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; + if ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth; + if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; + if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; + if ( this.scale !== undefined ) data.scale = this.scale; - var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif"; + if ( this.dithering === true ) data.dithering = true; - var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; + if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; + if ( this.alphaToCoverage === true ) data.alphaToCoverage = this.alphaToCoverage; + if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha; + if ( this.forceSinglePass === true ) data.forceSinglePass = this.forceSinglePass; - 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}"; + if ( this.wireframe === true ) data.wireframe = this.wireframe; + if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; + if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; + if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; - 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"; + if ( this.flatShading === true ) data.flatShading = this.flatShading; - 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"; + if ( this.visible === false ) data.visible = false; - 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"; + if ( this.toneMapped === false ) data.toneMapped = false; - 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"; + if ( this.fog === false ) data.fog = false; - 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"; + if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; - var fog_vertex = "#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif"; + // TODO: Copied from Object3D.toJSON - var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif"; + function extractFromCache( cache ) { - var 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"; + const values = []; - 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"; + for ( const key in cache ) { + + const data = cache[ key ]; + delete data.metadata; + values.push( data ); - 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 lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\treflectedLight.indirectDiffuse += lightMapIrradiance;\n#endif"; + return values; - 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"; + if ( isRootObject ) { - 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"; + const textures = extractFromCache( meta.textures ); + const images = extractFromCache( meta.images ); +<<<<<<< HEAD var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#if defined( ENVMAP_TYPE_CUBE_UV ) || defined( ENVMAP_TYPE_CUBE )\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, worldNormal );\n\t\t\t#endif\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 ) || defined( ENVMAP_TYPE_CUBE )\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\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t\t#else\n\t\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec );\n\t\t\t#endif\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"; +======= + if ( textures.length > 0 ) data.textures = textures; + if ( images.length > 0 ) data.images = images; +>>>>>>> mrdoob-dev - 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)"; + return data; - 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)"; + clone() { - 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"; + return new this.constructor().copy( this ); - 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_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\nfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\nif ( material.iridescenceThickness == 0.0 ) {\n\tmaterial.iridescence = 0.0;\n} else {\n\tmaterial.iridescence = saturate( material.iridescence );\n}\nif ( material.iridescence > 0.0 ) {\n\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n}\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"; + copy( source ) { +<<<<<<< HEAD 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 ) || defined( ENVMAP_TYPE_CUBE ) )\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"; +======= + this.name = source.name; +>>>>>>> mrdoob-dev - var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif"; + this.blending = source.blending; + this.side = source.side; + this.vertexColors = source.vertexColors; - var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; + this.opacity = source.opacity; + this.transparent = source.transparent; - var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif"; + this.blendSrc = source.blendSrc; + this.blendDst = source.blendDst; + this.blendEquation = source.blendEquation; + this.blendSrcAlpha = source.blendSrcAlpha; + this.blendDstAlpha = source.blendDstAlpha; + this.blendEquationAlpha = source.blendEquationAlpha; - var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif"; + this.depthFunc = source.depthFunc; + this.depthTest = source.depthTest; + this.depthWrite = source.depthWrite; - var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif"; + this.stencilWriteMask = source.stencilWriteMask; + this.stencilFunc = source.stencilFunc; + this.stencilRef = source.stencilRef; + this.stencilFuncMask = source.stencilFuncMask; + this.stencilFail = source.stencilFail; + this.stencilZFail = source.stencilZFail; + this.stencilZPass = source.stencilZPass; + this.stencilWrite = source.stencilWrite; - var 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"; + const srcPlanes = source.clippingPlanes; + let dstPlanes = null; - var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif"; + if ( srcPlanes !== null ) { - var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n\tdiffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif"; + const n = srcPlanes.length; + dstPlanes = new Array( n ); - var map_particle_pars_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tuniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; + for ( let i = 0; i !== n; ++ i ) { - var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif"; + dstPlanes[ i ] = srcPlanes[ i ].clone(); - var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; + } - var 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"; + } - var 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"; + this.clippingPlanes = dstPlanes; + this.clipIntersection = source.clipIntersection; + this.clipShadows = source.clipShadows; - var 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"; + this.shadowSide = source.shadowSide; - 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"; + this.colorWrite = source.colorWrite; - 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;"; + this.precision = source.precision; - 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"; + this.polygonOffset = source.polygonOffset; + this.polygonOffsetFactor = source.polygonOffsetFactor; + this.polygonOffsetUnits = source.polygonOffsetUnits; - var 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"; + this.dithering = source.dithering; - var 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"; + this.alphaTest = source.alphaTest; + this.alphaToCoverage = source.alphaToCoverage; + this.premultipliedAlpha = source.premultipliedAlpha; + this.forceSinglePass = source.forceSinglePass; - var 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"; + this.visible = source.visible; - var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN, float faceDirection ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\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"; + this.toneMapped = source.toneMapped; - var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif"; + this.userData = JSON.parse( JSON.stringify( source.userData ) ); - var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN, faceDirection );\n\t#endif\n#endif"; + return this; - var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif"; + } - var iridescence_pars_fragment = "#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif"; + dispose() { - 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 );"; + this.dispatchEvent( { type: 'dispose' } ); - var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 pack2HalfToRGBA( vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\n}\nvec2 unpackRGBATo2Half( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}"; + } - var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; + set needsUpdate( value ) { - var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;"; + if ( value === true ) this.version ++; - var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; + } - var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif"; + } - var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; + class MeshBasicMaterial extends Material { - var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; + constructor( parameters ) { - 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"; + super(); - 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"; + this.isMeshBasicMaterial = true; - 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"; + this.type = 'MeshBasicMaterial'; - 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}"; + this.color = new Color( 0xffffff ); // emissive - 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"; + this.map = null; - var 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"; + this.lightMap = null; + this.lightMapIntensity = 1.0; - var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif"; + this.aoMap = null; + this.aoMapIntensity = 1.0; - var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif"; + this.specularMap = null; - var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; + this.alphaMap = null; - var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; + this.envMap = null; + this.combine = MultiplyOperation; + this.reflectivity = 1; + this.refractionRatio = 0.98; - var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; - 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; }"; + this.fog = true; - 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"; + this.setValues( parameters ); - 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 uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif"; + copy( source ) { - var uv_pars_vertex = "#ifdef USE_UV\n\t#ifdef UVS_VERTEX_ONLY\n\t\tvec2 vUv;\n\t#else\n\t\tvarying vec2 vUv;\n\t#endif\n\tuniform mat3 uvTransform;\n#endif"; + super.copy( source ); - var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; + this.color.copy( source.color ); - var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; + this.map = source.map; - var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif"; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; - var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif"; + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; - 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"; + this.specularMap = source.specularMap; - 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}"; + this.alphaMap = source.alphaMap; - 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}"; + this.envMap = source.envMap; + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; - 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}"; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; - const vertex$d = "#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}"; - const fragment$d = "#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}"; + this.fog = source.fog; - const vertex$c = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}"; - const fragment$c = "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}"; + return this; - const vertex$b = "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}"; - 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 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 _vector$9 = /*@__PURE__*/ new Vector3(); + const _vector2$1 = /*@__PURE__*/ new Vector2(); - 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}"; + class BufferAttribute { - const vertex$7 = "#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}"; - 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}"; + constructor( array, itemSize, normalized = false ) { - 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}"; + if ( Array.isArray( array ) ) { +<<<<<<< HEAD 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\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}"; +======= + throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); +>>>>>>> mrdoob-dev - const vertex$4 = "#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}"; - const fragment$4 = "#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}"; + } - const vertex$3 = "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}"; - const fragment$3 = "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}"; + this.isBufferAttribute = true; - const vertex$2 = "#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}"; - const fragment$2 = "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}"; + this.name = ''; - const vertex$1 = "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}"; - const fragment$1 = "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}"; + this.array = array; + this.itemSize = itemSize; + this.count = array !== undefined ? array.length / itemSize : 0; + this.normalized = normalized; - const ShaderChunk = { - alphamap_fragment: alphamap_fragment, - alphamap_pars_fragment: alphamap_pars_fragment, - alphatest_fragment: alphatest_fragment, - alphatest_pars_fragment: alphatest_pars_fragment, - aomap_fragment: aomap_fragment, - aomap_pars_fragment: aomap_pars_fragment, - begin_vertex: begin_vertex, - beginnormal_vertex: beginnormal_vertex, - bsdfs: bsdfs, - iridescence_fragment: iridescence_fragment, - bumpmap_pars_fragment: bumpmap_pars_fragment, - clipping_planes_fragment: clipping_planes_fragment, - clipping_planes_pars_fragment: clipping_planes_pars_fragment, - clipping_planes_pars_vertex: clipping_planes_pars_vertex, - clipping_planes_vertex: clipping_planes_vertex, - color_fragment: color_fragment, - color_pars_fragment: color_pars_fragment, - color_pars_vertex: color_pars_vertex, - color_vertex: color_vertex, - common: common, - cube_uv_reflection_fragment: cube_uv_reflection_fragment, - defaultnormal_vertex: defaultnormal_vertex, - displacementmap_pars_vertex: displacementmap_pars_vertex, - displacementmap_vertex: displacementmap_vertex, - emissivemap_fragment: emissivemap_fragment, - emissivemap_pars_fragment: emissivemap_pars_fragment, - encodings_fragment: encodings_fragment, - encodings_pars_fragment: encodings_pars_fragment, - envmap_fragment: envmap_fragment, - envmap_common_pars_fragment: envmap_common_pars_fragment, - envmap_pars_fragment: envmap_pars_fragment, - envmap_pars_vertex: envmap_pars_vertex, - envmap_physical_pars_fragment: envmap_physical_pars_fragment, - envmap_vertex: envmap_vertex, - fog_vertex: fog_vertex, - fog_pars_vertex: fog_pars_vertex, - fog_fragment: fog_fragment, - fog_pars_fragment: fog_pars_fragment, - gradientmap_pars_fragment: gradientmap_pars_fragment, - lightmap_fragment: lightmap_fragment, - lightmap_pars_fragment: lightmap_pars_fragment, - lights_lambert_vertex: lights_lambert_vertex, - lights_pars_begin: lights_pars_begin, - lights_toon_fragment: lights_toon_fragment, - lights_toon_pars_fragment: lights_toon_pars_fragment, - lights_phong_fragment: lights_phong_fragment, - lights_phong_pars_fragment: lights_phong_pars_fragment, - lights_physical_fragment: lights_physical_fragment, - lights_physical_pars_fragment: lights_physical_pars_fragment, - lights_fragment_begin: lights_fragment_begin, - lights_fragment_maps: lights_fragment_maps, - lights_fragment_end: lights_fragment_end, - logdepthbuf_fragment: logdepthbuf_fragment, - logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, - logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, - logdepthbuf_vertex: logdepthbuf_vertex, - map_fragment: map_fragment, - map_pars_fragment: map_pars_fragment, - map_particle_fragment: map_particle_fragment, - map_particle_pars_fragment: map_particle_pars_fragment, - metalnessmap_fragment: metalnessmap_fragment, - metalnessmap_pars_fragment: metalnessmap_pars_fragment, - morphcolor_vertex: morphcolor_vertex, - morphnormal_vertex: morphnormal_vertex, - morphtarget_pars_vertex: morphtarget_pars_vertex, - morphtarget_vertex: morphtarget_vertex, - normal_fragment_begin: normal_fragment_begin, - normal_fragment_maps: normal_fragment_maps, - normal_pars_fragment: normal_pars_fragment, - normal_pars_vertex: normal_pars_vertex, - normal_vertex: normal_vertex, - normalmap_pars_fragment: normalmap_pars_fragment, - clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin, - clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps, - clearcoat_pars_fragment: clearcoat_pars_fragment, - iridescence_pars_fragment: iridescence_pars_fragment, - output_fragment: output_fragment, - packing: packing, - premultiplied_alpha_fragment: premultiplied_alpha_fragment, - project_vertex: project_vertex, - dithering_fragment: dithering_fragment, - dithering_pars_fragment: dithering_pars_fragment, - roughnessmap_fragment: roughnessmap_fragment, - roughnessmap_pars_fragment: roughnessmap_pars_fragment, - shadowmap_pars_fragment: shadowmap_pars_fragment, - shadowmap_pars_vertex: shadowmap_pars_vertex, - shadowmap_vertex: shadowmap_vertex, - shadowmask_pars_fragment: shadowmask_pars_fragment, - skinbase_vertex: skinbase_vertex, - skinning_pars_vertex: skinning_pars_vertex, - skinning_vertex: skinning_vertex, - skinnormal_vertex: skinnormal_vertex, - specularmap_fragment: specularmap_fragment, - specularmap_pars_fragment: specularmap_pars_fragment, - tonemapping_fragment: tonemapping_fragment, - tonemapping_pars_fragment: tonemapping_pars_fragment, - transmission_fragment: transmission_fragment, - transmission_pars_fragment: transmission_pars_fragment, - uv_pars_fragment: uv_pars_fragment, - uv_pars_vertex: uv_pars_vertex, - uv_vertex: uv_vertex, - uv2_pars_fragment: uv2_pars_fragment, - uv2_pars_vertex: uv2_pars_vertex, - uv2_vertex: uv2_vertex, - worldpos_vertex: worldpos_vertex, - background_vert: vertex$g, - background_frag: fragment$g, - cube_vert: vertex$f, - cube_frag: fragment$f, - depth_vert: vertex$e, - depth_frag: fragment$e, - distanceRGBA_vert: vertex$d, - distanceRGBA_frag: fragment$d, - equirect_vert: vertex$c, - equirect_frag: fragment$c, - linedashed_vert: vertex$b, - linedashed_frag: fragment$b, - meshbasic_vert: vertex$a, - meshbasic_frag: fragment$a, - meshlambert_vert: vertex$9, - meshlambert_frag: fragment$9, - meshmatcap_vert: vertex$8, - meshmatcap_frag: fragment$8, - meshnormal_vert: vertex$7, - meshnormal_frag: fragment$7, - meshphong_vert: vertex$6, - meshphong_frag: fragment$6, - meshphysical_vert: vertex$5, - meshphysical_frag: fragment$5, - meshtoon_vert: vertex$4, - meshtoon_frag: fragment$4, - points_vert: vertex$3, - points_frag: fragment$3, - shadow_vert: vertex$2, - shadow_frag: fragment$2, - sprite_vert: vertex$1, - sprite_frag: fragment$1 - }; + this.usage = StaticDrawUsage; + this.updateRange = { offset: 0, count: - 1 }; - /** - * Uniforms library for shared webgl shaders - */ + this.version = 0; - const UniformsLib = { - common: { - diffuse: { - value: new Color(0xffffff) - }, - opacity: { - value: 1.0 - }, - map: { - value: null - }, - uvTransform: { - value: new Matrix3() - }, - uv2Transform: { - value: new Matrix3() - }, - alphaMap: { - value: null - }, - alphaTest: { - value: 0 - } - }, - specularmap: { - specularMap: { - value: null - } - }, - envmap: { - envMap: { - value: null - }, - flipEnvMap: { - value: -1 - }, - reflectivity: { - value: 1.0 - }, - // basic, lambert, phong - ior: { - value: 1.5 - }, - // physical - refractionRatio: { - value: 0.98 - } // basic, lambert, phong + } - }, - aomap: { - aoMap: { - value: null - }, - aoMapIntensity: { - value: 1 - } - }, - lightmap: { - lightMap: { - value: null - }, - lightMapIntensity: { - value: 1 - } - }, - emissivemap: { - emissiveMap: { - value: null - } - }, - bumpmap: { - bumpMap: { - value: null - }, - bumpScale: { - value: 1 - } - }, - normalmap: { - normalMap: { - value: null - }, - normalScale: { - value: new Vector2(1, 1) - } - }, - displacementmap: { - displacementMap: { - value: null - }, - displacementScale: { - value: 1 - }, - displacementBias: { - value: 0 - } - }, - roughnessmap: { - roughnessMap: { - value: null - } - }, - metalnessmap: { - metalnessMap: { - value: null - } - }, - gradientmap: { - gradientMap: { - value: null - } - }, - fog: { - fogDensity: { - value: 0.00025 - }, - fogNear: { - value: 1 - }, - fogFar: { - value: 2000 - }, - fogColor: { - value: new Color(0xffffff) - } - }, - lights: { - ambientLightColor: { - value: [] - }, - lightProbe: { - value: [] - }, - directionalLights: { - value: [], - properties: { - direction: {}, - color: {} - } - }, - directionalLightShadows: { - value: [], - properties: { - shadowBias: {}, - shadowNormalBias: {}, - shadowRadius: {}, - shadowMapSize: {} - } - }, - directionalShadowMap: { - value: [] - }, - directionalShadowMatrix: { - value: [] - }, - spotLights: { - value: [], - properties: { - color: {}, - position: {}, - direction: {}, - distance: {}, - coneCos: {}, - penumbraCos: {}, - decay: {} - } - }, - spotLightShadows: { - value: [], - properties: { - shadowBias: {}, - shadowNormalBias: {}, - shadowRadius: {}, - shadowMapSize: {} - } - }, - spotShadowMap: { - value: [] - }, - spotShadowMatrix: { - value: [] - }, - pointLights: { - value: [], - properties: { - color: {}, - position: {}, - decay: {}, - distance: {} - } - }, - pointLightShadows: { - value: [], - properties: { - shadowBias: {}, - shadowNormalBias: {}, - shadowRadius: {}, - shadowMapSize: {}, - shadowCameraNear: {}, - shadowCameraFar: {} - } - }, - pointShadowMap: { - value: [] - }, - pointShadowMatrix: { - value: [] - }, - hemisphereLights: { - value: [], - properties: { - direction: {}, - skyColor: {}, - groundColor: {} - } - }, - // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src - rectAreaLights: { - value: [], - properties: { - color: {}, - position: {}, - width: {}, - height: {} - } - }, - ltc_1: { - value: null - }, - ltc_2: { - value: null - } - }, - points: { - diffuse: { - value: new Color(0xffffff) - }, - opacity: { - value: 1.0 - }, - size: { - value: 1.0 - }, - scale: { - value: 1.0 - }, - map: { - value: null - }, - alphaMap: { - value: null - }, - alphaTest: { - value: 0 - }, - uvTransform: { - value: new Matrix3() - } - }, - sprite: { - diffuse: { - value: new Color(0xffffff) - }, - opacity: { - value: 1.0 - }, - center: { - value: new Vector2(0.5, 0.5) - }, - rotation: { - value: 0.0 - }, - map: { - value: null - }, - alphaMap: { - value: null - }, - alphaTest: { - value: 0 - }, - uvTransform: { - value: new Matrix3() - } - } - }; + onUploadCallback() {} - const ShaderLib = { - basic: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.fog]), - vertexShader: ShaderChunk.meshbasic_vert, - fragmentShader: ShaderChunk.meshbasic_frag - }, - lambert: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.fog, UniformsLib.lights, { - emissive: { - value: new Color(0x000000) - } - }]), - vertexShader: ShaderChunk.meshlambert_vert, - fragmentShader: ShaderChunk.meshlambert_frag - }, - phong: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, UniformsLib.lights, { - emissive: { - value: new Color(0x000000) - }, - specular: { - value: new Color(0x111111) - }, - shininess: { - value: 30 - } - }]), - vertexShader: ShaderChunk.meshphong_vert, - fragmentShader: ShaderChunk.meshphong_frag - }, - standard: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.roughnessmap, UniformsLib.metalnessmap, UniformsLib.fog, UniformsLib.lights, { - emissive: { - value: new Color(0x000000) - }, - roughness: { - value: 1.0 - }, - metalness: { - value: 0.0 - }, - envMapIntensity: { - value: 1 - } // temporary + set needsUpdate( value ) { - }]), - vertexShader: ShaderChunk.meshphysical_vert, - fragmentShader: ShaderChunk.meshphysical_frag - }, - toon: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.gradientmap, UniformsLib.fog, UniformsLib.lights, { - emissive: { - value: new Color(0x000000) - } - }]), - vertexShader: ShaderChunk.meshtoon_vert, - fragmentShader: ShaderChunk.meshtoon_frag - }, - matcap: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, { - matcap: { - value: null - } - }]), - vertexShader: ShaderChunk.meshmatcap_vert, - fragmentShader: ShaderChunk.meshmatcap_frag - }, - points: { - uniforms: mergeUniforms([UniformsLib.points, UniformsLib.fog]), - vertexShader: ShaderChunk.points_vert, - fragmentShader: ShaderChunk.points_frag - }, - dashed: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.fog, { - scale: { - value: 1 - }, - dashSize: { - value: 1 - }, - totalSize: { - value: 2 - } - }]), - vertexShader: ShaderChunk.linedashed_vert, - fragmentShader: ShaderChunk.linedashed_frag - }, - depth: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.displacementmap]), - vertexShader: ShaderChunk.depth_vert, - fragmentShader: ShaderChunk.depth_frag - }, - normal: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, { - opacity: { - value: 1.0 - } - }]), - vertexShader: ShaderChunk.meshnormal_vert, - fragmentShader: ShaderChunk.meshnormal_frag - }, - sprite: { - uniforms: mergeUniforms([UniformsLib.sprite, UniformsLib.fog]), - vertexShader: ShaderChunk.sprite_vert, - fragmentShader: ShaderChunk.sprite_frag - }, - background: { - uniforms: { - uvTransform: { - value: new Matrix3() - }, - t2D: { - value: null - } - }, - vertexShader: ShaderChunk.background_vert, - fragmentShader: ShaderChunk.background_frag - }, + if ( value === true ) this.version ++; - /* ------------------------------------------------------------------------- - // Cube map shader - ------------------------------------------------------------------------- */ - cube: { - uniforms: mergeUniforms([UniformsLib.envmap, { - opacity: { - value: 1.0 - } - }]), - vertexShader: ShaderChunk.cube_vert, - fragmentShader: ShaderChunk.cube_frag - }, - equirect: { - uniforms: { - tEquirect: { - value: null - } - }, - vertexShader: ShaderChunk.equirect_vert, - fragmentShader: ShaderChunk.equirect_frag - }, - distanceRGBA: { - uniforms: mergeUniforms([UniformsLib.common, UniformsLib.displacementmap, { - referencePosition: { - value: new Vector3() - }, - nearDistance: { - value: 1 - }, - farDistance: { - value: 1000 - } - }]), - vertexShader: ShaderChunk.distanceRGBA_vert, - fragmentShader: ShaderChunk.distanceRGBA_frag - }, - shadow: { - uniforms: mergeUniforms([UniformsLib.lights, UniformsLib.fog, { - color: { - value: new Color(0x00000) - }, - opacity: { - value: 1.0 - } - }]), - vertexShader: ShaderChunk.shadow_vert, - fragmentShader: ShaderChunk.shadow_frag } - }; - ShaderLib.physical = { - uniforms: mergeUniforms([ShaderLib.standard.uniforms, { - clearcoat: { - value: 0 - }, - clearcoatMap: { - value: null - }, - clearcoatRoughness: { - value: 0 - }, - clearcoatRoughnessMap: { - value: null - }, - clearcoatNormalScale: { - value: new Vector2(1, 1) - }, - clearcoatNormalMap: { - value: null - }, - 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 Color(0x000000) - }, - sheenColorMap: { - value: null - }, - sheenRoughness: { - value: 1 - }, - sheenRoughnessMap: { - value: null - }, - transmission: { - value: 0 - }, - transmissionMap: { - value: null - }, - transmissionSamplerSize: { - value: new Vector2() - }, - transmissionSamplerMap: { - value: null - }, - thickness: { - value: 0 - }, - thicknessMap: { - value: null - }, - attenuationDistance: { - value: 0 - }, - attenuationColor: { - value: new Color(0x000000) - }, - specularIntensity: { - value: 1 - }, - specularIntensityMap: { - value: null - }, - specularColor: { - value: new Color(1, 1, 1) - }, - specularColorMap: { - value: null - } - }]), - vertexShader: ShaderChunk.meshphysical_vert, - fragmentShader: ShaderChunk.meshphysical_frag - }; - function WebGLBackground(renderer, cubemaps, state, objects, alpha, premultipliedAlpha) { - const clearColor = new Color(0x000000); - let clearAlpha = alpha === true ? 0 : 1; - let planeMesh; - let boxMesh; - let currentBackground = null; - let currentBackgroundVersion = 0; - let currentTonemapping = null; + setUsage( value ) { - function render(renderList, scene) { - let forceClear = false; - let background = scene.isScene === true ? scene.background : null; + this.usage = value; - if (background && background.isTexture) { - background = cubemaps.get(background); - } // Ignore background in AR - // TODO: Reconsider this. + return this; + } - const xr = renderer.xr; - const session = xr.getSession && xr.getSession(); + copy( source ) { - if (session && session.environmentBlendMode === 'additive') { - background = null; - } + this.name = source.name; + this.array = new source.array.constructor( source.array ); + this.itemSize = source.itemSize; + this.count = source.count; + this.normalized = source.normalized; - if (background === null) { - setClear(clearColor, clearAlpha); - } else if (background && background.isColor) { - setClear(background, 1); - forceClear = true; - } + this.usage = source.usage; - if (renderer.autoClear || forceClear) { - renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil); - } + return this; - 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, - side: BackSide, - depthTest: false, - depthWrite: false, - fog: false - })); - 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 + copyAt( index1, attribute, index2 ) { + index1 *= this.itemSize; + index2 *= attribute.itemSize; - Object.defineProperty(boxMesh.material, 'envMap', { - get: function () { - return this.uniforms.envMap.value; - } - }); - objects.update(boxMesh); - } + for ( let i = 0, l = this.itemSize; i < l; i ++ ) { - boxMesh.material.uniforms.envMap.value = background; - boxMesh.material.uniforms.flipEnvMap.value = background.isCubeTexture && background.isRenderTargetTexture === false ? -1 : 1; + this.array[ index1 + i ] = attribute.array[ index2 + i ]; - if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { - boxMesh.material.needsUpdate = true; - currentBackground = background; - currentBackgroundVersion = background.version; - currentTonemapping = renderer.toneMapping; - } + } - boxMesh.layers.enableAll(); // push to the pre-sorted opaque render list - - renderList.unshift(boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null); - } else if (background && background.isTexture) { - if (planeMesh === undefined) { - planeMesh = new Mesh(new PlaneGeometry(2, 2), new ShaderMaterial({ - name: 'BackgroundMaterial', - uniforms: cloneUniforms(ShaderLib.background.uniforms), - vertexShader: ShaderLib.background.vertexShader, - fragmentShader: ShaderLib.background.fragmentShader, - side: FrontSide, - depthTest: false, - depthWrite: false, - fog: false - })); - planeMesh.geometry.deleteAttribute('normal'); // enable code injection for non-built-in material - - Object.defineProperty(planeMesh.material, 'map', { - get: function () { - return this.uniforms.t2D.value; - } - }); - objects.update(planeMesh); - } + return this; - planeMesh.material.uniforms.t2D.value = background; + } - if (background.matrixAutoUpdate === true) { - background.updateMatrix(); - } + copyArray( array ) { - planeMesh.material.uniforms.uvTransform.value.copy(background.matrix); + this.array.set( array ); - if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { - planeMesh.material.needsUpdate = true; - currentBackground = background; - currentBackgroundVersion = background.version; - currentTonemapping = renderer.toneMapping; - } - - planeMesh.layers.enableAll(); // push to the pre-sorted opaque render list + return this; - 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); - } + applyMatrix3( m ) { - return { - getClearColor: function () { - return clearColor; - }, - setClearColor: function (color, alpha = 1) { - clearColor.set(color); - clearAlpha = alpha; - setClear(clearColor, clearAlpha); - }, - getClearAlpha: function () { - return clearAlpha; - }, - setClearAlpha: function (alpha) { - clearAlpha = alpha; - setClear(clearColor, clearAlpha); - }, - render: render - }; - } + if ( this.itemSize === 2 ) { - function WebGLBindingStates(gl, extensions, attributes, capabilities) { - const maxVertexAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); - const extension = capabilities.isWebGL2 ? null : extensions.get('OES_vertex_array_object'); - const vaoAvailable = capabilities.isWebGL2 || extension !== null; - const bindingStates = {}; - const defaultState = createBindingState(null); - let currentState = defaultState; - let forceUpdate = false; + for ( let i = 0, l = this.count; i < l; i ++ ) { - function setup(object, material, program, geometry, index) { - let updateBuffers = false; + _vector2$1.fromBufferAttribute( this, i ); + _vector2$1.applyMatrix3( m ); - if (vaoAvailable) { - const state = getBindingState(geometry, program, material); + this.setXY( i, _vector2$1.x, _vector2$1.y ); - 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; + } else if ( this.itemSize === 3 ) { - if (currentState.geometry !== geometry.id || currentState.program !== program.id || currentState.wireframe !== wireframe) { - currentState.geometry = geometry.id; - currentState.program = program.id; - currentState.wireframe = wireframe; - updateBuffers = true; - } - } + for ( let i = 0, l = this.count; i < l; i ++ ) { - if (index !== null) { - attributes.update(index, gl.ELEMENT_ARRAY_BUFFER); - } + _vector$9.fromBufferAttribute( this, i ); + _vector$9.applyMatrix3( m ); - if (updateBuffers || forceUpdate) { - forceUpdate = false; - setupVertexAttributes(object, material, program, geometry); + this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); - 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); - } + return this; - 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]; + applyMatrix4( m ) { - if (programMap === undefined) { - programMap = {}; - bindingStates[geometry.id] = programMap; - } + for ( let i = 0, l = this.count; i < l; i ++ ) { - let stateMap = programMap[program.id]; + _vector$9.fromBufferAttribute( this, i ); - if (stateMap === undefined) { - stateMap = {}; - programMap[program.id] = stateMap; - } + _vector$9.applyMatrix4( m ); - let state = stateMap[wireframe]; + this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); - 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 this; - return { - // for backward compatibility on non-VAO support browser - geometry: null, - program: null, - wireframe: false, - newAttributes: newAttributes, - enabledAttributes: enabledAttributes, - attributeDivisors: attributeDivisors, - object: vao, - attributes: {}, - index: null - }; } - function needsUpdate(object, geometry, program, index) { - const cachedAttributes = currentState.attributes; - const geometryAttributes = geometry.attributes; - let attributesNum = 0; - const programAttributes = program.getAttributes(); + applyNormalMatrix( m ) { - for (const name in programAttributes) { - const programAttribute = programAttributes[name]; + for ( let i = 0, l = this.count; i < l; i ++ ) { - if (programAttribute.location >= 0) { - const cachedAttribute = cachedAttributes[name]; - let geometryAttribute = geometryAttributes[name]; + _vector$9.fromBufferAttribute( this, i ); - if (geometryAttribute === undefined) { - if (name === 'instanceMatrix' && object.instanceMatrix) geometryAttribute = object.instanceMatrix; - if (name === 'instanceColor' && object.instanceColor) geometryAttribute = object.instanceColor; - } + _vector$9.applyNormalMatrix( m ); + + this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); - 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; - } + return this; - 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]; + transformDirection( m ) { - if (programAttribute.location >= 0) { - let attribute = attributes[name]; + for ( let i = 0, l = this.count; i < l; i ++ ) { - if (attribute === undefined) { - if (name === 'instanceMatrix' && object.instanceMatrix) attribute = object.instanceMatrix; - if (name === 'instanceColor' && object.instanceColor) attribute = object.instanceColor; - } + _vector$9.fromBufferAttribute( this, i ); - const data = {}; - data.attribute = attribute; + _vector$9.transformDirection( m ); - if (attribute && attribute.data) { - data.data = attribute.data; - } + this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); - cache[name] = data; - attributesNum++; - } } - currentState.attributes = cache; - currentState.attributesNum = attributesNum; - currentState.index = index; + return this; + } - function initAttributes() { - const newAttributes = currentState.newAttributes; + set( value, offset = 0 ) { - for (let i = 0, il = newAttributes.length; i < il; i++) { - newAttributes[i] = 0; - } - } + // Matching BufferAttribute constructor, do not normalize the array. + this.array.set( value, offset ); + + return this; - 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; + getX( index ) { - if (enabledAttributes[attribute] === 0) { - gl.enableVertexAttribArray(attribute); - enabledAttributes[attribute] = 1; - } + let x = this.array[ index * this.itemSize ]; - if (attributeDivisors[attribute] !== meshPerAttribute) { - const extension = capabilities.isWebGL2 ? gl : extensions.get('ANGLE_instanced_arrays'); - extension[capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE'](attribute, meshPerAttribute); - attributeDivisors[attribute] = meshPerAttribute; - } - } + if ( this.normalized ) x = denormalize( x, this.array ); - function disableUnusedAttributes() { - const newAttributes = currentState.newAttributes; - const enabledAttributes = currentState.enabledAttributes; + return x; - for (let i = 0, il = enabledAttributes.length; i < il; i++) { - if (enabledAttributes[i] !== newAttributes[i]) { - gl.disableVertexAttribArray(i); - enabledAttributes[i] = 0; - } - } } - 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); - } else { - gl.vertexAttribPointer(index, size, type, normalized, stride, offset); - } + setX( index, x ) { + + if ( this.normalized ) x = normalize( x, this.array ); + + this.array[ index * this.itemSize ] = x; + + return this; + } - function setupVertexAttributes(object, material, program, geometry) { - if (capabilities.isWebGL2 === false && (object.isInstancedMesh || geometry.isInstancedBufferGeometry)) { - if (extensions.get('ANGLE_instanced_arrays') === null) return; - } + getY( index ) { - initAttributes(); - const geometryAttributes = geometry.attributes; - const programAttributes = program.getAttributes(); - const materialDefaultAttributeValues = material.defaultAttributeValues; + let y = this.array[ index * this.itemSize + 1 ]; - for (const name in programAttributes) { - const programAttribute = programAttributes[name]; + if ( this.normalized ) y = denormalize( y, this.array ); - if (programAttribute.location >= 0) { - let geometryAttribute = geometryAttributes[name]; + return y; - 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 + setY( index, y ) { - if (attribute === undefined) continue; - const buffer = attribute.buffer; - const type = attribute.type; - const bytesPerElement = attribute.bytesPerElement; + if ( this.normalized ) y = normalize( y, this.array ); - if (geometryAttribute.isInterleavedBufferAttribute) { - const data = geometryAttribute.data; - const stride = data.stride; - const offset = geometryAttribute.offset; + this.array[ index * this.itemSize + 1 ] = y; - if (data.isInstancedInterleavedBuffer) { - for (let i = 0; i < programAttribute.locationSize; i++) { - enableAttributeAndDivisor(programAttribute.location + i, data.meshPerAttribute); - } + return this; - if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) { - geometry._maxInstanceCount = data.meshPerAttribute * data.count; - } - } else { - for (let i = 0; i < programAttribute.locationSize; i++) { - enableAttribute(programAttribute.location + i); - } - } + } - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + getZ( index ) { - 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); - } - } else { - if (geometryAttribute.isInstancedBufferAttribute) { - for (let i = 0; i < programAttribute.locationSize; i++) { - enableAttributeAndDivisor(programAttribute.location + i, geometryAttribute.meshPerAttribute); - } + let z = this.array[ index * this.itemSize + 2 ]; - if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) { - geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; - } - } else { - for (let i = 0; i < programAttribute.locationSize; i++) { - enableAttribute(programAttribute.location + i); - } - } + if ( this.normalized ) z = denormalize( z, this.array ); - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + return z; - 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; + setZ( index, z ) { - case 3: - gl.vertexAttrib3fv(programAttribute.location, value); - break; + if ( this.normalized ) z = normalize( z, this.array ); - case 4: - gl.vertexAttrib4fv(programAttribute.location, value); - break; + this.array[ index * this.itemSize + 2 ] = z; - default: - gl.vertexAttrib1fv(programAttribute.location, value); - } - } - } - } - } + return this; - disableUnusedAttributes(); } - function dispose() { - reset(); - - for (const geometryId in bindingStates) { - const programMap = bindingStates[geometryId]; + getW( index ) { - for (const programId in programMap) { - const stateMap = programMap[programId]; + let w = this.array[ index * this.itemSize + 3 ]; - for (const wireframe in stateMap) { - deleteVertexArrayObject(stateMap[wireframe].object); - delete stateMap[wireframe]; - } + if ( this.normalized ) w = denormalize( w, this.array ); - delete programMap[programId]; - } + return w; - delete bindingStates[geometryId]; - } } - function releaseStatesOfGeometry(geometry) { - if (bindingStates[geometry.id] === undefined) return; - const programMap = bindingStates[geometry.id]; + setW( index, w ) { - for (const programId in programMap) { - const stateMap = programMap[programId]; + if ( this.normalized ) w = normalize( w, this.array ); - for (const wireframe in stateMap) { - deleteVertexArrayObject(stateMap[wireframe].object); - delete stateMap[wireframe]; - } + this.array[ index * this.itemSize + 3 ] = w; - delete programMap[programId]; - } + return this; - 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]; + setXY( index, x, y ) { - for (const wireframe in stateMap) { - deleteVertexArrayObject(stateMap[wireframe].object); - delete stateMap[wireframe]; - } + index *= this.itemSize; + + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); - delete programMap[program.id]; } - } - function reset() { - resetDefaultState(); - forceUpdate = true; - if (currentState === defaultState) return; - currentState = defaultState; - bindVertexArrayObject(currentState.object); - } // for backward-compatibility + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; + return this; - function resetDefaultState() { - defaultState.geometry = null; - defaultState.program = null; - defaultState.wireframe = false; } - return { - setup: setup, - reset: reset, - resetDefaultState: resetDefaultState, - dispose: dispose, - releaseStatesOfGeometry: releaseStatesOfGeometry, - releaseStatesOfProgram: releaseStatesOfProgram, - initAttributes: initAttributes, - enableAttribute: enableAttribute, - disableUnusedAttributes: disableUnusedAttributes - }; - } + setXYZ( index, x, y, z ) { - function WebGLBufferRenderer(gl, extensions, info, capabilities) { - const isWebGL2 = capabilities.isWebGL2; - let mode; + index *= this.itemSize; - function setMode(value) { - mode = value; - } + if ( this.normalized ) { - function render(start, count) { - gl.drawArrays(mode, start, count); - info.update(count, mode, 1); - } + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); - 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'; + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; + this.array[ index + 2 ] = z; - if (extension === null) { - console.error('THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.'); - return; - } - } + return this; - extension[methodName](mode, start, count, primcount); - info.update(count, mode, primcount); - } // + } + setXYZW( index, x, y, z, w ) { - this.setMode = setMode; - this.render = render; - this.renderInstances = renderInstances; - } + index *= this.itemSize; - function WebGLCapabilities(gl, extensions, parameters) { - let maxAnisotropy; + if ( this.normalized ) { - function getMaxAnisotropy() { - if (maxAnisotropy !== undefined) return maxAnisotropy; + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + w = normalize( w, this.array ); - 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; + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; + this.array[ index + 2 ] = z; + this.array[ index + 3 ] = w; + + return this; + } - 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'; - } + onUpload( callback ) { - precision = 'mediump'; - } + this.onUploadCallback = callback; - 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 this; - 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); + clone() { + + return new this.constructor( this.array, this.itemSize ).copy( this ); - 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); - const maxVertexTextures = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); - const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); - const maxCubemapSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); - const maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); - const maxVertexUniforms = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS); - const maxVaryings = gl.getParameter(gl.MAX_VARYING_VECTORS); - const maxFragmentUniforms = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS); - const vertexTextures = maxVertexTextures > 0; - const floatFragmentTextures = isWebGL2 || extensions.has('OES_texture_float'); - const floatVertexTextures = vertexTextures && floatFragmentTextures; - const maxSamples = isWebGL2 ? gl.getParameter(gl.MAX_SAMPLES) : 0; - return { - isWebGL2: isWebGL2, - drawBuffers: drawBuffers, - getMaxAnisotropy: getMaxAnisotropy, - getMaxPrecision: getMaxPrecision, - precision: precision, - logarithmicDepthBuffer: logarithmicDepthBuffer, - maxTextures: maxTextures, - maxVertexTextures: maxVertexTextures, - maxTextureSize: maxTextureSize, - maxCubemapSize: maxCubemapSize, - maxAttributes: maxAttributes, - maxVertexUniforms: maxVertexUniforms, - maxVaryings: maxVaryings, - maxFragmentUniforms: maxFragmentUniforms, - vertexTextures: vertexTextures, - floatFragmentTextures: floatFragmentTextures, - floatVertexTextures: floatVertexTextures, - maxSamples: maxSamples - }; - } + toJSON() { - function WebGLClipping(properties) { - const scope = this; - let globalState = null, - numGlobalPlanes = 0, - localClippingEnabled = false, - renderingShadows = false; - const plane = new Plane(), - viewNormalMatrix = new Matrix3(), - uniform = { - value: null, - needsUpdate: false - }; - this.uniform = uniform; - this.numPlanes = 0; - this.numIntersection = 0; + const data = { + itemSize: this.itemSize, + type: this.array.constructor.name, + array: Array.from( this.array ), + normalized: this.normalized + }; - this.init = function (planes, enableLocalClipping, camera) { - 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; - globalState = projectPlanes(planes, camera, 0); - numGlobalPlanes = planes.length; - return enabled; - }; + if ( this.name !== '' ) data.name = this.name; + if ( this.usage !== StaticDrawUsage ) data.usage = this.usage; + if ( this.updateRange.offset !== 0 || this.updateRange.count !== - 1 ) data.updateRange = this.updateRange; - this.beginShadows = function () { - renderingShadows = true; - projectPlanes(null); - }; + return data; - this.endShadows = function () { - renderingShadows = false; - resetGlobalState(); - }; + } - this.setState = function (material, camera, useCache) { - const planes = material.clippingPlanes, - clipIntersection = material.clipIntersection, - clipShadows = material.clipShadows; - const materialProperties = properties.get(material); + // @deprecated - 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; - let dstArray = materialProperties.clippingState || null; - uniform.value = dstArray; // ensure unique state + copyColorsArray() { - dstArray = projectPlanes(planes, camera, lGlobal, useCache); + console.error( 'THREE.BufferAttribute: copyColorsArray() was removed in r144.' ); - for (let i = 0; i !== lGlobal; ++i) { - dstArray[i] = globalState[i]; - } + } - materialProperties.clippingState = dstArray; - this.numIntersection = clipIntersection ? this.numPlanes : 0; - this.numPlanes += nGlobal; - } - }; + copyVector2sArray() { - function resetGlobalState() { - if (uniform.value !== globalState) { - uniform.value = globalState; - uniform.needsUpdate = numGlobalPlanes > 0; - } + console.error( 'THREE.BufferAttribute: copyVector2sArray() was removed in r144.' ); - 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; + copyVector3sArray() { - if (skipTransform !== true || dstArray === null) { - const flatSize = dstOffset + nPlanes * 4, - viewMatrix = camera.matrixWorldInverse; - viewNormalMatrix.getNormalMatrix(viewMatrix); + console.error( 'THREE.BufferAttribute: copyVector3sArray() was removed in r144.' ); - 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; - } - } + copyVector4sArray() { - uniform.value = dstArray; - uniform.needsUpdate = true; - } + console.error( 'THREE.BufferAttribute: copyVector4sArray() was removed in r144.' ); - scope.numPlanes = nPlanes; - scope.numIntersection = 0; - return dstArray; } + } - function WebGLCubeMaps(renderer) { - let cubemaps = new WeakMap(); + // - function mapTextureMapping(texture, mapping) { - if (mapping === EquirectangularReflectionMapping) { - texture.mapping = CubeReflectionMapping; - } else if (mapping === EquirectangularRefractionMapping) { - texture.mapping = CubeRefractionMapping; - } + class Int8BufferAttribute extends BufferAttribute { + + constructor( array, itemSize, normalized ) { + + super( new Int8Array( array ), itemSize, normalized ); - 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; + class Uint8BufferAttribute extends BufferAttribute { - if (image && image.height > 0) { - const renderTarget = new WebGLCubeRenderTarget(image.height / 2); - renderTarget.fromEquirectangularTexture(renderer, texture); - cubemaps.set(texture, renderTarget); - texture.addEventListener('dispose', onTextureDispose); - return mapTextureMapping(renderTarget.texture, texture.mapping); - } else { - // image not yet ready. try the conversion next frame - return null; - } - } - } - } + constructor( array, itemSize, normalized ) { + + super( new Uint8Array( array ), itemSize, normalized ); - 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(); - } - } + class Uint8ClampedBufferAttribute extends BufferAttribute { + + constructor( array, itemSize, normalized ) { + + super( new Uint8ClampedArray( array ), itemSize, normalized ); - function dispose() { - cubemaps = new WeakMap(); } - return { - get: get, - dispose: dispose - }; } - class OrthographicCamera extends Camera { - constructor(left = -1, right = 1, top = 1, bottom = -1, near = 0.1, far = 2000) { - super(); - this.isOrthographicCamera = true; - this.type = 'OrthographicCamera'; - this.zoom = 1; - this.view = null; - this.left = left; - this.right = right; - this.top = top; - this.bottom = bottom; - this.near = near; - this.far = far; - this.updateProjectionMatrix(); - } + class Int16BufferAttribute extends BufferAttribute { + + constructor( array, itemSize, normalized ) { + + super( new Int16Array( array ), itemSize, normalized ); - copy(source, recursive) { - super.copy(source, recursive); - this.left = source.left; - this.right = source.right; - this.top = source.top; - this.bottom = source.bottom; - this.near = source.near; - this.far = source.far; - this.zoom = source.zoom; - this.view = source.view === null ? null : Object.assign({}, source.view); - return this; } - setViewOffset(fullWidth, fullHeight, x, y, width, height) { - if (this.view === null) { - this.view = { - enabled: true, - fullWidth: 1, - fullHeight: 1, - offsetX: 0, - offsetY: 0, - width: 1, - height: 1 - }; - } + } + + class Uint16BufferAttribute extends BufferAttribute { + + constructor( array, itemSize, normalized ) { + + super( new Uint16Array( array ), itemSize, normalized ); - this.view.enabled = true; - this.view.fullWidth = fullWidth; - this.view.fullHeight = fullHeight; - this.view.offsetX = x; - this.view.offsetY = y; - this.view.width = width; - this.view.height = height; - this.updateProjectionMatrix(); } - clearViewOffset() { - if (this.view !== null) { - this.view.enabled = false; - } + } + + class Int32BufferAttribute extends BufferAttribute { + + constructor( array, itemSize, normalized ) { + + super( new Int32Array( array ), itemSize, normalized ); - this.updateProjectionMatrix(); } - updateProjectionMatrix() { - const dx = (this.right - this.left) / (2 * this.zoom); - const dy = (this.top - this.bottom) / (2 * this.zoom); - const cx = (this.right + this.left) / 2; - const cy = (this.top + this.bottom) / 2; - let left = cx - dx; - let right = cx + dx; - let top = cy + dy; - let bottom = cy - dy; + } - if (this.view !== null && this.view.enabled) { - const scaleW = (this.right - this.left) / this.view.fullWidth / this.zoom; - const scaleH = (this.top - this.bottom) / this.view.fullHeight / this.zoom; - left += scaleW * this.view.offsetX; - right = left + scaleW * this.view.width; - top -= scaleH * this.view.offsetY; - bottom = top - scaleH * this.view.height; - } + class Uint32BufferAttribute extends BufferAttribute { + + constructor( array, itemSize, normalized ) { + + super( new Uint32Array( array ), itemSize, normalized ); - this.projectionMatrix.makeOrthographic(left, right, top, bottom, this.near, this.far); - this.projectionMatrixInverse.copy(this.projectionMatrix).invert(); } - toJSON(meta) { - const data = super.toJSON(meta); - data.object.zoom = this.zoom; - data.object.left = this.left; - data.object.right = this.right; - data.object.top = this.top; - data.object.bottom = this.bottom; - data.object.near = this.near; - data.object.far = this.far; - if (this.view !== null) data.object.view = Object.assign({}, this.view); - return data; + } + + class Float16BufferAttribute extends BufferAttribute { + + constructor( array, itemSize, normalized ) { + + super( new Uint16Array( array ), itemSize, normalized ); + + this.isFloat16BufferAttribute = true; + } } - 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]; // The maximum length of the blur for loop. Smaller sigmas will use fewer - // samples and exit early, but not recompile the shader. + class Float32BufferAttribute extends BufferAttribute { - const MAX_SAMPLES = 20; + constructor( array, itemSize, normalized ) { - const _flatCamera = /*@__PURE__*/new OrthographicCamera(); + super( new Float32Array( array ), itemSize, normalized ); - const _clearColor = /*@__PURE__*/new Color(); + } - let _oldTarget = null; // 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. + class Float64BufferAttribute extends BufferAttribute { - 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 - * blur to be quickly accessed based on material roughness. It is packed into a - * special CubeUV format that allows us to perform custom interpolation so that - * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap - * chain, it only goes down to the LOD_MIN level (above), and then creates extra - * even more filtered 'mips' at the same LOD_MIN resolution, associated with - * higher roughness levels. In this way we maintain resolution to smoothly - * interpolate diffuse lighting while limiting sampling computation. - * - * Paper: Fast, Accurate Image-Based Lighting - * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view - */ + constructor( array, itemSize, normalized ) { - class PMREMGenerator { - constructor(renderer) { - this._renderer = renderer; - this._pingPongRenderTarget = null; - this._lodMax = 0; - this._cubeSize = 0; - this._lodPlanes = []; - this._sizeLods = []; - this._sigmas = []; - this._blurMaterial = null; - this._cubemapMaterial = null; - this._equirectMaterial = null; + super( new Float64Array( array ), itemSize, normalized ); - this._compileMaterial(this._blurMaterial); } - /** - * Generates a PMREM from a supplied Scene, which can be faster than using an - * image if networking bandwidth is low. Optional sigma specifies a blur radius - * in radians to be applied to the scene before PMREM generation. Optional near - * and far planes ensure the scene is rendered in its entirety (the cubeCamera - * is placed at the origin). - */ + } +<<<<<<< HEAD fromScene(scene, sigma = 0, near = 0.1, far = 100, cubeUVRenderTarget = null, pingPongRenderTarget = null) { _oldTarget = this._renderer.getRenderTarget(); @@ -11810,19 +9784,30 @@ } this._setSize(256); +======= + let _id$1 = 0; - cubeUVRenderTarget.depthBuffer = true; + 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(); - this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); + class BufferGeometry extends EventDispatcher { +>>>>>>> mrdoob-dev - if (sigma > 0) { - this._blur(cubeUVRenderTarget, 0, 0, sigma); - } + constructor() { - this._applyPMREM(cubeUVRenderTarget); + super(); + + this.isBufferGeometry = true; - this._cleanup(cubeUVRenderTarget); + Object.defineProperty( this, 'id', { value: _id$1 ++ } ); + this.uuid = generateUUID(); + +<<<<<<< HEAD return cubeUVRenderTarget; } @@ -11872,602 +9857,257 @@ * or HDR. The ideal input image size is 1k (1024 x 512), * as this matches best with the 256 x 256 cubemap output. */ +======= + this.name = ''; + this.type = 'BufferGeometry'; +>>>>>>> mrdoob-dev + this.index = null; + this.attributes = {}; - 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. - */ + this.morphAttributes = {}; + this.morphTargetsRelative = false; + this.groups = []; - 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. - */ + this.boundingBox = null; + this.boundingSphere = null; + this.drawRange = { start: 0, count: Infinity }; - compileCubemapShader() { - if (this._cubemapMaterial === null) { - this._cubemapMaterial = _getCubemapMaterial(); + this.userData = {}; - 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. - */ + getIndex() { - compileEquirectangularShader() { - if (this._equirectMaterial === null) { - this._equirectMaterial = _getEquirectMaterial(); + return this.index; - 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. - */ + setIndex( index ) { - dispose() { - this._dispose(); + if ( Array.isArray( index ) ) { - if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose(); - if (this._equirectMaterial !== null) this._equirectMaterial.dispose(); - } // private interface + this.index = new ( arrayNeedsUint32( index ) ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 ); + } else { - _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(); + this.index = index; - for (let i = 0; i < this._lodPlanes.length; i++) { - this._lodPlanes[i].dispose(); } - } - _cleanup(outputTarget) { - this._renderer.setRenderTarget(_oldTarget); - - outputTarget.scissorTest = false; + return this; - _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); - } + getAttribute( name ) { - _oldTarget = this._renderer.getRenderTarget(); + return this.attributes[ name ]; - const cubeUVRenderTarget = renderTarget || this._allocateTargets(); + } - this._textureToCubeUV(texture, cubeUVRenderTarget); + setAttribute( name, attribute ) { - this._applyPMREM(cubeUVRenderTarget); + this.attributes[ name ] = attribute; - this._cleanup(cubeUVRenderTarget); + return this; - return cubeUVRenderTarget; } - _allocateTargets() { - const width = 3 * Math.max(this._cubeSize, 16 * 7); - const height = 4 * this._cubeSize; - const params = { - magFilter: LinearFilter, - minFilter: LinearFilter, - generateMipmaps: false, - type: HalfFloatType, - format: RGBAFormat, - encoding: LinearEncoding, - depthBuffer: false - }; + deleteAttribute( name ) { - const cubeUVRenderTarget = _createRenderTarget(width, height, params); + delete this.attributes[ name ]; - if (this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width) { - if (this._pingPongRenderTarget !== null) { - this._dispose(); - } - - this._pingPongRenderTarget = _createRenderTarget(width, height, params); - const { - _lodMax - } = this; - ({ - sizeLods: this._sizeLods, - lodPlanes: this._lodPlanes, - sigmas: this._sigmas - } = _createPlanes(_lodMax)); - this._blurMaterial = _getBlurShader(_lodMax, width, height); - } + return this; - return cubeUVRenderTarget; } - _compileMaterial(material) { - const tmpMesh = new Mesh(this._lodPlanes[0], material); - - this._renderer.compile(tmpMesh, _flatCamera); - } + hasAttribute( name ) { - _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { - const fov = 90; - const aspect = 1; - const cubeCamera = new PerspectiveCamera(fov, aspect, near, far); - const upSign = [1, -1, 1, 1, 1, 1]; - const forwardSign = [1, 1, 1, -1, -1, -1]; - const renderer = this._renderer; - const originalAutoClear = renderer.autoClear; - const toneMapping = renderer.toneMapping; - renderer.getClearColor(_clearColor); - renderer.toneMapping = NoToneMapping; - renderer.autoClear = false; - const backgroundMaterial = new MeshBasicMaterial({ - name: 'PMREM.Background', - side: BackSide, - depthWrite: false, - depthTest: false - }); - const backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial); - let useSolidColor = false; - const background = scene.background; + return this.attributes[ name ] !== undefined; - if (background) { - if (background.isColor) { - backgroundMaterial.color.copy(background); - scene.background = null; - useSolidColor = true; - } - } else { - backgroundMaterial.color.copy(_clearColor); - useSolidColor = true; - } + } - for (let i = 0; i < 6; i++) { - const col = i % 3; + addGroup( start, count, materialIndex = 0 ) { - if (col === 0) { - cubeCamera.up.set(0, upSign[i], 0); - cubeCamera.lookAt(forwardSign[i], 0, 0); - } else if (col === 1) { - cubeCamera.up.set(0, 0, upSign[i]); - cubeCamera.lookAt(0, forwardSign[i], 0); - } else { - cubeCamera.up.set(0, upSign[i], 0); - cubeCamera.lookAt(0, 0, forwardSign[i]); - } + this.groups.push( { - const size = this._cubeSize; + start: start, + count: count, + materialIndex: materialIndex - _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); + } ); - renderer.setRenderTarget(cubeUVRenderTarget); + } - if (useSolidColor) { - renderer.render(backgroundBox, cubeCamera); - } + clearGroups() { - renderer.render(scene, cubeCamera); - } + this.groups = []; - 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; + setDrawRange( start, count ) { - if (isCubeTexture) { - if (this._cubemapMaterial === null) { - this._cubemapMaterial = _getCubemapMaterial(); - } + this.drawRange.start = start; + this.drawRange.count = count; - 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; + applyMatrix4( matrix ) { - _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); + const position = this.attributes.position; - renderer.setRenderTarget(cubeUVRenderTarget); - renderer.render(mesh, _flatCamera); - } + if ( position !== undefined ) { - _applyPMREM(cubeUVRenderTarget) { - const renderer = this._renderer; - const autoClear = renderer.autoClear; - renderer.autoClear = false; + position.applyMatrix4( matrix ); - 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]; + position.needsUpdate = true; - this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); } - renderer.autoClear = autoClear; - } - /** - * This is a two-pass Gaussian blur for a cubemap. Normally this is done - * vertically and horizontally, but this breaks down on a cube. Here we apply - * the blur latitudinally (around the poles), and then longitudinally (towards - * the poles) to approximate the orthogonally-separable blur. It is least - * accurate at the poles, but still does a decent job. - */ + const normal = this.attributes.normal; + if ( normal !== undefined ) { - _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { - const pingPongRenderTarget = this._pingPongRenderTarget; + const normalMatrix = new Matrix3().getNormalMatrix( matrix ); - this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); + normal.applyNormalMatrix( normalMatrix ); - this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis); - } + normal.needsUpdate = true; - _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { - const renderer = this._renderer; - const blurMaterial = this._blurMaterial; + } + + const tangent = this.attributes.tangent; - 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. + if ( tangent !== undefined ) { + tangent.transformDirection( matrix ); - const STANDARD_DEVIATIONS = 3; - const blurMesh = new Mesh(this._lodPlanes[lodOut], blurMaterial); - const blurUniforms = blurMaterial.uniforms; - const pixels = this._sizeLods[lodIn] - 1; - 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; + tangent.needsUpdate = true; - 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; + if ( this.boundingBox !== null ) { - for (let i = 0; i < MAX_SAMPLES; ++i) { - const x = i / sigmaPixels; - const weight = Math.exp(-x * x / 2); - weights.push(weight); + this.computeBoundingBox(); - 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; - } + if ( this.boundingSphere !== null ) { - blurUniforms['envMap'].value = targetIn.texture; - blurUniforms['samples'].value = samples; - blurUniforms['weights'].value = weights; - blurUniforms['latitudinal'].value = direction === 'latitudinal'; + this.computeBoundingSphere(); - if (poleAxis) { - blurUniforms['poleAxis'].value = poleAxis; } - const { - _lodMax - } = this; - blurUniforms['dTheta'].value = radiansPerPixel; - blurUniforms['mipInt'].value = _lodMax - lodIn; - 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); + return this; - renderer.setRenderTarget(targetOut); - renderer.render(blurMesh, _flatCamera); } - } + applyQuaternion( q ) { - function _createPlanes(lodMax) { - const lodPlanes = []; - const sizeLods = []; - const sigmas = []; - let lod = lodMax; - const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; + _m1.makeRotationFromQuaternion( q ); - for (let i = 0; i < totalLods; i++) { - const sizeLod = Math.pow(2, lod); - sizeLods.push(sizeLod); - let sigma = 1.0 / sizeLod; + this.applyMatrix4( _m1 ); - if (i > lodMax - LOD_MIN) { - sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1]; - } else if (i === 0) { - sigma = 0; - } + return this; - sigmas.push(sigma); - const texelSize = 1.0 / (sizeLod - 2); - const min = -texelSize; - const max = 1 + texelSize; - const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; - const cubeFaces = 6; - const vertices = 6; - const positionSize = 3; - const uvSize = 2; - const faceIndexSize = 1; - 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; - const coordinates = [x, y, 0, x + 2 / 3, y, 0, x + 2 / 3, y + 1, 0, x, y, 0, x + 2 / 3, y + 1, 0, x, y + 1, 0]; - position.set(coordinates, positionSize * vertices * face); - uv.set(uv1, uvSize * vertices * face); - const fill = [face, face, face, face, face, face]; - faceIndex.set(fill, faceIndexSize * vertices * face); - } + rotateX( angle ) { - 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); + // rotate geometry around world x-axis - if (lod > LOD_MIN) { - lod--; - } - } + _m1.makeRotationX( angle ); - return { - lodPlanes, - sizeLods, - sigmas - }; - } + this.applyMatrix4( _m1 ); - function _createRenderTarget(width, height, params) { - const cubeUVRenderTarget = new WebGLRenderTarget(width, height, params); - cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; - cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; - cubeUVRenderTarget.scissorTest = true; - return cubeUVRenderTarget; - } + return this; - 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); - const shaderMaterial = new ShaderMaterial({ - name: 'SphericalGaussianBlur', - defines: { - 'n': MAX_SAMPLES, - 'CUBEUV_TEXEL_WIDTH': 1.0 / width, - 'CUBEUV_TEXEL_HEIGHT': 1.0 / height, - 'CUBEUV_MAX_MIP': `${lodMax}.0` - }, - uniforms: { - 'envMap': { - value: null - }, - 'samples': { - value: 1 - }, - 'weights': { - value: weights - }, - 'latitudinal': { - value: false - }, - 'dTheta': { - value: 0 - }, - 'mipInt': { - value: 0 - }, - 'poleAxis': { - value: poleAxis - } - }, - vertexShader: _getCommonVertexShader(), - fragmentShader: - /* glsl */ - ` + rotateY( angle ) { - precision mediump float; - precision mediump int; + // rotate geometry around world y-axis - varying vec3 vOutputDirection; + _m1.makeRotationY( angle ); - uniform sampler2D envMap; - uniform int samples; - uniform float weights[ n ]; - uniform bool latitudinal; - uniform float dTheta; - uniform float mipInt; - uniform vec3 poleAxis; + this.applyMatrix4( _m1 ); - #define ENVMAP_TYPE_CUBE_UV - #include + return this; - vec3 getSample( float theta, vec3 axis ) { + } - float cosTheta = cos( theta ); - // Rodrigues' axis-angle rotation - vec3 sampleDirection = vOutputDirection * cosTheta - + cross( axis, vOutputDirection ) * sin( theta ) - + axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta ); + rotateZ( angle ) { - return bilinearCubeUV( envMap, sampleDirection, mipInt ); + // rotate geometry around world z-axis - } + _m1.makeRotationZ( angle ); - void main() { + this.applyMatrix4( _m1 ); - vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection ); + return this; - if ( all( equal( axis, vec3( 0.0 ) ) ) ) { + } - axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x ); + translate( x, y, z ) { - } - - axis = normalize( axis ); - - gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); - gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis ); - - for ( int i = 1; i < n; i++ ) { - - if ( i >= samples ) { + // translate geometry - break; + _m1.makeTranslation( x, y, z ); - } + this.applyMatrix4( _m1 ); - float theta = dTheta * float( i ); - gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis ); - gl_FragColor.rgb += weights[ i ] * getSample( theta, axis ); + return this; - } + } - } - `, - blending: NoBlending, - depthTest: false, - depthWrite: false - }); - return shaderMaterial; - } + scale( x, y, z ) { - function _getEquirectMaterial() { - return new ShaderMaterial({ - name: 'EquirectangularToCubeUV', - uniforms: { - 'envMap': { - value: null - } - }, - vertexShader: _getCommonVertexShader(), - fragmentShader: - /* glsl */ - ` + // scale geometry - precision mediump float; - precision mediump int; + _m1.makeScale( x, y, z ); - varying vec3 vOutputDirection; + this.applyMatrix4( _m1 ); - uniform sampler2D envMap; + return this; - #include + } - void main() { + lookAt( vector ) { - vec3 outputDirection = normalize( vOutputDirection ); - vec2 uv = equirectUv( outputDirection ); + _obj.lookAt( vector ); - gl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 ); + _obj.updateMatrix(); - } - `, - blending: NoBlending, - depthTest: false, - depthWrite: false - }); - } + this.applyMatrix4( _obj.matrix ); - function _getCubemapMaterial() { - return new ShaderMaterial({ - name: 'CubemapToCubeUV', - uniforms: { - 'envMap': { - value: null - }, - 'flipEnvMap': { - value: -1 - } - }, - vertexShader: _getCommonVertexShader(), - fragmentShader: - /* glsl */ - ` + return this; - precision mediump float; - precision mediump int; + } - uniform float flipEnvMap; + center() { - varying vec3 vOutputDirection; + this.computeBoundingBox(); - uniform samplerCube envMap; + this.boundingBox.getCenter( _offset ).negate(); - void main() { + this.translate( _offset.x, _offset.y, _offset.z ); - gl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) ); + return this; - } - `, - blending: NoBlending, - depthTest: false, - depthWrite: false - }); - } + } - function _getCommonVertexShader() { - return ( - /* glsl */ - ` + setFromPoints( points ) { - precision mediump float; - precision mediump int; + const position = []; - attribute float faceIndex; + for ( let i = 0, l = points.length; i < l; i ++ ) { - varying vec3 vOutputDirection; + const point = points[ i ]; + position.push( point.x, point.y, point.z || 0 ); +<<<<<<< HEAD mat3 getRotationMatrix(vec3 axis, float angle) { axis = normalize(axis); float s = sin(angle); @@ -12480,1548 +10120,859 @@ } // RH coordinate system; PMREM face-indexing convention vec3 getDirection( vec2 uv, float face ) { +======= + } +>>>>>>> mrdoob-dev - uv = 2.0 * uv - 1.0; + this.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); - vec3 direction = vec3( uv, 1.0 ); + return this; - if ( face == 0.0 ) { + } - direction = direction.zyx; // ( 1, v, u ) pos x + computeBoundingBox() { - } else if ( face == 1.0 ) { + if ( this.boundingBox === null ) { - direction = direction.xzy; - direction.xz *= -1.0; // ( -u, 1, -v ) pos y + this.boundingBox = new Box3(); - } else if ( face == 2.0 ) { + } - direction.x *= -1.0; // ( -u, v, 1 ) pos z + const position = this.attributes.position; + const morphAttributesPosition = this.morphAttributes.position; - } else if ( face == 3.0 ) { + if ( position && position.isGLBufferAttribute ) { - direction = direction.zyx; - direction.xz *= -1.0; // ( -1, v, -u ) neg x + console.error( 'THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box. Alternatively set "mesh.frustumCulled" to "false".', this ); - } else if ( face == 4.0 ) { + this.boundingBox.set( + new Vector3( - Infinity, - Infinity, - Infinity ), + new Vector3( + Infinity, + Infinity, + Infinity ) + ); - direction = direction.xzy; - direction.xy *= -1.0; // ( -u, -1, v ) neg y + return; - } else if ( face == 5.0 ) { + } - direction.z *= -1.0; // ( u, v, -1 ) neg z + if ( position !== undefined ) { +<<<<<<< HEAD } mat3 rotationMatrix = getRotationMatrix(vec3(1.0, 0.0, 0.0), 1.57); direction = rotationMatrix * direction; return direction; +======= + this.boundingBox.setFromBufferAttribute( position ); - } + // process morph attributes if present +>>>>>>> mrdoob-dev - void main() { + if ( morphAttributesPosition ) { - vOutputDirection = getDirection( uv, faceIndex ); - gl_Position = vec4( position, 1.0 ); + for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - } - ` - ); - } + const morphAttribute = morphAttributesPosition[ i ]; + _box$1.setFromBufferAttribute( morphAttribute ); - function WebGLCubeUVMaps(renderer) { - let cubeUVmaps = new WeakMap(); - let pmremGenerator = null; + if ( this.morphTargetsRelative ) { - 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 + _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 ); - if (isEquirectMap || isCubeMap) { - if (texture.isRenderTargetTexture && texture.needsPMREMUpdate === true) { - texture.needsPMREMUpdate = false; - let renderTarget = cubeUVmaps.get(texture); - if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer); - renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture, renderTarget) : pmremGenerator.fromCubemap(texture, renderTarget); - cubeUVmaps.set(texture, renderTarget); - return renderTarget.texture; - } else { - if (cubeUVmaps.has(texture)) { - 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); - cubeUVmaps.set(texture, renderTarget); - texture.addEventListener('dispose', onTextureDispose); - return renderTarget.texture; - } else { - // image not yet ready. try the conversion next frame - return null; - } + this.boundingBox.expandByPoint( _box$1.min ); + this.boundingBox.expandByPoint( _box$1.max ); + } + } + } - } - return texture; - } + } else { - function isCubeTextureComplete(image) { - let count = 0; - const length = 6; + this.boundingBox.makeEmpty(); - for (let i = 0; i < length; i++) { - if (image[i] !== undefined) count++; } - return count === length; - } + if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { - function onTextureDispose(event) { - const texture = event.target; - texture.removeEventListener('dispose', onTextureDispose); - const cubemapUV = cubeUVmaps.get(texture); + console.error( 'THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); - 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 - }; - } + computeBoundingSphere() { - function WebGLExtensions(gl) { - const extensions = {}; + if ( this.boundingSphere === null ) { + + this.boundingSphere = new Sphere(); - function getExtension(name) { - if (extensions[name] !== undefined) { - return extensions[name]; } - let extension; + const position = this.attributes.position; + const morphAttributesPosition = this.morphAttributes.position; - 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; + if ( position && position.isGLBufferAttribute ) { - 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; + console.error( 'THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere. Alternatively set "mesh.frustumCulled" to "false".', this ); - case 'WEBGL_compressed_texture_s3tc': - extension = gl.getExtension('WEBGL_compressed_texture_s3tc') || gl.getExtension('MOZ_WEBGL_compressed_texture_s3tc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc'); - break; + this.boundingSphere.set( new Vector3(), Infinity ); - case 'WEBGL_compressed_texture_pvrtc': - extension = gl.getExtension('WEBGL_compressed_texture_pvrtc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc'); - break; + return; - default: - extension = gl.getExtension(name); } - extensions[name] = extension; - return extension; - } + if ( position ) { - return { - has: function (name) { - return getExtension(name) !== null; - }, - init: function (capabilities) { - if (capabilities.isWebGL2) { - getExtension('EXT_color_buffer_float'); - } else { - getExtension('WEBGL_depth_texture'); - getExtension('OES_texture_float'); - getExtension('OES_texture_half_float'); - getExtension('OES_texture_half_float_linear'); - getExtension('OES_standard_derivatives'); - getExtension('OES_element_index_uint'); - 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); + // first, find the center of the bounding sphere - if (extension === null) { - console.warn('THREE.WebGLRenderer: ' + name + ' extension not supported.'); - } + const center = this.boundingSphere.center; - return extension; - } - }; - } + _box$1.setFromBufferAttribute( position ); - function WebGLGeometries(gl, attributes, info, bindingStates) { - const geometries = {}; - const wireframeAttributes = new WeakMap(); + // process morph attributes if present - function onGeometryDispose(event) { - const geometry = event.target; + if ( morphAttributesPosition ) { - if (geometry.index !== null) { - attributes.remove(geometry.index); - } + for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - for (const name in geometry.attributes) { - attributes.remove(geometry.attributes[name]); - } + const morphAttribute = morphAttributesPosition[ i ]; + _boxMorphTargets.setFromBufferAttribute( morphAttribute ); - geometry.removeEventListener('dispose', onGeometryDispose); - delete geometries[geometry.id]; - const attribute = wireframeAttributes.get(geometry); + if ( this.morphTargetsRelative ) { - if (attribute) { - attributes.remove(attribute); - wireframeAttributes.delete(geometry); - } + _vector$8.addVectors( _box$1.min, _boxMorphTargets.min ); + _box$1.expandByPoint( _vector$8 ); - bindingStates.releaseStatesOfGeometry(geometry); + _vector$8.addVectors( _box$1.max, _boxMorphTargets.max ); + _box$1.expandByPoint( _vector$8 ); - if (geometry.isInstancedBufferGeometry === true) { - delete geometry._maxInstanceCount; - } // + } else { + _box$1.expandByPoint( _boxMorphTargets.min ); + _box$1.expandByPoint( _boxMorphTargets.max ); - info.memory.geometries--; - } + } - function get(object, geometry) { - if (geometries[geometry.id] === true) return geometry; - geometry.addEventListener('dispose', onGeometryDispose); - geometries[geometry.id] = true; - info.memory.geometries++; - return geometry; - } + } + + } - function update(geometry) { - const geometryAttributes = geometry.attributes; // Updating index buffer in VAO now. See WebGLBindingStates. + _box$1.getCenter( center ); - for (const name in geometryAttributes) { - attributes.update(geometryAttributes[name], gl.ARRAY_BUFFER); - } // morph targets + // 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 ++ ) { - const morphAttributes = geometry.morphAttributes; + _vector$8.fromBufferAttribute( position, i ); - for (const name in morphAttributes) { - const array = morphAttributes[name]; + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) ); - 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; + // process morph attributes if present - if (geometryIndex !== null) { - const array = geometryIndex.array; - version = geometryIndex.version; + if ( morphAttributesPosition ) { - for (let i = 0, l = array.length; i < l; i += 3) { - const a = array[i + 0]; - const b = array[i + 1]; - const c = array[i + 2]; - indices.push(a, b, b, c, c, a); - } - } else { - const array = geometryPosition.array; - version = geometryPosition.version; + for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { - const a = i + 0; - const b = i + 1; - const c = i + 2; - indices.push(a, b, b, c, c, a); - } - } + const morphAttribute = morphAttributesPosition[ i ]; + const morphTargetsRelative = this.morphTargetsRelative; - const attribute = new (arrayNeedsUint32(indices) ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); - attribute.version = version; // Updating index buffer in VAO now. See WebGLBindingStates - // + for ( let j = 0, jl = morphAttribute.count; j < jl; j ++ ) { - const previousAttribute = wireframeAttributes.get(geometry); - if (previousAttribute) attributes.remove(previousAttribute); // + _vector$8.fromBufferAttribute( morphAttribute, j ); - wireframeAttributes.set(geometry, attribute); - } + if ( morphTargetsRelative ) { - function getWireframeAttribute(geometry) { - const currentAttribute = wireframeAttributes.get(geometry); + _offset.fromBufferAttribute( position, j ); + _vector$8.add( _offset ); - if (currentAttribute) { - const geometryIndex = geometry.index; + } + + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) ); + + } - if (geometryIndex !== null) { - // if the attribute is obsolete, create a new one - if (currentAttribute.version < geometryIndex.version) { - updateWireframeAttribute(geometry); } + } - } else { - updateWireframeAttribute(geometry); - } - return wireframeAttributes.get(geometry); - } + this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); - return { - get: get, - update: update, - getWireframeAttribute: getWireframeAttribute - }; - } + if ( isNaN( this.boundingSphere.radius ) ) { - function WebGLIndexedBufferRenderer(gl, extensions, info, capabilities) { - const isWebGL2 = capabilities.isWebGL2; - let mode; + console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this ); - 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); - } + computeTangents() { - function renderInstances(start, count, primcount) { - if (primcount === 0) return; - let extension, methodName; + const index = this.index; + const attributes = this.attributes; - if (isWebGL2) { - extension = gl; - methodName = 'drawElementsInstanced'; - } else { - extension = extensions.get('ANGLE_instanced_arrays'); - methodName = 'drawElementsInstancedANGLE'; + // based on http://www.terathon.com/code/tangent.html + // (per vertex tangents) - if (extension === null) { - console.error('THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.'); - return; - } - } + if ( index === null || + attributes.position === undefined || + attributes.normal === undefined || + attributes.uv === undefined ) { - extension[methodName](mode, count, type, start * bytesPerElement, primcount); - info.update(count, mode, primcount); - } // + console.error( 'THREE.BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)' ); + return; + } - this.setMode = setMode; - this.setIndex = setIndex; - this.render = render; - this.renderInstances = renderInstances; - } + const indices = index.array; + const positions = attributes.position.array; + const normals = attributes.normal.array; + const uvs = attributes.uv.array; - function WebGLInfo(gl) { - const memory = { - geometries: 0, - textures: 0 - }; - const render = { - frame: 0, - calls: 0, - triangles: 0, - points: 0, - lines: 0 - }; + const nVertices = positions.length / 3; - function update(count, mode, instanceCount) { - render.calls++; + if ( this.hasAttribute( 'tangent' ) === false ) { - switch (mode) { - case gl.TRIANGLES: - render.triangles += instanceCount * (count / 3); - break; + this.setAttribute( 'tangent', new BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) ); - case gl.LINES: - render.lines += instanceCount * (count / 2); - break; + } - case gl.LINE_STRIP: - render.lines += instanceCount * (count - 1); - break; + const tangents = this.getAttribute( 'tangent' ).array; - case gl.LINE_LOOP: - render.lines += instanceCount * count; - break; + const tan1 = [], tan2 = []; - case gl.POINTS: - render.points += instanceCount * count; - break; + for ( let i = 0; i < nVertices; i ++ ) { + + tan1[ i ] = new Vector3(); + tan2[ i ] = new Vector3(); - default: - console.error('THREE.WebGLInfo: Unknown draw mode:', mode); - break; } - } - function reset() { - render.frame++; - render.calls = 0; - render.triangles = 0; - render.points = 0; - render.lines = 0; - } + const vA = new Vector3(), + vB = new Vector3(), + vC = new Vector3(), - return { - memory: memory, - render: render, - programs: null, - autoReset: true, - reset: reset, - update: update - }; - } + uvA = new Vector2(), + uvB = new Vector2(), + uvC = new Vector2(), - function numericalSort(a, b) { - return a[0] - b[0]; - } + sdir = new Vector3(), + tdir = new Vector3(); - function absNumericalSort(a, b) { - return Math.abs(b[1]) - Math.abs(a[1]); - } + function handleTriangle( a, b, c ) { - 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 Int16Array) denominator = 32767;else if (array instanceof Int32Array) denominator = 2147483647;else console.error('THREE.WebGLMorphtargets: Unsupported morph attribute data type: ', array); - morph.divideScalar(denominator); - } + vA.fromArray( positions, a * 3 ); + vB.fromArray( positions, b * 3 ); + vC.fromArray( positions, c * 3 ); - function WebGLMorphtargets(gl, capabilities, textures) { - const influencesList = {}; - const morphInfluences = new Float32Array(8); - const morphTextures = new WeakMap(); - const morph = new Vector4(); - const workInfluences = []; + uvA.fromArray( uvs, a * 2 ); + uvB.fromArray( uvs, b * 2 ); + uvC.fromArray( uvs, c * 2 ); - for (let i = 0; i < 8; i++) { - workInfluences[i] = [i, 0]; - } + vB.sub( vA ); + vC.sub( vA ); - function update(object, geometry, material, program) { - const objectInfluences = object.morphTargetInfluences; + uvB.sub( uvA ); + uvC.sub( uvA ); - 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); + const r = 1.0 / ( uvB.x * uvC.y - uvC.x * uvB.y ); - if (entry === undefined || entry.count !== morphTargetsCount) { - if (entry !== undefined) entry.texture.dispose(); - const hasMorphPosition = geometry.morphAttributes.position !== undefined; - const hasMorphNormals = geometry.morphAttributes.normal !== undefined; - const hasMorphColors = geometry.morphAttributes.color !== undefined; - const morphTargets = geometry.morphAttributes.position || []; - const morphNormals = geometry.morphAttributes.normal || []; - const morphColors = geometry.morphAttributes.color || []; - let vertexDataCount = 0; - if (hasMorphPosition === true) vertexDataCount = 1; - if (hasMorphNormals === true) vertexDataCount = 2; - if (hasMorphColors === true) vertexDataCount = 3; - let width = geometry.attributes.position.count * vertexDataCount; - let height = 1; + // silently ignore degenerate uv triangles having coincident or colinear vertices - if (width > capabilities.maxTextureSize) { - height = Math.ceil(width / capabilities.maxTextureSize); - width = capabilities.maxTextureSize; - } + if ( ! isFinite( r ) ) return; - const buffer = new Float32Array(width * height * 4 * morphTargetsCount); - const texture = new DataArrayTexture(buffer, width, height, morphTargetsCount); - texture.type = FloatType; - texture.needsUpdate = true; // fill buffer + sdir.copy( vB ).multiplyScalar( uvC.y ).addScaledVector( vC, - uvB.y ).multiplyScalar( r ); + tdir.copy( vC ).multiplyScalar( uvB.x ).addScaledVector( vB, - uvC.x ).multiplyScalar( r ); - const vertexDataStride = vertexDataCount * 4; + tan1[ a ].add( sdir ); + tan1[ b ].add( sdir ); + tan1[ c ].add( sdir ); - 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; + tan2[ a ].add( tdir ); + tan2[ b ].add( tdir ); + tan2[ c ].add( tdir ); - 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; - } + let groups = this.groups; - 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 ( groups.length === 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; - buffer[offset + stride + 11] = morphColor.itemSize === 4 ? morph.w : 1; - } - } - } + groups = [ { + start: 0, + count: indices.length + } ]; - 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); - } + for ( let i = 0, il = groups.length; i < il; ++ i ) { - geometry.addEventListener('dispose', disposeTexture); - } // + const group = groups[ i ]; + + const start = group.start; + const count = group.count; + for ( let j = start, jl = start + count; j < jl; j += 3 ) { - let morphInfluencesSum = 0; + handleTriangle( + indices[ j + 0 ], + indices[ j + 1 ], + indices[ j + 2 ] + ); - 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); - program.getUniforms().setValue(gl, 'morphTargetsTexture', entry.texture, textures); - program.getUniforms().setValue(gl, 'morphTargetsTextureSize', entry.size); - } 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 = []; + const tmp = new Vector3(), tmp2 = new Vector3(); + const n = new Vector3(), n2 = new Vector3(); - for (let i = 0; i < length; i++) { - influences[i] = [i, 0]; - } + function handleVertex( v ) { - influencesList[geometry.id] = influences; - } // Collect influences + n.fromArray( normals, v * 3 ); + n2.copy( n ); + const t = tan1[ v ]; - for (let i = 0; i < length; i++) { - const influence = influences[i]; - influence[0] = i; - influence[1] = objectInfluences[i]; - } + // Gram-Schmidt orthogonalize - influences.sort(absNumericalSort); + tmp.copy( t ); + tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize(); - for (let i = 0; i < 8; i++) { - if (i < length && influences[i][1]) { - workInfluences[i][0] = influences[i][0]; - workInfluences[i][1] = influences[i][1]; - } else { - workInfluences[i][0] = Number.MAX_SAFE_INTEGER; - workInfluences[i][1] = 0; - } - } + // Calculate handedness - workInfluences.sort(numericalSort); - const morphTargets = geometry.morphAttributes.position; - const morphNormals = geometry.morphAttributes.normal; - let morphInfluencesSum = 0; + tmp2.crossVectors( n2, t ); + const test = tmp2.dot( tan2[ v ] ); + const w = ( test < 0.0 ) ? - 1.0 : 1.0; - for (let i = 0; i < 8; i++) { - const influence = workInfluences[i]; - const index = influence[0]; - const value = influence[1]; + tangents[ v * 4 ] = tmp.x; + tangents[ v * 4 + 1 ] = tmp.y; + tangents[ v * 4 + 2 ] = tmp.z; + tangents[ v * 4 + 3 ] = w; - 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]); - } + for ( let i = 0, il = groups.length; i < il; ++ i ) { - morphInfluences[i] = value; - morphInfluencesSum += value; - } else { - if (morphTargets && geometry.hasAttribute('morphTarget' + i) === true) { - geometry.deleteAttribute('morphTarget' + i); - } + const group = groups[ i ]; - if (morphNormals && geometry.hasAttribute('morphNormal' + i) === true) { - geometry.deleteAttribute('morphNormal' + i); - } + const start = group.start; + const count = group.count; - morphInfluences[i] = 0; - } - } // GLSL shader uses formula baseinfluence * base + sum(target * influence) - // This allows us to switch between absolute morphs and relative morphs without changing shader code - // When baseinfluence = 1 - sum(influence), the above is equivalent to sum((target - base) * influence) + for ( let j = start, jl = start + count; j < jl; j += 3 ) { + handleVertex( indices[ j + 0 ] ); + handleVertex( indices[ j + 1 ] ); + handleVertex( indices[ j + 2 ] ); + + } - const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; - program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence); - program.getUniforms().setValue(gl, 'morphTargetInfluences', morphInfluences); } + } - return { - update: update - }; - } + computeVertexNormals() { - function WebGLObjects(gl, geometries, attributes, info) { - let updateMap = new WeakMap(); + const index = this.index; + const positionAttribute = this.getAttribute( 'position' ); - function update(object) { - const frame = info.render.frame; - const geometry = object.geometry; - const buffergeometry = geometries.get(object, geometry); // Update once per frame + if ( positionAttribute !== undefined ) { - if (updateMap.get(buffergeometry) !== frame) { - geometries.update(buffergeometry); - updateMap.set(buffergeometry, frame); - } + let normalAttribute = this.getAttribute( 'normal' ); - if (object.isInstancedMesh) { - if (object.hasEventListener('dispose', onInstancedMeshDispose) === false) { - object.addEventListener('dispose', onInstancedMeshDispose); - } + if ( normalAttribute === undefined ) { - attributes.update(object.instanceMatrix, gl.ARRAY_BUFFER); + normalAttribute = new BufferAttribute( new Float32Array( positionAttribute.count * 3 ), 3 ); + this.setAttribute( 'normal', normalAttribute ); - if (object.instanceColor !== null) { - attributes.update(object.instanceColor, gl.ARRAY_BUFFER); - } - } + } else { - return buffergeometry; - } + // reset existing normals to zero - function dispose() { - updateMap = new WeakMap(); - } + for ( let i = 0, il = normalAttribute.count; i < il; i ++ ) { - function onInstancedMeshDispose(event) { - const instancedMesh = event.target; - instancedMesh.removeEventListener('dispose', onInstancedMeshDispose); - attributes.remove(instancedMesh.instanceMatrix); - if (instancedMesh.instanceColor !== null) attributes.remove(instancedMesh.instanceColor); - } + normalAttribute.setXYZ( i, 0, 0, 0 ); - return { - update: update, - dispose: dispose - }; - } + } - /** - * Uniforms of a program. - * Those form a tree structure with a special top-level container for the root, - * which you get by calling 'new WebGLUniforms( gl, program )'. - * - * - * Properties of inner nodes including the top-level container: - * - * .seq - array of nested uniforms - * .map - nested uniforms by name - * - * - * Methods of all nodes except the top-level container: - * - * .setValue( gl, value, [textures] ) - * - * uploads a uniform value(s) - * the 'textures' parameter is needed for sampler uniforms - * - * - * Static methods of the top-level container (textures factorizations): - * - * .upload( gl, seq, values, textures ) - * - * sets uniforms in 'seq' to 'values[id].value' - * - * .seqWithValue( seq, values ) : filteredSeq - * - * filters 'seq' entries with corresponding entry in values - * - * - * Methods of the top-level container (textures factorizations): - * - * .setValue( gl, name, value, textures ) - * - * sets uniform with name 'name' to 'value' - * - * .setOptional( gl, obj, prop ) - * - * like .set for an optional property of the object - * - */ - const emptyTexture = new Texture(); - const emptyArrayTexture = new DataArrayTexture(); - const empty3dTexture = new Data3DTexture(); - const emptyCubeTexture = new CubeTexture(); // --- Utilities --- - // Array Caches (provide typed arrays for temporary by size) + } - const arrayCacheF32 = []; - const arrayCacheI32 = []; // Float32Array caches used for uploading Matrix uniforms + const pA = new Vector3(), pB = new Vector3(), pC = new Vector3(); + const nA = new Vector3(), nB = new Vector3(), nC = new Vector3(); + const cb = new Vector3(), ab = new Vector3(); - const mat4array = new Float32Array(16); - const mat3array = new Float32Array(9); - const mat2array = new Float32Array(4); // Flattening for arrays of vectors and matrices + // indexed elements - function flatten(array, nBlocks, blockSize) { - const firstElem = array[0]; - if (firstElem <= 0 || firstElem > 0) return array; // unoptimized: ! isNaN( firstElem ) - // see http://jacksondunstan.com/articles/983 + if ( index ) { - const n = nBlocks * blockSize; - let r = arrayCacheF32[n]; + for ( let i = 0, il = index.count; i < il; i += 3 ) { - if (r === undefined) { - r = new Float32Array(n); - arrayCacheF32[n] = r; - } + const vA = index.getX( i + 0 ); + const vB = index.getX( i + 1 ); + const vC = index.getX( i + 2 ); - if (nBlocks !== 0) { - firstElem.toArray(r, 0); + pA.fromBufferAttribute( positionAttribute, vA ); + pB.fromBufferAttribute( positionAttribute, vB ); + pC.fromBufferAttribute( positionAttribute, vC ); - for (let i = 1, offset = 0; i !== nBlocks; ++i) { - offset += blockSize; - array[i].toArray(r, offset); - } - } + cb.subVectors( pC, pB ); + ab.subVectors( pA, pB ); + cb.cross( ab ); - return r; - } + nA.fromBufferAttribute( normalAttribute, vA ); + nB.fromBufferAttribute( normalAttribute, vB ); + nC.fromBufferAttribute( normalAttribute, vC ); - function arraysEqual(a, b) { - if (a.length !== b.length) return false; + nA.add( cb ); + nB.add( cb ); + nC.add( cb ); - for (let i = 0, l = a.length; i < l; i++) { - if (a[i] !== b[i]) return false; - } + normalAttribute.setXYZ( vA, nA.x, nA.y, nA.z ); + normalAttribute.setXYZ( vB, nB.x, nB.y, nB.z ); + normalAttribute.setXYZ( vC, nC.x, nC.y, nC.z ); - return true; - } + } - function copyArray(a, b) { - for (let i = 0, l = b.length; i < l; i++) { - a[i] = b[i]; - } - } // Texture unit allocation + } else { + // non-indexed elements (unconnected triangle soup) - function allocTexUnits(textures, n) { - let r = arrayCacheI32[n]; + for ( let i = 0, il = positionAttribute.count; i < il; i += 3 ) { - if (r === undefined) { - r = new Int32Array(n); - arrayCacheI32[n] = r; - } + pA.fromBufferAttribute( positionAttribute, i + 0 ); + pB.fromBufferAttribute( positionAttribute, i + 1 ); + pC.fromBufferAttribute( positionAttribute, i + 2 ); - for (let i = 0; i !== n; ++i) { - r[i] = textures.allocateTextureUnit(); - } + cb.subVectors( pC, pB ); + ab.subVectors( pA, pB ); + cb.cross( ab ); - return r; - } // --- Setters --- - // Note: Defining these methods externally, because they come in a bunch - // and this way their names minify. - // Single scalar + normalAttribute.setXYZ( i + 0, cb.x, cb.y, cb.z ); + normalAttribute.setXYZ( i + 1, cb.x, cb.y, cb.z ); + normalAttribute.setXYZ( i + 2, cb.x, cb.y, cb.z ); + } - 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) + } + this.normalizeNormals(); - function setValueV2f(gl, v) { - const cache = this.cache; + normalAttribute.needsUpdate = true; - if (v.x !== undefined) { - if (cache[0] !== v.x || cache[1] !== v.y) { - gl.uniform2f(this.addr, v.x, v.y); - cache[0] = v.x; - cache[1] = v.y; } - } else { - if (arraysEqual(cache, v)) return; - gl.uniform2fv(this.addr, v); - copyArray(cache, v); + } - } - function setValueV3f(gl, v) { - const cache = this.cache; + // @deprecated since r144 - if (v.x !== undefined) { - if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) { - gl.uniform3f(this.addr, v.x, v.y, v.z); - cache[0] = v.x; - cache[1] = v.y; - cache[2] = v.z; - } - } else if (v.r !== undefined) { - if (cache[0] !== v.r || cache[1] !== v.g || cache[2] !== v.b) { - gl.uniform3f(this.addr, v.r, v.g, v.b); - cache[0] = v.r; - cache[1] = v.g; - cache[2] = v.b; - } - } else { - if (arraysEqual(cache, v)) return; - gl.uniform3fv(this.addr, v); - copyArray(cache, v); - } - } + merge() { - function setValueV4f(gl, v) { - const cache = this.cache; + console.error( 'THREE.BufferGeometry.merge() has been removed. Use THREE.BufferGeometryUtils.mergeBufferGeometries() instead.' ); + return this; - if (v.x !== undefined) { - if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) { - gl.uniform4f(this.addr, v.x, v.y, v.z, v.w); - cache[0] = v.x; - cache[1] = v.y; - cache[2] = v.z; - cache[3] = v.w; - } - } else { - if (arraysEqual(cache, v)) return; - gl.uniform4fv(this.addr, v); - copyArray(cache, v); } - } // Single matrix (from flat array or THREE.MatrixN) + normalizeNormals() { - function setValueM2(gl, v) { - const cache = this.cache; - const elements = v.elements; + const normals = this.attributes.normal; - if (elements === undefined) { - if (arraysEqual(cache, v)) return; - gl.uniformMatrix2fv(this.addr, false, v); - copyArray(cache, v); - } else { - if (arraysEqual(cache, elements)) return; - mat2array.set(elements); - gl.uniformMatrix2fv(this.addr, false, mat2array); - copyArray(cache, elements); - } - } + for ( let i = 0, il = normals.count; i < il; i ++ ) { - function setValueM3(gl, v) { - const cache = this.cache; - const elements = v.elements; + _vector$8.fromBufferAttribute( normals, i ); - if (elements === undefined) { - if (arraysEqual(cache, v)) return; - gl.uniformMatrix3fv(this.addr, false, v); - copyArray(cache, v); - } else { - if (arraysEqual(cache, elements)) return; - mat3array.set(elements); - gl.uniformMatrix3fv(this.addr, false, mat3array); - copyArray(cache, elements); - } - } + _vector$8.normalize(); - function setValueM4(gl, v) { - const cache = this.cache; - const elements = v.elements; + normals.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z ); + + } - if (elements === undefined) { - if (arraysEqual(cache, v)) return; - gl.uniformMatrix4fv(this.addr, false, v); - copyArray(cache, v); - } else { - if (arraysEqual(cache, elements)) return; - mat4array.set(elements); - gl.uniformMatrix4fv(this.addr, false, mat4array); - copyArray(cache, elements); } - } // Single integer / boolean + toNonIndexed() { - 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) + function convertBufferAttribute( attribute, indices ) { + const array = attribute.array; + const itemSize = attribute.itemSize; + const normalized = attribute.normalized; - function setValueV2i(gl, v) { - const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform2iv(this.addr, v); - copyArray(cache, v); - } + const array2 = new array.constructor( indices.length * itemSize ); - function setValueV3i(gl, v) { - const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform3iv(this.addr, v); - copyArray(cache, v); - } + let index = 0, index2 = 0; - function setValueV4i(gl, v) { - const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform4iv(this.addr, v); - copyArray(cache, v); - } // Single unsigned integer + for ( let i = 0, l = indices.length; i < l; i ++ ) { + if ( attribute.isInterleavedBufferAttribute ) { - 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) + index = indices[ i ] * attribute.data.stride + attribute.offset; + } else { - function setValueV2ui(gl, v) { - const cache = this.cache; - if (arraysEqual(cache, v)) return; - gl.uniform2uiv(this.addr, v); - copyArray(cache, v); - } + index = indices[ i ] * itemSize; - function setValueV3ui(gl, v) { - const cache = this.cache; - 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) + for ( let j = 0; j < itemSize; j ++ ) { + array2[ index2 ++ ] = array[ index ++ ]; - 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); - } + return new BufferAttribute( array2, itemSize, normalized ); - 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); - } + if ( this.index === null ) { - function setValueT6(gl, v, textures) { - const cache = this.cache; - const unit = textures.allocateTextureUnit(); + console.warn( 'THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.' ); + return this; - if (cache[0] !== unit) { - gl.uniform1i(this.addr, unit); - cache[0] = unit; - } + } - textures.setTextureCube(v || emptyCubeTexture, unit); - } + const geometry2 = new BufferGeometry(); - function setValueT2DArray1(gl, v, textures) { - const cache = this.cache; - const unit = textures.allocateTextureUnit(); + const indices = this.index.array; + const attributes = this.attributes; - if (cache[0] !== unit) { - gl.uniform1i(this.addr, unit); - cache[0] = unit; - } + // attributes - textures.setTexture2DArray(v || emptyArrayTexture, unit); - } // Helper to pick the right setter for the singular case + for ( const name in attributes ) { + const attribute = attributes[ name ]; - function getSingularSetter(type) { - switch (type) { - case 0x1406: - return setValueV1f; - // FLOAT + const newAttribute = convertBufferAttribute( attribute, indices ); - case 0x8b50: - return setValueV2f; - // _VEC2 + geometry2.setAttribute( name, newAttribute ); - case 0x8b51: - return setValueV3f; - // _VEC3 + } - case 0x8b52: - return setValueV4f; - // _VEC4 + // morph attributes - case 0x8b5a: - return setValueM2; - // _MAT2 + const morphAttributes = this.morphAttributes; - case 0x8b5b: - return setValueM3; - // _MAT3 + for ( const name in morphAttributes ) { - case 0x8b5c: - return setValueM4; - // _MAT4 + const morphArray = []; + const morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes - case 0x1404: - case 0x8b56: - return setValueV1i; - // INT, BOOL + for ( let i = 0, il = morphAttribute.length; i < il; i ++ ) { - case 0x8b53: - case 0x8b57: - return setValueV2i; - // _VEC2 + const attribute = morphAttribute[ i ]; - case 0x8b54: - case 0x8b58: - return setValueV3i; - // _VEC3 + const newAttribute = convertBufferAttribute( attribute, indices ); - case 0x8b55: - case 0x8b59: - return setValueV4i; - // _VEC4 + morphArray.push( newAttribute ); - case 0x1405: - return setValueV1ui; - // UINT + } - case 0x8dc6: - return setValueV2ui; - // _VEC2 + geometry2.morphAttributes[ name ] = morphArray; - case 0x8dc7: - return setValueV3ui; - // _VEC3 + } - case 0x8dc8: - return setValueV4ui; - // _VEC4 + geometry2.morphTargetsRelative = this.morphTargetsRelative; - case 0x8b5e: // SAMPLER_2D + // groups - case 0x8d66: // SAMPLER_EXTERNAL_OES + const groups = this.groups; - case 0x8dca: // INT_SAMPLER_2D + for ( let i = 0, l = groups.length; i < l; i ++ ) { - case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D + const group = groups[ i ]; + geometry2.addGroup( group.start, group.count, group.materialIndex ); - case 0x8b62: - // SAMPLER_2D_SHADOW - return setValueT1; + } - case 0x8b5f: // SAMPLER_3D + return geometry2; - case 0x8dcb: // INT_SAMPLER_3D + } - case 0x8dd3: - // UNSIGNED_INT_SAMPLER_3D - return setValueT3D1; + toJSON() { - case 0x8b60: // SAMPLER_CUBE + const data = { + metadata: { + version: 4.5, + type: 'BufferGeometry', + generator: 'BufferGeometry.toJSON' + } + }; - case 0x8dcc: // INT_SAMPLER_CUBE + // standard BufferGeometry serialization - case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE + 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; - case 0x8dc5: - // SAMPLER_CUBE_SHADOW - return setValueT6; + if ( this.parameters !== undefined ) { - case 0x8dc1: // SAMPLER_2D_ARRAY + const parameters = this.parameters; - case 0x8dcf: // INT_SAMPLER_2D_ARRAY + for ( const key in parameters ) { - case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY + if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; - case 0x8dc4: - // SAMPLER_2D_ARRAY_SHADOW - return setValueT2DArray1; - } - } // Array of scalars + } + return data; - function setValueV1fArray(gl, v) { - gl.uniform1fv(this.addr, v); - } // Array of vectors (from flat array or array of THREE.VectorN) + } + // for simplicity the code assumes attributes are not shared across geometries, see #15811 - function setValueV2fArray(gl, v) { - const data = flatten(v, this.size, 2); - gl.uniform2fv(this.addr, data); - } + data.data = { attributes: {} }; - function setValueV3fArray(gl, v) { - const data = flatten(v, this.size, 3); - gl.uniform3fv(this.addr, data); - } + const index = this.index; - 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) + if ( index !== null ) { + data.data.index = { + type: index.array.constructor.name, + array: Array.prototype.slice.call( index.array ) + }; - 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); - } + const attributes = this.attributes; - function setValueM4Array(gl, v) { - const data = flatten(v, this.size, 16); - gl.uniformMatrix4fv(this.addr, false, data); - } // Array of integer / boolean + for ( const key in attributes ) { + const attribute = attributes[ key ]; - function setValueV1iArray(gl, v) { - gl.uniform1iv(this.addr, v); - } // Array of integer / boolean vectors (from flat array) + data.data.attributes[ key ] = attribute.toJSON( data.data ); + } - function setValueV2iArray(gl, v) { - gl.uniform2iv(this.addr, v); - } + const morphAttributes = {}; + let hasMorphAttributes = false; - function setValueV3iArray(gl, v) { - gl.uniform3iv(this.addr, v); - } + for ( const key in this.morphAttributes ) { - function setValueV4iArray(gl, v) { - gl.uniform4iv(this.addr, v); - } // Array of unsigned integer + const attributeArray = this.morphAttributes[ key ]; + const array = []; - function setValueV1uiArray(gl, v) { - gl.uniform1uiv(this.addr, v); - } // Array of unsigned integer vectors (from flat array) + for ( let i = 0, il = attributeArray.length; i < il; i ++ ) { + const attribute = attributeArray[ i ]; - function setValueV2uiArray(gl, v) { - gl.uniform2uiv(this.addr, v); - } + array.push( attribute.toJSON( data.data ) ); - 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) + if ( array.length > 0 ) { + morphAttributes[ key ] = array; - function setValueT1Array(gl, v, textures) { - const n = v.length; - const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); + hasMorphAttributes = true; - for (let i = 0; i !== n; ++i) { - textures.setTexture2D(v[i] || emptyTexture, units[i]); - } - } + } - function setValueT3DArray(gl, v, textures) { - const n = v.length; - const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); + } - for (let i = 0; i !== n; ++i) { - textures.setTexture3D(v[i] || empty3dTexture, units[i]); - } - } + if ( hasMorphAttributes ) { - function setValueT6Array(gl, v, textures) { - const n = v.length; - const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); + data.data.morphAttributes = morphAttributes; + data.data.morphTargetsRelative = this.morphTargetsRelative; - for (let i = 0; i !== n; ++i) { - textures.setTextureCube(v[i] || emptyCubeTexture, units[i]); - } - } + } - function setValueT2DArrayArray(gl, v, textures) { - const n = v.length; - const units = allocTexUnits(textures, n); - gl.uniform1iv(this.addr, units); + const groups = this.groups; - 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 + if ( groups.length > 0 ) { + data.data.groups = JSON.parse( JSON.stringify( groups ) ); - function getPureArraySetter(type) { - switch (type) { - case 0x1406: - return setValueV1fArray; - // FLOAT + } - case 0x8b50: - return setValueV2fArray; - // _VEC2 + const boundingSphere = this.boundingSphere; - case 0x8b51: - return setValueV3fArray; - // _VEC3 + if ( boundingSphere !== null ) { - case 0x8b52: - return setValueV4fArray; - // _VEC4 + data.data.boundingSphere = { + center: boundingSphere.center.toArray(), + radius: boundingSphere.radius + }; - case 0x8b5a: - return setValueM2Array; - // _MAT2 + } - case 0x8b5b: - return setValueM3Array; - // _MAT3 + return data; - case 0x8b5c: - return setValueM4Array; - // _MAT4 + } - case 0x1404: - case 0x8b56: - return setValueV1iArray; - // INT, BOOL + clone() { - case 0x8b53: - case 0x8b57: - return setValueV2iArray; - // _VEC2 + return new this.constructor().copy( this ); - case 0x8b54: - case 0x8b58: - return setValueV3iArray; - // _VEC3 + } - case 0x8b55: - case 0x8b59: - return setValueV4iArray; - // _VEC4 + copy( source ) { - case 0x1405: - return setValueV1uiArray; - // UINT + // reset - case 0x8dc6: - return setValueV2uiArray; - // _VEC2 + this.index = null; + this.attributes = {}; + this.morphAttributes = {}; + this.groups = []; + this.boundingBox = null; + this.boundingSphere = null; - case 0x8dc7: - return setValueV3uiArray; - // _VEC3 + // used for storing cloned, shared data - case 0x8dc8: - return setValueV4uiArray; - // _VEC4 + const data = {}; - case 0x8b5e: // SAMPLER_2D + // name - case 0x8d66: // SAMPLER_EXTERNAL_OES + this.name = source.name; - case 0x8dca: // INT_SAMPLER_2D + // index - case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D + const index = source.index; - case 0x8b62: - // SAMPLER_2D_SHADOW - return setValueT1Array; + if ( index !== null ) { - case 0x8b5f: // SAMPLER_3D + this.setIndex( index.clone( data ) ); - case 0x8dcb: // INT_SAMPLER_3D + } - case 0x8dd3: - // UNSIGNED_INT_SAMPLER_3D - return setValueT3DArray; + // attributes - case 0x8b60: // SAMPLER_CUBE + const attributes = source.attributes; - case 0x8dcc: // INT_SAMPLER_CUBE + for ( const name in attributes ) { - case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE + const attribute = attributes[ name ]; + this.setAttribute( name, attribute.clone( data ) ); - case 0x8dc5: - // SAMPLER_CUBE_SHADOW - return setValueT6Array; + } - case 0x8dc1: // SAMPLER_2D_ARRAY + // morph attributes - case 0x8dcf: // INT_SAMPLER_2D_ARRAY + const morphAttributes = source.morphAttributes; - case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY + for ( const name in morphAttributes ) { - case 0x8dc4: - // SAMPLER_2D_ARRAY_SHADOW - return setValueT2DArrayArray; - } - } // --- Uniform Classes --- + const array = []; + const morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes + for ( let i = 0, l = morphAttribute.length; i < l; i ++ ) { - class SingleUniform { - constructor(id, activeInfo, addr) { - this.id = id; - this.addr = addr; - this.cache = []; - this.setValue = getSingularSetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG - } + array.push( morphAttribute[ i ].clone( data ) ); - } + } - class PureArrayUniform { - constructor(id, activeInfo, addr) { - this.id = id; - this.addr = addr; - this.cache = []; - this.size = activeInfo.size; - this.setValue = getPureArraySetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG - } + this.morphAttributes[ name ] = array; - } + } - class StructuredUniform { - constructor(id) { - this.id = id; - this.seq = []; - this.map = {}; - } + this.morphTargetsRelative = source.morphTargetsRelative; - setValue(gl, value, textures) { - const seq = this.seq; + // 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 ); - for (let i = 0, n = seq.length; i !== n; ++i) { - const u = seq[i]; - u.setValue(gl, value[u.id], textures); } - } - } // --- Top-level --- - // Parser - builds up the property tree from the path strings + // bounding box + const boundingBox = source.boundingBox; - const RePathPart = /(\w+)(\])?(\[|\.)?/g; // extracts - // - the identifier (member name or array index) - // - followed by an optional right bracket (found when array index) - // - followed by an optional left bracket or dot (type of subscript) - // - // Note: These portions can be read in a non-overlapping fashion and - // allow straightforward parsing of the hierarchy that WebGL encodes - // in the uniform names. + if ( boundingBox !== null ) { - function addUniform(container, uniformObject) { - container.seq.push(uniformObject); - container.map[uniformObject.id] = uniformObject; - } + this.boundingBox = boundingBox.clone(); - function parseUniform(activeInfo, addr, container) { - const path = activeInfo.name, - pathLength = path.length; // reset RegExp object, because of the early exit of a previous run + } - RePathPart.lastIndex = 0; + // bounding sphere - while (true) { - const match = RePathPart.exec(path), - matchEnd = RePathPart.lastIndex; - let id = match[1]; - const idIsIndex = match[2] === ']', - subscript = match[3]; - if (idIsIndex) id = id | 0; // convert to integer + const boundingSphere = source.boundingSphere; - 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 ( boundingSphere !== null ) { - if (next === undefined) { - next = new StructuredUniform(id); - addUniform(container, next); - } + this.boundingSphere = boundingSphere.clone(); - container = next; } - } - } // Root Container + // draw range - class WebGLUniforms { - constructor(gl, program) { - this.seq = []; - this.map = {}; - const n = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + this.drawRange.start = source.drawRange.start; + this.drawRange.count = source.drawRange.count; - for (let i = 0; i < n; ++i) { - const info = gl.getActiveUniform(program, i), - addr = gl.getUniformLocation(program, info.name); - parseUniform(info, addr, this); - } - } + // user data - setValue(gl, name, value, textures) { - const u = this.map[name]; - if (u !== undefined) u.setValue(gl, value, textures); - } + this.userData = source.userData; - setOptional(gl, object, name) { - const v = object[name]; - if (v !== undefined) this.setValue(gl, name, v); - } + // geometry generator parameters - static upload(gl, seq, values, textures) { - for (let i = 0, n = seq.length; i !== n; ++i) { - const u = seq[i], - v = values[u.id]; + if ( source.parameters !== undefined ) this.parameters = Object.assign( {}, source.parameters ); + + return this; - if (v.needsUpdate !== false) { - // note: always updating when .needsUpdate is undefined - u.setValue(gl, v.value, textures); - } - } } - static seqWithValue(seq, values) { - const r = []; + dispose() { - for (let i = 0, n = seq.length; i !== n; ++i) { - const u = seq[i]; - if (u.id in values) r.push(u); - } + this.dispatchEvent( { type: 'dispose' } ); - return r; } } - function WebGLShader(gl, type, string) { - const shader = gl.createShader(type); - gl.shaderSource(shader, string); - gl.compileShader(shader); - return shader; - } + const _inverseMatrix$2 = /*@__PURE__*/ new Matrix4(); + const _ray$2 = /*@__PURE__*/ new Ray(); + const _sphere$3 = /*@__PURE__*/ new Sphere(); - let programIdCount = 0; + const _vA$1 = /*@__PURE__*/ new Vector3(); + const _vB$1 = /*@__PURE__*/ new Vector3(); + const _vC$1 = /*@__PURE__*/ new Vector3(); - 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); + const _tempA = /*@__PURE__*/ new Vector3(); + const _morphA = /*@__PURE__*/ new Vector3(); +<<<<<<< HEAD for (let i = from; i < to; i++) { const line = i + 1; lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`); } +======= + const _uvA$1 = /*@__PURE__*/ new Vector2(); + const _uvB$1 = /*@__PURE__*/ new Vector2(); + const _uvC$1 = /*@__PURE__*/ new Vector2(); +>>>>>>> mrdoob-dev - return lines2.join('\n'); - } + const _intersectionPoint = /*@__PURE__*/ new Vector3(); + const _intersectionPointWorld = /*@__PURE__*/ new Vector3(); - function getEncodingComponents(encoding) { - switch (encoding) { - case LinearEncoding: - return ['Linear', '( value )']; + class Mesh extends Object3D { - case sRGBEncoding: - return ['sRGB', '( value )']; + constructor( geometry = new BufferGeometry(), material = new MeshBasicMaterial() ) { - default: - console.warn('THREE.WebGLProgram: Unsupported encoding:', encoding); - return ['Linear', '( value )']; - } - } + super(); - 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); + this.isMesh = true; +<<<<<<< HEAD if (errorMatches) { // --enable-privileged-webgl-extension // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); @@ -14031,262 +10982,151 @@ return errors; } } +======= + this.type = 'Mesh'; +>>>>>>> mrdoob-dev - function getTexelEncodingFunction(functionName, encoding) { - const components = getEncodingComponents(encoding); - return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[0] + components[1] + '; }'; - } + this.geometry = geometry; + this.material = material; - function getToneMappingFunction(functionName, toneMapping) { - let toneMappingName; + this.updateMorphTargets(); - switch (toneMapping) { - case LinearToneMapping: - toneMappingName = 'Linear'; - break; + } - case ReinhardToneMapping: - toneMappingName = 'Reinhard'; - break; + copy( source, recursive ) { - case CineonToneMapping: - toneMappingName = 'OptimizedCineon'; - break; + super.copy( source, recursive ); - case ACESFilmicToneMapping: - toneMappingName = 'ACESFilmic'; - break; + if ( source.morphTargetInfluences !== undefined ) { - case CustomToneMapping: - toneMappingName = 'Custom'; - break; + this.morphTargetInfluences = source.morphTargetInfluences.slice(); - default: - console.warn('THREE.WebGLProgram: Unsupported toneMapping:', toneMapping); - toneMappingName = 'Linear'; - } + } - return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }'; - } + if ( source.morphTargetDictionary !== undefined ) { - 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'); - } + this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary ); - function generateDefines(defines) { - const chunks = []; + } + + this.material = source.material; + this.geometry = source.geometry; + + return this; - for (const name in defines) { - const value = defines[name]; - if (value === false) continue; - chunks.push('#define ' + name + ' ' + value); } - return chunks.join('\n'); - } + updateMorphTargets() { - function fetchAttributeLocations(gl, program) { - const attributes = {}; - const n = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); + const geometry = this.geometry; - 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 ); + const morphAttributes = geometry.morphAttributes; + const keys = Object.keys( morphAttributes ); - attributes[name] = { - type: info.type, - location: gl.getAttribLocation(program, name), - locationSize: locationSize - }; - } + if ( keys.length > 0 ) { - return attributes; - } + const morphAttribute = morphAttributes[ keys[ 0 ] ]; - function filterEmptyLine(string) { - return string !== ''; - } + if ( morphAttribute !== undefined ) { - 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); - } + this.morphTargetInfluences = []; + this.morphTargetDictionary = {}; - function replaceClippingPlaneNums(string, parameters) { - return string.replace(/NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, parameters.numClippingPlanes - parameters.numClipIntersection); - } // Resolve Includes + for ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) { + const name = morphAttribute[ m ].name || String( m ); - const includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; + this.morphTargetInfluences.push( 0 ); + this.morphTargetDictionary[ name ] = m; - 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 + getVertexPosition( index, target ) { + const geometry = this.geometry; + const position = geometry.attributes.position; + const morphPosition = geometry.morphAttributes.position; + const morphTargetsRelative = geometry.morphTargetsRelative; - 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; + target.fromBufferAttribute( position, index ); - function unrollLoops(string) { - return string.replace(unrollLoopPattern, loopReplacer).replace(deprecatedUnrollLoopPattern, deprecatedLoopReplacer); - } + const morphInfluences = this.morphTargetInfluences; - 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); - } + if ( morphPosition && morphInfluences ) { - function loopReplacer(match, start, end, snippet) { - let string = ''; + _morphA.set( 0, 0, 0 ); - for (let i = parseInt(start); i < parseInt(end); i++) { - string += snippet.replace(/\[\s*i\s*\]/g, '[ ' + i + ' ]').replace(/UNROLLED_LOOP_INDEX/g, i); - } + for ( let i = 0, il = morphPosition.length; i < il; i ++ ) { - return string; - } // + const influence = morphInfluences[ i ]; + const morphAttribute = morphPosition[ i ]; + if ( influence === 0 ) continue; - function generatePrecision(parameters) { - let precisionstring = 'precision ' + parameters.precision + ' float;\nprecision ' + parameters.precision + ' int;'; + _tempA.fromBufferAttribute( morphAttribute, index ); - if (parameters.precision === 'highp') { - precisionstring += '\n#define HIGH_PRECISION'; - } else if (parameters.precision === 'mediump') { - precisionstring += '\n#define MEDIUM_PRECISION'; - } else if (parameters.precision === 'lowp') { - precisionstring += '\n#define LOW_PRECISION'; - } + if ( morphTargetsRelative ) { - return precisionstring; - } + _morphA.addScaledVector( _tempA, influence ); - function generateShadowMapTypeDefine(parameters) { - let shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; + } else { - if (parameters.shadowMapType === PCFShadowMap) { - shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; - } else if (parameters.shadowMapType === PCFSoftShadowMap) { - shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; - } else if (parameters.shadowMapType === VSMShadowMap) { - shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; - } + _morphA.addScaledVector( _tempA.sub( target ), influence ); - 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; + target.add( _morphA ); - case CubeUVReflectionMapping: - envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; - break; } - } - return envMapTypeDefine; - } + if ( this.isSkinnedMesh ) { - function generateEnvMapModeDefine(parameters) { - let envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; + this.boneTransform( index, target ); - if (parameters.envMap) { - switch (parameters.envMapMode) { - case CubeRefractionMapping: - envMapModeDefine = 'ENVMAP_MODE_REFRACTION'; - break; } + + return target; + } - return envMapModeDefine; - } + raycast( raycaster, intersects ) { - function generateEnvMapBlendingDefine(parameters) { - let envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; + const geometry = this.geometry; + const material = this.material; + const matrixWorld = this.matrixWorld; - if (parameters.envMap) { - switch (parameters.combine) { - case MultiplyOperation: - envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; - break; + if ( material === undefined ) return; - case MixOperation: - envMapBlendingDefine = 'ENVMAP_BLENDING_MIX'; - break; + // Checking boundingSphere distance to ray - case AddOperation: - envMapBlendingDefine = 'ENVMAP_BLENDING_ADD'; - break; - } - } + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - return envMapBlendingDefine; - } + _sphere$3.copy( geometry.boundingSphere ); + _sphere$3.applyMatrix4( matrixWorld ); - function generateCubeUVSize(parameters) { - const imageHeight = parameters.envMapCubeUVHeight; - if (imageHeight === null) return null; - const maxMip = Math.log2(imageHeight) - 2; - const texelHeight = 1.0 / imageHeight; - const texelWidth = 1.0 / (3 * Math.max(Math.pow(2, maxMip), 7 * 16)); - return { - texelWidth, - texelHeight, - maxMip - }; - } + if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return; - 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; - let fragmentShader = parameters.fragmentShader; - const shadowMapTypeDefine = generateShadowMapTypeDefine(parameters); - const envMapTypeDefine = generateEnvMapTypeDefine(parameters); - const envMapModeDefine = generateEnvMapModeDefine(parameters); - const envMapBlendingDefine = generateEnvMapBlendingDefine(parameters); - const envMapCubeUVSize = generateCubeUVSize(parameters); - const customExtensions = parameters.isWebGL2 ? '' : generateExtensions(parameters); - const customDefines = generateDefines(defines); - const program = gl.createProgram(); - let prefixVertex, prefixFragment; - let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : ''; + // - if (parameters.isRawShaderMaterial) { - prefixVertex = [customDefines].filter(filterEmptyLine).join('\n'); + _inverseMatrix$2.copy( matrixWorld ).invert(); + _ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 ); - if (prefixVertex.length > 0) { - prefixVertex += '\n'; - } + // Check boundingBox before continuing - prefixFragment = [customExtensions, customDefines].filter(filterEmptyLine).join('\n'); + if ( geometry.boundingBox !== null ) { + + if ( _ray$2.intersectsBox( geometry.boundingBox ) === false ) return; - if (prefixFragment.length > 0) { - prefixFragment += '\n'; } +<<<<<<< HEAD } 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 @@ -14331,254 +11171,162 @@ const glFragmentShader = WebGLShader(gl, gl.FRAGMENT_SHADER, fragmentGlsl); gl.attachShader(program, glVertexShader); gl.attachShader(program, glFragmentShader); // Force a particular attribute to index 0. +======= - if (parameters.index0AttributeName !== undefined) { - gl.bindAttribLocation(program, 0, parameters.index0AttributeName); - } else if (parameters.morphTargets === true) { - // programs with morphTargets displace position out of attribute 0 - gl.bindAttribLocation(program, 0, 'position'); - } + let intersection; - gl.linkProgram(program); // check for link errors + const index = geometry.index; + const position = geometry.attributes.position; + const uv = geometry.attributes.uv; + const uv2 = geometry.attributes.uv2; + const groups = geometry.groups; + const drawRange = geometry.drawRange; +>>>>>>> mrdoob-dev - 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 ( index !== null ) { - if (gl.getProgramParameter(program, gl.LINK_STATUS) === false) { - runnable = false; - const vertexErrors = getShaderErrors(gl, glVertexShader, 'vertex'); - const fragmentErrors = getShaderErrors(gl, glFragmentShader, 'fragment'); - console.error('THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' + 'VALIDATE_STATUS ' + gl.getProgramParameter(program, gl.VALIDATE_STATUS) + '\n\n' + 'Program Info Log: ' + programLog + '\n' + vertexErrors + '\n' + fragmentErrors); - } else if (programLog !== '') { - console.warn('THREE.WebGLProgram: Program Info Log:', programLog); - } else if (vertexLog === '' || fragmentLog === '') { - haveDiagnostics = false; - } + // indexed buffer geometry - if (haveDiagnostics) { - this.diagnostics = { - runnable: runnable, - programLog: programLog, - vertexShader: { - log: vertexLog, - prefix: prefixVertex - }, - fragmentShader: { - log: fragmentLog, - prefix: prefixFragment - } - }; - } - } // Clean up - // Crashes in iOS9 and iOS10. #18402 - // gl.detachShader( program, glVertexShader ); - // gl.detachShader( program, glFragmentShader ); + if ( Array.isArray( material ) ) { + for ( let i = 0, il = groups.length; i < il; i ++ ) { - gl.deleteShader(glVertexShader); - gl.deleteShader(glFragmentShader); // set up caching for uniform locations + const group = groups[ i ]; + const groupMaterial = material[ group.materialIndex ]; - let cachedUniforms; + const start = Math.max( group.start, drawRange.start ); + const end = Math.min( index.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) ); - this.getUniforms = function () { - if (cachedUniforms === undefined) { - cachedUniforms = new WebGLUniforms(gl, program); - } + for ( let j = start, jl = end; j < jl; j += 3 ) { - return cachedUniforms; - }; // set up caching for attribute locations + const a = index.getX( j ); + const b = index.getX( j + 1 ); + const c = index.getX( j + 2 ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray$2, uv, uv2, a, b, c ); - let cachedAttributes; + if ( intersection ) { - this.getAttributes = function () { - if (cachedAttributes === undefined) { - cachedAttributes = fetchAttributeLocations(gl, program); - } + intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics + intersection.face.materialIndex = group.materialIndex; + intersects.push( intersection ); - return cachedAttributes; - }; // free resource + } + } - this.destroy = function () { - bindingStates.releaseStatesOfProgram(this); - gl.deleteProgram(program); - this.program = undefined; - }; // + } + } else { - this.name = parameters.shaderName; - this.id = programIdCount++; - this.cacheKey = cacheKey; - this.usedTimes = 1; - this.program = program; - this.vertexShader = glVertexShader; - this.fragmentShader = glFragmentShader; - return this; - } + const start = Math.max( 0, drawRange.start ); + const end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); - let _id = 0; + for ( let i = start, il = end; i < il; i += 3 ) { - class WebGLShaderCache { - constructor() { - this.shaderCache = new Map(); - this.materialCache = new Map(); - } + const a = index.getX( i ); + const b = index.getX( i + 1 ); + const c = index.getX( i + 2 ); - update(material) { - const vertexShader = material.vertexShader; - const fragmentShader = material.fragmentShader; + intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray$2, uv, uv2, a, b, c ); - const vertexShaderStage = this._getShaderStage(vertexShader); + if ( intersection ) { - const fragmentShaderStage = this._getShaderStage(fragmentShader); + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics + intersects.push( intersection ); - 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; - } + } else if ( position !== undefined ) { - remove(material) { - const materialShaders = this.materialCache.get(material); + // non-indexed buffer geometry - for (const shaderStage of materialShaders) { - shaderStage.usedTimes--; - if (shaderStage.usedTimes === 0) this.shaderCache.delete(shaderStage.code); - } + if ( Array.isArray( material ) ) { - this.materialCache.delete(material); - return this; - } + for ( let i = 0, il = groups.length; i < il; i ++ ) { - getVertexShaderID(material) { - return this._getShaderStage(material.vertexShader).id; - } + const group = groups[ i ]; + const groupMaterial = material[ group.materialIndex ]; - getFragmentShaderID(material) { - return this._getShaderStage(material.fragmentShader).id; - } + const start = Math.max( group.start, drawRange.start ); + const end = Math.min( position.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) ); - dispose() { - this.shaderCache.clear(); - this.materialCache.clear(); - } + for ( let j = start, jl = end; j < jl; j += 3 ) { - _getShaderCacheForMaterial(material) { - const cache = this.materialCache; + const a = j; + const b = j + 1; + const c = j + 2; - if (cache.has(material) === false) { - cache.set(material, new Set()); - } + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray$2, uv, uv2, a, b, c ); - return cache.get(material); - } + if ( intersection ) { - _getShaderStage(code) { - const cache = this.shaderCache; + intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics + intersection.face.materialIndex = group.materialIndex; + intersects.push( intersection ); - if (cache.has(code) === false) { - const stage = new WebGLShaderStage(code); - cache.set(code, stage); - } + } - return cache.get(code); - } + } - } + } - class WebGLShaderStage { - constructor(code) { - this.id = _id++; - this.code = code; - this.usedTimes = 0; - } + } else { - } + const start = Math.max( 0, drawRange.start ); + const end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); - function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping) { - const _programLayers = new Layers(); + for ( let i = start, il = end; i < il; i += 3 ) { - const _customShaders = new WebGLShaderCache(); + const a = i; + const b = i + 1; + const c = i + 2; - const programs = []; - const isWebGL2 = capabilities.isWebGL2; - const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; - const vertexTextures = capabilities.vertexTextures; - let precision = capabilities.precision; - const shaderIDs = { - MeshDepthMaterial: 'depth', - MeshDistanceMaterial: 'distanceRGBA', - MeshNormalMaterial: 'normal', - MeshBasicMaterial: 'basic', - MeshLambertMaterial: 'lambert', - MeshPhongMaterial: 'phong', - MeshToonMaterial: 'toon', - MeshStandardMaterial: 'physical', - MeshPhysicalMaterial: 'physical', - MeshMatcapMaterial: 'matcap', - LineBasicMaterial: 'basic', - LineDashedMaterial: 'dashed', - PointsMaterial: 'points', - ShadowMaterial: 'shadow', - SpriteMaterial: 'sprite' - }; + intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray$2, uv, uv2, a, b, c ); - 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 - // (not to blow over maxLights budget) + if ( intersection ) { + + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics + intersects.push( intersection ); + + } - 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; // + } - let vertexShader, fragmentShader; - let customVertexShaderID, customFragmentShaderID; + } - if (shaderID) { - const shader = ShaderLib[shaderID]; - vertexShader = shader.vertexShader; - fragmentShader = shader.fragmentShader; - } else { - vertexShader = material.vertexShader; - fragmentShader = material.fragmentShader; + function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) { + + let intersect; - _customShaders.update(material); + if ( material.side === BackSide ) { - customVertexShaderID = _customShaders.getVertexShaderID(material); - customFragmentShaderID = _customShaders.getFragmentShaderID(material); - } + intersect = ray.intersectTriangle( pC, pB, pA, true, point ); + + } else { + + intersect = ray.intersectTriangle( pA, pB, pC, ( material.side === FrontSide ), point ); + + } + + if ( intersect === null ) return null; + _intersectionPointWorld.copy( point ); + _intersectionPointWorld.applyMatrix4( object.matrixWorld ); + + const distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld ); + +<<<<<<< HEAD const currentRenderTarget = renderer.getRenderTarget(); const useAlphaTest = material.alphaTest > 0; const useClearcoat = material.clearcoat > 0; @@ -14686,30 +11434,25 @@ }; return parameters; } +======= + if ( distance < raycaster.near || distance > raycaster.far ) return null; +>>>>>>> mrdoob-dev - function getProgramCacheKey(parameters) { - const array = []; + return { + distance: distance, + point: _intersectionPointWorld.clone(), + object: object + }; - 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]); - } - } + function checkBufferGeometryIntersection( object, material, raycaster, ray, uv, uv2, a, b, c ) { - if (parameters.isRawShaderMaterial === false) { - getProgramCacheKeyParameters(array, parameters); - getProgramCacheKeyBooleans(array, parameters); - array.push(renderer.outputEncoding); - } + object.getVertexPosition( a, _vA$1 ); + object.getVertexPosition( b, _vB$1 ); + object.getVertexPosition( c, _vC$1 ); +<<<<<<< HEAD array.push(parameters.customProgramCacheKey); if (renderer.extraProgramCacheKey) { @@ -14718,5607 +11461,2937 @@ return array.join(); } +======= + const intersection = checkIntersection( object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint ); +>>>>>>> mrdoob-dev - function getProgramCacheKeyParameters(array, parameters) { - array.push(parameters.precision); - array.push(parameters.outputEncoding); - array.push(parameters.envMapMode); - array.push(parameters.envMapCubeUVHeight); - array.push(parameters.combine); - array.push(parameters.vertexUvs); - array.push(parameters.fogExp2); - array.push(parameters.sizeAttenuation); - array.push(parameters.morphTargetsCount); - array.push(parameters.morphAttributeCount); - array.push(parameters.numDirLights); - array.push(parameters.numPointLights); - array.push(parameters.numSpotLights); - array.push(parameters.numHemiLights); - array.push(parameters.numRectAreaLights); - array.push(parameters.numDirLightShadows); - array.push(parameters.numPointLightShadows); - array.push(parameters.numSpotLightShadows); - 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 ( intersection ) { - if (parameters.isWebGL2) _programLayers.enable(0); - if (parameters.supportsVertexTextures) _programLayers.enable(1); - if (parameters.instancing) _programLayers.enable(2); - if (parameters.instancingColor) _programLayers.enable(3); - if (parameters.map) _programLayers.enable(4); - if (parameters.matcap) _programLayers.enable(5); - if (parameters.envMap) _programLayers.enable(6); - if (parameters.lightMap) _programLayers.enable(7); - if (parameters.aoMap) _programLayers.enable(8); - if (parameters.emissiveMap) _programLayers.enable(9); - if (parameters.bumpMap) _programLayers.enable(10); - if (parameters.normalMap) _programLayers.enable(11); - if (parameters.objectSpaceNormalMap) _programLayers.enable(12); - if (parameters.tangentSpaceNormalMap) _programLayers.enable(13); - if (parameters.clearcoat) _programLayers.enable(14); - if (parameters.clearcoatMap) _programLayers.enable(15); - if (parameters.clearcoatRoughnessMap) _programLayers.enable(16); - if (parameters.clearcoatNormalMap) _programLayers.enable(17); - if (parameters.iridescence) _programLayers.enable(18); - if (parameters.iridescenceMap) _programLayers.enable(19); - if (parameters.iridescenceThicknessMap) _programLayers.enable(20); - if (parameters.displacementMap) _programLayers.enable(21); - if (parameters.specularMap) _programLayers.enable(22); - if (parameters.roughnessMap) _programLayers.enable(23); - if (parameters.metalnessMap) _programLayers.enable(24); - if (parameters.gradientMap) _programLayers.enable(25); - if (parameters.alphaMap) _programLayers.enable(26); - if (parameters.alphaTest) _programLayers.enable(27); - if (parameters.vertexColors) _programLayers.enable(28); - if (parameters.vertexAlphas) _programLayers.enable(29); - 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); + if ( uv ) { - _programLayers.disableAll(); + _uvA$1.fromBufferAttribute( uv, a ); + _uvB$1.fromBufferAttribute( uv, b ); + _uvC$1.fromBufferAttribute( uv, c ); - 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); - array.push(_programLayers.mask); - } - - function getUniforms(material) { - const shaderID = shaderIDs[material.type]; - let uniforms; + intersection.uv = Triangle.getUV( _intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() ); - 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 + if ( uv2 ) { - for (let p = 0, pl = programs.length; p < pl; p++) { - const preexistingProgram = programs[p]; + _uvA$1.fromBufferAttribute( uv2, a ); + _uvB$1.fromBufferAttribute( uv2, b ); + _uvC$1.fromBufferAttribute( uv2, c ); - if (preexistingProgram.cacheKey === cacheKey) { - program = preexistingProgram; - ++program.usedTimes; - break; - } - } + intersection.uv2 = Triangle.getUV( _intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() ); - if (program === undefined) { - program = new WebGLProgram(renderer, cacheKey, parameters, bindingStates); - programs.push(program); } - return program; - } + const face = { + a: a, + b: b, + c: c, + normal: new Vector3(), + materialIndex: 0 + }; - 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 + Triangle.getNormal( _vA$1, _vB$1, _vC$1, face.normal ); - program.destroy(); - } - } + intersection.face = face; - function releaseShaderCache(material) { - _customShaders.remove(material); } - function dispose() { - _customShaders.dispose(); - } + return intersection; - return { - getParameters: getParameters, - getProgramCacheKey: getProgramCacheKey, - getUniforms: getUniforms, - acquireProgram: acquireProgram, - releaseProgram: releaseProgram, - releaseShaderCache: releaseShaderCache, - // Exposed for resource monitoring & error feedback via renderer.info: - programs: programs, - dispose: dispose - }; } - function WebGLProperties() { - let properties = new WeakMap(); + class BoxGeometry extends BufferGeometry { - function get(object) { - let map = properties.get(object); + constructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) { - if (map === undefined) { - map = {}; - properties.set(object, map); - } + super(); - return map; - } + this.type = 'BoxGeometry'; - function remove(object) { - properties.delete(object); - } + this.parameters = { + width: width, + height: height, + depth: depth, + widthSegments: widthSegments, + heightSegments: heightSegments, + depthSegments: depthSegments + }; - function update(object, key, value) { - properties.get(object)[key] = value; - } + const scope = this; - function dispose() { - properties = new WeakMap(); - } + // segments - return { - get: get, - remove: remove, - update: update, - dispose: dispose - }; - } + widthSegments = Math.floor( widthSegments ); + heightSegments = Math.floor( heightSegments ); + depthSegments = Math.floor( depthSegments ); - function painterSortStable(a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else if (a.material.id !== b.material.id) { - return a.material.id - b.material.id; - } else if (a.z !== b.z) { - return a.z - b.z; - } else { - return a.id - b.id; - } - } + // buffers - function reversePainterSortStable(a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else if (a.z !== b.z) { - return b.z - a.z; - } else { - return a.id - b.id; - } - } + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; - function WebGLRenderList() { - const renderItems = []; - let renderItemsIndex = 0; - const opaque = []; - const transmissive = []; - const transparent = []; + // helper variables - function init() { - renderItemsIndex = 0; - opaque.length = 0; - transmissive.length = 0; - transparent.length = 0; - } + let numberOfVertices = 0; + let groupStart = 0; - function getNextRenderItem(object, geometry, material, groupOrder, z, group) { - let renderItem = renderItems[renderItemsIndex]; + // build each side of the box geometry - if (renderItem === undefined) { - renderItem = { - id: object.id, - object: object, - geometry: geometry, - material: material, - groupOrder: groupOrder, - renderOrder: object.renderOrder, - z: z, - group: group - }; - renderItems[renderItemsIndex] = renderItem; - } else { - renderItem.id = object.id; - renderItem.object = object; - renderItem.geometry = geometry; - renderItem.material = material; - renderItem.groupOrder = groupOrder; - renderItem.renderOrder = object.renderOrder; - renderItem.z = z; - renderItem.group = group; - } + 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 - renderItemsIndex++; - return renderItem; - } + // build geometry - function push(object, geometry, material, groupOrder, z, group) { - const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); + this.setIndex( indices ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - if (material.transmission > 0.0) { - transmissive.push(renderItem); - } else if (material.transparent === true) { - transparent.push(renderItem); - } else { - opaque.push(renderItem); - } - } + function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { - function unshift(object, geometry, material, groupOrder, z, group) { - const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); + const segmentWidth = width / gridX; + const segmentHeight = height / gridY; - if (material.transmission > 0.0) { - transmissive.unshift(renderItem); - } else if (material.transparent === true) { - transparent.unshift(renderItem); - } else { - opaque.unshift(renderItem); - } - } + const widthHalf = width / 2; + const heightHalf = height / 2; + const depthHalf = depth / 2; - 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); - } + const gridX1 = gridX + 1; + const gridY1 = gridY + 1; - 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; - renderItem.id = null; - renderItem.object = null; - renderItem.geometry = null; - renderItem.material = null; - renderItem.group = null; - } - } + let vertexCounter = 0; + let groupCount = 0; - return { - opaque: opaque, - transmissive: transmissive, - transparent: transparent, - init: init, - push: push, - unshift: unshift, - finish: finish, - sort: sort - }; - } + const vector = new Vector3(); - function WebGLRenderLists() { - let lists = new WeakMap(); + // generate vertices, normals and uvs - function get(scene, renderCallDepth) { - let list; + for ( let iy = 0; iy < gridY1; iy ++ ) { - if (lists.has(scene) === false) { - list = new WebGLRenderList(); - lists.set(scene, [list]); - } else { - if (renderCallDepth >= lists.get(scene).length) { - list = new WebGLRenderList(); - lists.get(scene).push(list); - } else { - list = lists.get(scene)[renderCallDepth]; - } - } + const y = iy * segmentHeight - heightHalf; - return list; - } + for ( let ix = 0; ix < gridX1; ix ++ ) { - function dispose() { - lists = new WeakMap(); - } + const x = ix * segmentWidth - widthHalf; - return { - get: get, - dispose: dispose - }; - } + // set values to correct vector component - function UniformsCache() { - const lights = {}; - return { - get: function (light) { - if (lights[light.id] !== undefined) { - return lights[light.id]; - } + vector[ u ] = x * udir; + vector[ v ] = y * vdir; + vector[ w ] = depthHalf; - let uniforms; + // now apply vector to vertex buffer - switch (light.type) { - case 'DirectionalLight': - uniforms = { - direction: new Vector3(), - color: new Color() - }; - break; + vertices.push( vector.x, vector.y, vector.z ); - case 'SpotLight': - uniforms = { - position: new Vector3(), - direction: new Vector3(), - color: new Color(), - distance: 0, - coneCos: 0, - penumbraCos: 0, - decay: 0 - }; - break; + // set values to correct vector component - case 'PointLight': - uniforms = { - position: new Vector3(), - color: new Color(), - distance: 0, - decay: 0 - }; - break; + vector[ u ] = 0; + vector[ v ] = 0; + vector[ w ] = depth > 0 ? 1 : - 1; - case 'HemisphereLight': - uniforms = { - direction: new Vector3(), - skyColor: new Color(), - groundColor: new Color() - }; - break; + // now apply vector to normal buffer - case 'RectAreaLight': - uniforms = { - color: new Color(), - position: new Vector3(), - halfWidth: new Vector3(), - halfHeight: new Vector3() - }; - break; - } + normals.push( vector.x, vector.y, vector.z ); - lights[light.id] = uniforms; - return uniforms; - } - }; - } + // uvs - function ShadowUniformsCache() { - const lights = {}; - return { - get: function (light) { - if (lights[light.id] !== undefined) { - return lights[light.id]; - } + uvs.push( ix / gridX ); + uvs.push( 1 - ( iy / gridY ) ); - let uniforms; + // counters - switch (light.type) { - case 'DirectionalLight': - uniforms = { - shadowBias: 0, - shadowNormalBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2() - }; - break; + vertexCounter += 1; - case 'SpotLight': - uniforms = { - shadowBias: 0, - shadowNormalBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2() - }; - break; + } - case 'PointLight': - uniforms = { - shadowBias: 0, - shadowNormalBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2(), - shadowCameraNear: 1, - shadowCameraFar: 1000 - }; - break; - // TODO (abelnation): set RectAreaLight shadow uniforms } - lights[light.id] = uniforms; - return uniforms; - } - }; - } - - let nextVersion = 0; - - function shadowCastingLightsFirst(lightA, lightB) { - return (lightB.castShadow ? 1 : 0) - (lightA.castShadow ? 1 : 0); - } + // indices - function WebGLLights(extensions, capabilities) { - const cache = new UniformsCache(); - const shadowCache = ShadowUniformsCache(); - const state = { - version: 0, - hash: { - directionalLength: -1, - pointLength: -1, - spotLength: -1, - rectAreaLength: -1, - hemiLength: -1, - numDirectionalShadows: -1, - numPointShadows: -1, - numSpotShadows: -1 - }, - ambient: [0, 0, 0], - probe: [], - directional: [], - directionalShadow: [], - directionalShadowMap: [], - directionalShadowMatrix: [], - spot: [], - spotShadow: [], - spotShadowMap: [], - spotShadowMatrix: [], - rectArea: [], - rectAreaLTC1: null, - rectAreaLTC2: null, - point: [], - pointShadow: [], - pointShadowMap: [], - pointShadowMatrix: [], - hemi: [] - }; + // 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 i = 0; i < 9; i++) state.probe.push(new Vector3()); + for ( let iy = 0; iy < gridY; iy ++ ) { - const vector3 = new Vector3(); - const matrix4 = new Matrix4(); - const matrix42 = new Matrix4(); + for ( let ix = 0; ix < gridX; ix ++ ) { - function setup(lights, physicallyCorrectLights) { - let r = 0, - g = 0, - b = 0; + 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; - for (let i = 0; i < 9; i++) state.probe[i].set(0, 0, 0); + // faces - let directionalLength = 0; - let pointLength = 0; - let spotLength = 0; - let rectAreaLength = 0; - let hemiLength = 0; - let numDirectionalShadows = 0; - let numPointShadows = 0; - let numSpotShadows = 0; - lights.sort(shadowCastingLightsFirst); // artist-friendly light intensity scaling factor + indices.push( a, b, d ); + indices.push( b, c, d ); - const scaleFactor = physicallyCorrectLights !== true ? Math.PI : 1; + // increase counter - 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; + groupCount += 6; - if (light.isAmbientLight) { - r += color.r * intensity * scaleFactor; - g += color.g * intensity * scaleFactor; - b += color.b * intensity * scaleFactor; - } else if (light.isLightProbe) { - for (let j = 0; j < 9; j++) { - state.probe[j].addScaledVector(light.sh.coefficients[j], intensity); } - } 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); - shadowUniforms.shadowBias = shadow.bias; - shadowUniforms.shadowNormalBias = shadow.normalBias; - shadowUniforms.shadowRadius = shadow.radius; - shadowUniforms.shadowMapSize = shadow.mapSize; - state.directionalShadow[directionalLength] = shadowUniforms; - state.directionalShadowMap[directionalLength] = shadowMap; - state.directionalShadowMatrix[directionalLength] = light.shadow.matrix; - numDirectionalShadows++; - } - - state.directional[directionalLength] = uniforms; - directionalLength++; - } else if (light.isSpotLight) { - const uniforms = cache.get(light); - uniforms.position.setFromMatrixPosition(light.matrixWorld); - uniforms.color.copy(color).multiplyScalar(intensity * scaleFactor); - uniforms.distance = distance; - uniforms.coneCos = Math.cos(light.angle); - uniforms.penumbraCos = Math.cos(light.angle * (1 - light.penumbra)); - uniforms.decay = light.decay; + } - if (light.castShadow) { - const shadow = light.shadow; - const shadowUniforms = shadowCache.get(light); - shadowUniforms.shadowBias = shadow.bias; - shadowUniforms.shadowNormalBias = shadow.normalBias; - shadowUniforms.shadowRadius = shadow.radius; - shadowUniforms.shadowMapSize = shadow.mapSize; - state.spotShadow[spotLength] = shadowUniforms; - state.spotShadowMap[spotLength] = shadowMap; - state.spotShadowMatrix[spotLength] = light.shadow.matrix; - numSpotShadows++; - } - - 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); - uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0); - state.rectArea[rectAreaLength] = uniforms; - rectAreaLength++; - } else if (light.isPointLight) { - const uniforms = cache.get(light); - uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor); - uniforms.distance = light.distance; - uniforms.decay = light.decay; + // add a group to the geometry. this will ensure multi material support - if (light.castShadow) { - const shadow = light.shadow; - const shadowUniforms = shadowCache.get(light); - shadowUniforms.shadowBias = shadow.bias; - shadowUniforms.shadowNormalBias = shadow.normalBias; - shadowUniforms.shadowRadius = shadow.radius; - shadowUniforms.shadowMapSize = shadow.mapSize; - shadowUniforms.shadowCameraNear = shadow.camera.near; - shadowUniforms.shadowCameraFar = shadow.camera.far; - state.pointShadow[pointLength] = shadowUniforms; - state.pointShadowMap[pointLength] = shadowMap; - state.pointShadowMatrix[pointLength] = light.shadow.matrix; - numPointShadows++; - } + scope.addGroup( groupStart, groupCount, materialIndex ); - state.point[pointLength] = uniforms; - pointLength++; - } else if (light.isHemisphereLight) { - const uniforms = cache.get(light); - uniforms.skyColor.copy(light.color).multiplyScalar(intensity * scaleFactor); - uniforms.groundColor.copy(light.groundColor).multiplyScalar(intensity * scaleFactor); - state.hemi[hemiLength] = uniforms; - hemiLength++; - } - } + // calculate new start value for groups - if (rectAreaLength > 0) { - if (capabilities.isWebGL2) { - // WebGL 2 - state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; - state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; - } else { - // WebGL 1 - if (extensions.has('OES_texture_float_linear') === true) { - state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; - state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; - } else if (extensions.has('OES_texture_half_float_linear') === true) { - state.rectAreaLTC1 = UniformsLib.LTC_HALF_1; - state.rectAreaLTC2 = UniformsLib.LTC_HALF_2; - } else { - console.error('THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.'); - } - } - } + groupStart += groupCount; - state.ambient[0] = r; - state.ambient[1] = g; - state.ambient[2] = b; - const hash = state.hash; + // update total number of vertices + + numberOfVertices += vertexCounter; - if (hash.directionalLength !== directionalLength || hash.pointLength !== pointLength || hash.spotLength !== spotLength || hash.rectAreaLength !== rectAreaLength || hash.hemiLength !== hemiLength || hash.numDirectionalShadows !== numDirectionalShadows || hash.numPointShadows !== numPointShadows || hash.numSpotShadows !== numSpotShadows) { - state.directional.length = directionalLength; - state.spot.length = spotLength; - state.rectArea.length = rectAreaLength; - state.point.length = pointLength; - state.hemi.length = hemiLength; - state.directionalShadow.length = numDirectionalShadows; - state.directionalShadowMap.length = numDirectionalShadows; - state.pointShadow.length = numPointShadows; - state.pointShadowMap.length = numPointShadows; - state.spotShadow.length = numSpotShadows; - state.spotShadowMap.length = numSpotShadows; - state.directionalShadowMatrix.length = numDirectionalShadows; - state.pointShadowMatrix.length = numPointShadows; - state.spotShadowMatrix.length = numSpotShadows; - hash.directionalLength = directionalLength; - hash.pointLength = pointLength; - hash.spotLength = spotLength; - hash.rectAreaLength = rectAreaLength; - hash.hemiLength = hemiLength; - hash.numDirectionalShadows = numDirectionalShadows; - hash.numPointShadows = numPointShadows; - hash.numSpotShadows = numSpotShadows; - state.version = nextVersion++; } + } - function setupView(lights, camera) { - let directionalLength = 0; - let pointLength = 0; - let spotLength = 0; - let rectAreaLength = 0; - let hemiLength = 0; - const viewMatrix = camera.matrixWorldInverse; + static fromJSON( data ) { - 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); - vector3.setFromMatrixPosition(light.target.matrixWorld); - uniforms.direction.sub(vector3); - uniforms.direction.transformDirection(viewMatrix); - directionalLength++; - } else if (light.isSpotLight) { - const uniforms = state.spot[spotLength]; - uniforms.position.setFromMatrixPosition(light.matrixWorld); - uniforms.position.applyMatrix4(viewMatrix); - uniforms.direction.setFromMatrixPosition(light.matrixWorld); - vector3.setFromMatrixPosition(light.target.matrixWorld); - uniforms.direction.sub(vector3); - uniforms.direction.transformDirection(viewMatrix); - spotLength++; - } 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 + return new BoxGeometry( data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments ); - matrix42.identity(); - matrix4.copy(light.matrixWorld); - matrix4.premultiply(viewMatrix); - matrix42.extractRotation(matrix4); - uniforms.halfWidth.set(light.width * 0.5, 0.0, 0.0); - uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0); - uniforms.halfWidth.applyMatrix4(matrix42); - uniforms.halfHeight.applyMatrix4(matrix42); - rectAreaLength++; - } else if (light.isPointLight) { - const uniforms = state.point[pointLength]; - uniforms.position.setFromMatrixPosition(light.matrixWorld); - uniforms.position.applyMatrix4(viewMatrix); - pointLength++; - } else if (light.isHemisphereLight) { - const uniforms = state.hemi[hemiLength]; - uniforms.direction.setFromMatrixPosition(light.matrixWorld); - uniforms.direction.transformDirection(viewMatrix); - hemiLength++; - } - } } - return { - setup: setup, - setupView: setupView, - state: state - }; } - function WebGLRenderState(extensions, capabilities) { - const lights = new WebGLLights(extensions, capabilities); - const lightsArray = []; - const shadowsArray = []; + /** + * Uniform Utilities + */ - function init() { - lightsArray.length = 0; - shadowsArray.length = 0; - } + function cloneUniforms( src ) { - function pushLight(light) { - lightsArray.push(light); - } + const dst = {}; - function pushShadow(shadowLight) { - shadowsArray.push(shadowLight); - } + for ( const u in src ) { - function setupLights(physicallyCorrectLights) { - lights.setup(lightsArray, physicallyCorrectLights); - } + dst[ u ] = {}; - function setupLightsView(camera) { - lights.setupView(lightsArray, camera); - } + for ( const p in src[ u ] ) { - const state = { - lightsArray: lightsArray, - shadowsArray: shadowsArray, - lights: lights - }; - return { - init: init, - state: state, - setupLights: setupLights, - setupLightsView: setupLightsView, - pushLight: pushLight, - pushShadow: pushShadow - }; - } + const property = src[ u ][ p ]; - function WebGLRenderStates(extensions, capabilities) { - let renderStates = new WeakMap(); + if ( property && ( property.isColor || + property.isMatrix3 || property.isMatrix4 || + property.isVector2 || property.isVector3 || property.isVector4 || + property.isTexture || property.isQuaternion ) ) { - function get(scene, renderCallDepth = 0) { - let renderState; + dst[ u ][ p ] = property.clone(); + + } else if ( Array.isArray( property ) ) { + + dst[ u ][ p ] = property.slice(); - if (renderStates.has(scene) === false) { - renderState = new WebGLRenderState(extensions, capabilities); - renderStates.set(scene, [renderState]); - } else { - if (renderCallDepth >= renderStates.get(scene).length) { - renderState = new WebGLRenderState(extensions, capabilities); - renderStates.get(scene).push(renderState); } else { - renderState = renderStates.get(scene)[renderCallDepth]; + + dst[ u ][ p ] = property; + } + } - return renderState; } - function dispose() { - renderStates = new WeakMap(); - } + return dst; - return { - get: get, - dispose: dispose - }; } - class MeshDepthMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshDepthMaterial = true; - this.type = 'MeshDepthMaterial'; - this.depthPacking = BasicDepthPacking; - this.map = null; - this.alphaMap = null; - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.setValues(parameters); - } + function mergeUniforms( uniforms ) { - copy(source) { - super.copy(source); - this.depthPacking = source.depthPacking; - this.map = source.map; - this.alphaMap = source.alphaMap; - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - return this; - } + const merged = {}; - } + for ( let u = 0; u < uniforms.length; u ++ ) { - class MeshDistanceMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshDistanceMaterial = true; - this.type = 'MeshDistanceMaterial'; - this.referencePosition = new Vector3(); - this.nearDistance = 1; - this.farDistance = 1000; - this.map = null; - this.alphaMap = null; - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.setValues(parameters); - } + const tmp = cloneUniforms( uniforms[ u ] ); + + for ( const p in tmp ) { + + merged[ p ] = tmp[ p ]; + + } - copy(source) { - super.copy(source); - this.referencePosition.copy(source.referencePosition); - this.nearDistance = source.nearDistance; - this.farDistance = source.farDistance; - this.map = source.map; - this.alphaMap = source.alphaMap; - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - return this; } + return merged; + } - const vertex = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; - const fragment = "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}"; + function cloneUniformsGroups( src ) { - function WebGLShadowMap(_renderer, _objects, _capabilities) { - let _frustum = new Frustum(); + const dst = []; - const _shadowMapSize = new Vector2(), - _viewportSize = new Vector2(), - _viewport = new Vector4(), - _depthMaterial = new MeshDepthMaterial({ - depthPacking: RGBADepthPacking - }), - _distanceMaterial = new MeshDistanceMaterial(), - _materialCache = {}, - _maxTextureSize = _capabilities.maxTextureSize; - - const shadowSide = { - 0: BackSide, - 1: FrontSide, - 2: DoubleSide - }; - const shadowMaterialVertical = new ShaderMaterial({ - defines: { - VSM_SAMPLES: 8 - }, - uniforms: { - shadow_pass: { - value: null - }, - resolution: { - value: new Vector2() - }, - radius: { - value: 4.0 - } - }, - vertexShader: vertex, - fragmentShader: fragment - }); - const shadowMaterialHorizontal = shadowMaterialVertical.clone(); - shadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1; - const fullScreenTri = new BufferGeometry(); - fullScreenTri.setAttribute('position', new BufferAttribute(new Float32Array([-1, -1, 0.5, 3, -1, 0.5, -1, 3, 0.5]), 3)); - const fullScreenMesh = new Mesh(fullScreenTri, shadowMaterialVertical); - const scope = this; - this.enabled = false; - this.autoUpdate = true; - this.needsUpdate = false; - this.type = PCFShadowMap; + for ( let u = 0; u < src.length; u ++ ) { - this.render = function (lights, scene, camera) { - if (scope.enabled === false) return; - if (scope.autoUpdate === false && scope.needsUpdate === false) return; - if (lights.length === 0) return; + dst.push( src[ u ].clone() ); - const currentRenderTarget = _renderer.getRenderTarget(); + } - const activeCubeFace = _renderer.getActiveCubeFace(); + return dst; - const activeMipmapLevel = _renderer.getActiveMipmapLevel(); + } - const _state = _renderer.state; // Set GL state for depth map. + function getUnlitUniformColorSpace( renderer ) { - _state.setBlending(NoBlending); + if ( renderer.getRenderTarget() === null ) { - _state.buffers.color.setClear(1, 1, 1, 1); + // https://github.com/mrdoob/three.js/pull/23937#issuecomment-1111067398 + return renderer.outputEncoding === sRGBEncoding ? SRGBColorSpace : LinearSRGBColorSpace; - _state.buffers.depth.setTest(true); + } - _state.setScissorTest(false); // render depth map + return LinearSRGBColorSpace; + } - for (let i = 0, il = lights.length; i < il; i++) { - const light = lights[i]; - const shadow = light.shadow; + // Legacy - if (shadow === undefined) { - console.warn('THREE.WebGLShadowMap:', light, 'has no shadow.'); - continue; - } + const UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; - if (shadow.autoUpdate === false && shadow.needsUpdate === false) continue; + var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; - _shadowMapSize.copy(shadow.mapSize); + var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; - const shadowFrameExtents = shadow.getFrameExtents(); + class ShaderMaterial extends Material { - _shadowMapSize.multiply(shadowFrameExtents); + constructor( parameters ) { - _viewportSize.copy(shadow.mapSize); + super(); - 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; - } + this.isShaderMaterial = true; - if (_shadowMapSize.y > _maxTextureSize) { - _viewportSize.y = Math.floor(_maxTextureSize / shadowFrameExtents.y); - _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; - shadow.mapSize.y = _viewportSize.y; - } - } + this.type = 'ShaderMaterial'; - if (shadow.map === null && !shadow.isPointLightShadow && this.type === VSMShadowMap) { - shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y); - shadow.map.texture.name = light.name + '.shadowMap'; - shadow.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y); - shadow.camera.updateProjectionMatrix(); - } + this.defines = {}; + this.uniforms = {}; + this.uniformsGroups = []; - if (shadow.map === null) { - const pars = { - minFilter: NearestFilter, - magFilter: NearestFilter, - format: RGBAFormat - }; - shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars); - shadow.map.texture.name = light.name + '.shadowMap'; - shadow.camera.updateProjectionMatrix(); - } + this.vertexShader = default_vertex; + this.fragmentShader = default_fragment; - _renderer.setRenderTarget(shadow.map); + this.linewidth = 1; - _renderer.clear(); + this.wireframe = false; + this.wireframeLinewidth = 1; - const viewportCount = shadow.getViewportCount(); + 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 - for (let vp = 0; vp < viewportCount; vp++) { - const viewport = shadow.getViewport(vp); + this.extensions = { + derivatives: false, // set to use derivatives + fragDepth: false, // set to use fragment depth values + drawBuffers: false, // set to use draw buffers + shaderTextureLOD: false // set to use shader texture LOD + }; - _viewport.set(_viewportSize.x * viewport.x, _viewportSize.y * viewport.y, _viewportSize.x * viewport.z, _viewportSize.y * viewport.w); + // When rendered geometry doesn't include these attributes but the material does, + // use these default values in WebGL. This avoids errors when buffer data is missing. + this.defaultAttributeValues = { + 'color': [ 1, 1, 1 ], + 'uv': [ 0, 0 ], + 'uv2': [ 0, 0 ] + }; - _state.viewport(_viewport); + this.index0AttributeName = undefined; + this.uniformsNeedUpdate = false; - shadow.updateMatrices(light, vp); - _frustum = shadow.getFrustum(); - renderObject(scene, camera, shadow.camera, light, this.type); - } // do blur pass for VSM + this.glslVersion = null; + if ( parameters !== undefined ) { - if (!shadow.isPointLightShadow && this.type === VSMShadowMap) { - VSMPass(shadow, camera); - } + this.setValues( parameters ); - shadow.needsUpdate = false; } - scope.needsUpdate = false; + } - _renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel); - }; + copy( source ) { - function VSMPass(shadow, camera) { - const geometry = _objects.update(fullScreenMesh); + super.copy( source ); - 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; - } // vertical pass + this.fragmentShader = source.fragmentShader; + this.vertexShader = source.vertexShader; + this.uniforms = cloneUniforms( source.uniforms ); + this.uniformsGroups = cloneUniformsGroups( source.uniformsGroups ); - shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; - shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; - shadowMaterialVertical.uniforms.radius.value = shadow.radius; + this.defines = Object.assign( {}, source.defines ); - _renderer.setRenderTarget(shadow.mapPass); + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; - _renderer.clear(); + this.fog = source.fog; + this.lights = source.lights; + this.clipping = source.clipping; - _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); // horizontal pass + this.extensions = Object.assign( {}, source.extensions ); + this.glslVersion = source.glslVersion; - shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture; - shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize; - shadowMaterialHorizontal.uniforms.radius.value = shadow.radius; + return this; - _renderer.setRenderTarget(shadow.map); + } - _renderer.clear(); + toJSON( meta ) { - _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null); - } + const data = super.toJSON( meta ); - function getDepthMaterial(object, material, light, shadowCameraNear, shadowCameraFar, type) { - let result = null; - const customMaterial = light.isPointLight === true ? object.customDistanceMaterial : object.customDepthMaterial; + data.glslVersion = this.glslVersion; + data.uniforms = {}; - if (customMaterial !== undefined) { - result = customMaterial; - } else { - result = light.isPointLight === true ? _distanceMaterial : _depthMaterial; - } + for ( const name in this.uniforms ) { - if (_renderer.localClippingEnabled && material.clipShadows === true && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0) { - // in this case we need a unique material instance reflecting the - // appropriate state - const keyA = result.uuid, - keyB = material.uuid; - let materialsForVariant = _materialCache[keyA]; + const uniform = this.uniforms[ name ]; + const value = uniform.value; - if (materialsForVariant === undefined) { - materialsForVariant = {}; - _materialCache[keyA] = materialsForVariant; - } + if ( value && value.isTexture ) { - let cachedMaterial = materialsForVariant[keyB]; + data.uniforms[ name ] = { + type: 't', + value: value.toJSON( meta ).uuid + }; - if (cachedMaterial === undefined) { - cachedMaterial = result.clone(); - materialsForVariant[keyB] = cachedMaterial; - } + } else if ( value && value.isColor ) { - result = cachedMaterial; - } + data.uniforms[ name ] = { + type: 'c', + value: value.getHex() + }; - result.visible = material.visible; - result.wireframe = material.wireframe; + } else if ( value && value.isVector2 ) { - if (type === VSMShadowMap) { - result.side = material.shadowSide !== null ? material.shadowSide : material.side; - } else { - result.side = material.shadowSide !== null ? material.shadowSide : shadowSide[material.side]; - } + data.uniforms[ name ] = { + type: 'v2', + value: value.toArray() + }; - result.alphaMap = material.alphaMap; - result.alphaTest = material.alphaTest; - result.clipShadows = material.clipShadows; - result.clippingPlanes = material.clippingPlanes; - result.clipIntersection = material.clipIntersection; - result.displacementMap = material.displacementMap; - result.displacementScale = material.displacementScale; - result.displacementBias = material.displacementBias; - result.wireframeLinewidth = material.wireframeLinewidth; - result.linewidth = material.linewidth; + } else if ( value && value.isVector3 ) { - if (light.isPointLight === true && result.isMeshDistanceMaterial === true) { - result.referencePosition.setFromMatrixPosition(light.matrixWorld); - result.nearDistance = shadowCameraNear; - result.farDistance = shadowCameraFar; - } + data.uniforms[ name ] = { + type: 'v3', + value: value.toArray() + }; - return result; - } + } else if ( value && value.isVector4 ) { - function renderObject(object, camera, shadowCamera, light, type) { - if (object.visible === false) return; - const visible = object.layers.test(camera.layers); + data.uniforms[ name ] = { + type: 'v4', + value: value.toArray() + }; - 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); + } else if ( value && value.isMatrix3 ) { - const geometry = _objects.update(object); + data.uniforms[ name ] = { + type: 'm3', + value: value.toArray() + }; - const material = object.material; + } else if ( value && value.isMatrix4 ) { - if (Array.isArray(material)) { - const groups = geometry.groups; + data.uniforms[ name ] = { + type: 'm4', + value: value.toArray() + }; - for (let k = 0, kl = groups.length; k < kl; k++) { - const group = groups[k]; - const groupMaterial = material[group.materialIndex]; + } else { - if (groupMaterial && groupMaterial.visible) { - const depthMaterial = getDepthMaterial(object, groupMaterial, light, shadowCamera.near, shadowCamera.far, type); + data.uniforms[ name ] = { + value: value + }; - _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group); - } - } - } else if (material.visible) { - const depthMaterial = getDepthMaterial(object, material, light, shadowCamera.near, shadowCamera.far, type); + // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far - _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); } - } - } - function WebGLState(gl, extensions, capabilities) { - const isWebGL2 = capabilities.isWebGL2; + if ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines; - function ColorBuffer() { - let locked = false; - const color = new Vector4(); - let currentColorMask = null; - const currentColorClear = new Vector4(0, 0, 0, 0); - return { - setMask: function (colorMask) { - if (currentColorMask !== colorMask && !locked) { - gl.colorMask(colorMask, colorMask, colorMask, colorMask); - currentColorMask = colorMask; - } - }, - setLocked: function (lock) { - locked = lock; - }, - setClear: function (r, g, b, a, premultipliedAlpha) { - if (premultipliedAlpha === true) { - r *= a; - g *= a; - b *= a; - } + data.vertexShader = this.vertexShader; + data.fragmentShader = this.fragmentShader; - color.set(r, g, b, a); + const extensions = {}; - if (currentColorClear.equals(color) === false) { - gl.clearColor(r, g, b, a); - currentColorClear.copy(color); - } - }, - reset: function () { - locked = false; - currentColorMask = null; - currentColorClear.set(-1, 0, 0, 0); // set to invalid state - } - }; - } + for ( const key in this.extensions ) { - function DepthBuffer() { - let locked = false; - let currentDepthMask = null; - let currentDepthFunc = null; - let currentDepthClear = null; - return { - setTest: function (depthTest) { - if (depthTest) { - enable(gl.DEPTH_TEST); - } else { - disable(gl.DEPTH_TEST); - } - }, - setMask: function (depthMask) { - if (currentDepthMask !== depthMask && !locked) { - gl.depthMask(depthMask); - currentDepthMask = depthMask; - } - }, - setFunc: function (depthFunc) { - if (currentDepthFunc !== depthFunc) { - if (depthFunc) { - switch (depthFunc) { - case NeverDepth: - gl.depthFunc(gl.NEVER); - break; + if ( this.extensions[ key ] === true ) extensions[ key ] = true; - case AlwaysDepth: - gl.depthFunc(gl.ALWAYS); - break; + } - case LessDepth: - gl.depthFunc(gl.LESS); - break; + if ( Object.keys( extensions ).length > 0 ) data.extensions = extensions; - case LessEqualDepth: - gl.depthFunc(gl.LEQUAL); - break; + return data; - case EqualDepth: - gl.depthFunc(gl.EQUAL); - break; + } - case GreaterEqualDepth: - gl.depthFunc(gl.GEQUAL); - break; + } - case GreaterDepth: - gl.depthFunc(gl.GREATER); - break; + class Camera extends Object3D { - case NotEqualDepth: - gl.depthFunc(gl.NOTEQUAL); - break; + constructor() { - default: - gl.depthFunc(gl.LEQUAL); - } - } else { - gl.depthFunc(gl.LEQUAL); - } + super(); - currentDepthFunc = depthFunc; - } - }, - setLocked: function (lock) { - locked = lock; - }, - setClear: function (depth) { - if (currentDepthClear !== depth) { - gl.clearDepth(depth); - currentDepthClear = depth; - } - }, - reset: function () { - locked = false; - currentDepthMask = null; - currentDepthFunc = null; - currentDepthClear = null; - } - }; - } + this.isCamera = true; - function StencilBuffer() { - let locked = false; - let currentStencilMask = null; - let currentStencilFunc = null; - let currentStencilRef = null; - let currentStencilFuncMask = null; - let currentStencilFail = null; - let currentStencilZFail = null; - let currentStencilZPass = null; - let currentStencilClear = null; - return { - setTest: function (stencilTest) { - if (!locked) { - if (stencilTest) { - enable(gl.STENCIL_TEST); - } else { - disable(gl.STENCIL_TEST); - } - } - }, - setMask: function (stencilMask) { - if (currentStencilMask !== stencilMask && !locked) { - gl.stencilMask(stencilMask); - currentStencilMask = stencilMask; - } - }, - setFunc: function (stencilFunc, stencilRef, stencilMask) { - if (currentStencilFunc !== stencilFunc || currentStencilRef !== stencilRef || currentStencilFuncMask !== stencilMask) { - gl.stencilFunc(stencilFunc, stencilRef, stencilMask); - currentStencilFunc = stencilFunc; - currentStencilRef = stencilRef; - currentStencilFuncMask = stencilMask; - } - }, - setOp: function (stencilFail, stencilZFail, stencilZPass) { - if (currentStencilFail !== stencilFail || currentStencilZFail !== stencilZFail || currentStencilZPass !== stencilZPass) { - gl.stencilOp(stencilFail, stencilZFail, stencilZPass); - currentStencilFail = stencilFail; - currentStencilZFail = stencilZFail; - currentStencilZPass = stencilZPass; - } - }, - setLocked: function (lock) { - locked = lock; - }, - setClear: function (stencil) { - if (currentStencilClear !== stencil) { - gl.clearStencil(stencil); - currentStencilClear = stencil; - } - }, - reset: function () { - locked = false; - currentStencilMask = null; - currentStencilFunc = null; - currentStencilRef = null; - currentStencilFuncMask = null; - currentStencilFail = null; - currentStencilZFail = null; - currentStencilZPass = null; - currentStencilClear = null; - } - }; - } // + this.type = 'Camera'; + this.matrixWorldInverse = new Matrix4(); - const colorBuffer = new ColorBuffer(); - const depthBuffer = new DepthBuffer(); - const stencilBuffer = new StencilBuffer(); - let enabledCapabilities = {}; - let currentBoundFramebuffers = {}; - let currentDrawbuffers = new WeakMap(); - let defaultDrawbuffers = []; - let currentProgram = null; - let currentBlendingEnabled = false; - let currentBlending = null; - let currentBlendEquation = null; - let currentBlendSrc = null; - let currentBlendDst = null; - let currentBlendEquationAlpha = null; - let currentBlendSrcAlpha = null; - let currentBlendDstAlpha = null; - let currentPremultipledAlpha = false; - let currentFlipSided = null; - let currentCullFace = null; - let currentLineWidth = null; - let currentPolygonOffsetFactor = null; - let currentPolygonOffsetUnits = null; - const maxTextures = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS); - let lineWidthAvailable = false; - let version = 0; - const glVersion = gl.getParameter(gl.VERSION); + this.projectionMatrix = new Matrix4(); + this.projectionMatrixInverse = new Matrix4(); - if (glVersion.indexOf('WebGL') !== -1) { - version = parseFloat(/^WebGL (\d)/.exec(glVersion)[1]); - lineWidthAvailable = version >= 1.0; - } else if (glVersion.indexOf('OpenGL ES') !== -1) { - 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); + copy( source, recursive ) { - function createTexture(type, target, count) { - const data = new Uint8Array(4); // 4 is required to match default unpack alignment of 4. + super.copy( source, recursive ); - 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); + this.matrixWorldInverse.copy( source.matrixWorldInverse ); - for (let i = 0; i < count; i++) { - gl.texImage2D(target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data); - } + this.projectionMatrix.copy( source.projectionMatrix ); + this.projectionMatrixInverse.copy( source.projectionMatrixInverse ); + + return this; - 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 + getWorldDirection( target ) { - colorBuffer.setClear(0, 0, 0, 1); - depthBuffer.setClear(1); - stencilBuffer.setClear(0); - enable(gl.DEPTH_TEST); - depthBuffer.setFunc(LessEqualDepth); - setFlipSided(false); - setCullFace(CullFaceBack); - enable(gl.CULL_FACE); - setBlending(NoBlending); // + this.updateWorldMatrix( true, false ); - function enable(id) { - if (enabledCapabilities[id] !== true) { - gl.enable(id); - enabledCapabilities[id] = true; - } - } + const e = this.matrixWorld.elements; - function disable(id) { - if (enabledCapabilities[id] !== false) { - gl.disable(id); - enabledCapabilities[id] = false; - } - } + return target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize(); - 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; - } + updateMatrixWorld( force ) { - if (target === gl.FRAMEBUFFER) { - currentBoundFramebuffers[gl.DRAW_FRAMEBUFFER] = framebuffer; - } - } + super.updateMatrixWorld( force ); - return true; - } + this.matrixWorldInverse.copy( this.matrixWorld ).invert(); - return false; } - function drawBuffers(renderTarget, framebuffer) { - let drawBuffers = defaultDrawbuffers; - let needsUpdate = false; + updateWorldMatrix( updateParents, updateChildren ) { - if (renderTarget) { - drawBuffers = currentDrawbuffers.get(framebuffer); + super.updateWorldMatrix( updateParents, updateChildren ); - if (drawBuffers === undefined) { - drawBuffers = []; - currentDrawbuffers.set(framebuffer, drawBuffers); - } + this.matrixWorldInverse.copy( this.matrixWorld ).invert(); - 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; - } + clone() { - drawBuffers.length = textures.length; - needsUpdate = true; - } - } else { - if (drawBuffers[0] !== gl.COLOR_ATTACHMENT0) { - drawBuffers[0] = gl.COLOR_ATTACHMENT0; - needsUpdate = true; - } - } - } else { - if (drawBuffers[0] !== gl.BACK) { - drawBuffers[0] = gl.BACK; - needsUpdate = true; - } - } + return new this.constructor().copy( this ); - if (needsUpdate) { - if (capabilities.isWebGL2) { - gl.drawBuffers(drawBuffers); - } else { - extensions.get('WEBGL_draw_buffers').drawBuffersWEBGL(drawBuffers); - } - } } - function useProgram(program) { - if (currentProgram !== program) { - gl.useProgram(program); - currentProgram = program; - return true; - } + } - return false; - } + class PerspectiveCamera extends Camera { - const equationToGL = { - [AddEquation]: gl.FUNC_ADD, - [SubtractEquation]: gl.FUNC_SUBTRACT, - [ReverseSubtractEquation]: gl.FUNC_REVERSE_SUBTRACT - }; + constructor( fov = 50, aspect = 1, near = 0.1, far = 2000 ) { - if (isWebGL2) { - equationToGL[MinEquation] = gl.MIN; - equationToGL[MaxEquation] = gl.MAX; - } else { - const extension = extensions.get('EXT_blend_minmax'); + super(); - if (extension !== null) { - equationToGL[MinEquation] = extension.MIN_EXT; - equationToGL[MaxEquation] = extension.MAX_EXT; - } - } + this.isPerspectiveCamera = true; - const factorToGL = { - [ZeroFactor]: gl.ZERO, - [OneFactor]: gl.ONE, - [SrcColorFactor]: gl.SRC_COLOR, - [SrcAlphaFactor]: gl.SRC_ALPHA, - [SrcAlphaSaturateFactor]: gl.SRC_ALPHA_SATURATE, - [DstColorFactor]: gl.DST_COLOR, - [DstAlphaFactor]: gl.DST_ALPHA, - [OneMinusSrcColorFactor]: gl.ONE_MINUS_SRC_COLOR, - [OneMinusSrcAlphaFactor]: gl.ONE_MINUS_SRC_ALPHA, - [OneMinusDstColorFactor]: gl.ONE_MINUS_DST_COLOR, - [OneMinusDstAlphaFactor]: gl.ONE_MINUS_DST_ALPHA - }; + this.type = 'PerspectiveCamera'; - function setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha) { - if (blending === NoBlending) { - if (currentBlendingEnabled === true) { - disable(gl.BLEND); - currentBlendingEnabled = false; - } + this.fov = fov; + this.zoom = 1; - return; - } + this.near = near; + this.far = far; + this.focus = 10; - if (currentBlendingEnabled === false) { - enable(gl.BLEND); - currentBlendingEnabled = true; - } + this.aspect = aspect; + this.view = null; - if (blending !== CustomBlending) { - if (blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha) { - if (currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation) { - gl.blendEquation(gl.FUNC_ADD); - currentBlendEquation = AddEquation; - currentBlendEquationAlpha = AddEquation; - } + this.filmGauge = 35; // width of the film (default in millimeters) + this.filmOffset = 0; // horizontal film offset (same unit as gauge) - if (premultipliedAlpha) { - switch (blending) { - case NormalBlending: - gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - break; + this.updateProjectionMatrix(); - 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; + copy( source, recursive ) { - case MultiplyBlending: - gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA); - break; + super.copy( source, recursive ); - default: - console.error('THREE.WebGLState: Invalid blending: ', blending); - break; - } - } else { - switch (blending) { - case NormalBlending: - gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - break; + this.fov = source.fov; + this.zoom = source.zoom; - case AdditiveBlending: - gl.blendFunc(gl.SRC_ALPHA, gl.ONE); - break; + this.near = source.near; + this.far = source.far; + this.focus = source.focus; - case SubtractiveBlending: - gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE); - break; + this.aspect = source.aspect; + this.view = source.view === null ? null : Object.assign( {}, source.view ); - case MultiplyBlending: - gl.blendFunc(gl.ZERO, gl.SRC_COLOR); - break; + this.filmGauge = source.filmGauge; + this.filmOffset = source.filmOffset; - default: - console.error('THREE.WebGLState: Invalid blending: ', blending); - break; - } - } + return this; - currentBlendSrc = null; - currentBlendDst = null; - currentBlendSrcAlpha = null; - currentBlendDstAlpha = null; - currentBlending = blending; - currentPremultipledAlpha = premultipliedAlpha; - } + } - return; - } // custom blending + /** + * Sets the FOV by focal length in respect to the current .filmGauge. + * + * The default film gauge is 35, so that the focal length can be specified for + * a 35mm (full frame) camera. + * + * Values for focal length and film gauge must have the same unit. + */ + setFocalLength( focalLength ) { + /** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */ + const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; - blendEquationAlpha = blendEquationAlpha || blendEquation; - blendSrcAlpha = blendSrcAlpha || blendSrc; - blendDstAlpha = blendDstAlpha || blendDst; + this.fov = RAD2DEG * 2 * Math.atan( vExtentSlope ); + this.updateProjectionMatrix(); - 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; - currentBlendDst = blendDst; - currentBlendSrcAlpha = blendSrcAlpha; - currentBlendDstAlpha = blendDstAlpha; - } + /** + * Calculates the focal length from the current .fov and .filmGauge. + */ + getFocalLength() { - currentBlending = blending; - currentPremultipledAlpha = null; - } - - function setMaterial(material, frontFaceCW) { - material.side === DoubleSide ? disable(gl.CULL_FACE) : enable(gl.CULL_FACE); - let flipSided = material.side === BackSide; - if (frontFaceCW) flipSided = !flipSided; - setFlipSided(flipSided); - material.blending === NormalBlending && material.transparent === false ? setBlending(NoBlending) : setBlending(material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha); - depthBuffer.setFunc(material.depthFunc); - depthBuffer.setTest(material.depthTest); - depthBuffer.setMask(material.depthWrite); - colorBuffer.setMask(material.colorWrite); - const stencilWrite = material.stencilWrite; - stencilBuffer.setTest(stencilWrite); + const vExtentSlope = Math.tan( DEG2RAD * 0.5 * this.fov ); - if (stencilWrite) { - stencilBuffer.setMask(material.stencilWriteMask); - stencilBuffer.setFunc(material.stencilFunc, material.stencilRef, material.stencilFuncMask); - stencilBuffer.setOp(material.stencilFail, material.stencilZFail, material.stencilZPass); - } + return 0.5 * this.getFilmHeight() / vExtentSlope; - setPolygonOffset(material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits); - material.alphaToCoverage === true ? enable(gl.SAMPLE_ALPHA_TO_COVERAGE) : disable(gl.SAMPLE_ALPHA_TO_COVERAGE); - } // + } + getEffectiveFOV() { - function setFlipSided(flipSided) { - if (currentFlipSided !== flipSided) { - if (flipSided) { - gl.frontFace(gl.CW); - } else { - gl.frontFace(gl.CCW); - } + return RAD2DEG * 2 * Math.atan( + Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom ); - currentFlipSided = flipSided; - } } - function setCullFace(cullFace) { - if (cullFace !== CullFaceNone) { - enable(gl.CULL_FACE); + getFilmWidth() { - if (cullFace !== currentCullFace) { - if (cullFace === CullFaceBack) { - gl.cullFace(gl.BACK); - } else if (cullFace === CullFaceFront) { - gl.cullFace(gl.FRONT); - } else { - gl.cullFace(gl.FRONT_AND_BACK); - } - } - } else { - disable(gl.CULL_FACE); - } + // film not completely covered in portrait format (aspect < 1) + return this.filmGauge * Math.min( this.aspect, 1 ); - currentCullFace = cullFace; } - function setLineWidth(width) { - if (width !== currentLineWidth) { - if (lineWidthAvailable) gl.lineWidth(width); - currentLineWidth = width; - } - } + getFilmHeight() { - function setPolygonOffset(polygonOffset, factor, units) { - if (polygonOffset) { - enable(gl.POLYGON_OFFSET_FILL); + // film not completely covered in landscape format (aspect > 1) + return this.filmGauge / Math.max( this.aspect, 1 ); - if (currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units) { - gl.polygonOffset(factor, units); - currentPolygonOffsetFactor = factor; - currentPolygonOffsetUnits = units; - } - } else { - disable(gl.POLYGON_OFFSET_FILL); - } } - function setScissorTest(scissorTest) { - if (scissorTest) { - enable(gl.SCISSOR_TEST); - } else { - disable(gl.SCISSOR_TEST); - } - } // texture + /** + * Sets an offset in a larger frustum. This is useful for multi-window or + * multi-monitor/multi-machine setups. + * + * For example, if you have 3x2 monitors and each monitor is 1920x1080 and + * the monitors are in grid like this + * + * +---+---+---+ + * | A | B | C | + * +---+---+---+ + * | D | E | F | + * +---+---+---+ + * + * then for each monitor you would call it like this + * + * const w = 1920; + * const h = 1080; + * const fullWidth = w * 3; + * const fullHeight = h * 2; + * + * --A-- + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); + * --B-- + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); + * --C-- + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); + * --D-- + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); + * --E-- + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); + * --F-- + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); + * + * Note there is no reason monitors have to be the same size or in a grid. + */ + setViewOffset( fullWidth, fullHeight, x, y, width, height ) { + this.aspect = fullWidth / fullHeight; - function activeTexture(webglSlot) { - if (webglSlot === undefined) webglSlot = gl.TEXTURE0 + maxTextures - 1; + if ( this.view === null ) { - if (currentTextureSlot !== webglSlot) { - gl.activeTexture(webglSlot); - currentTextureSlot = webglSlot; - } - } + this.view = { + enabled: true, + fullWidth: 1, + fullHeight: 1, + offsetX: 0, + offsetY: 0, + width: 1, + height: 1 + }; - function bindTexture(webglType, webglTexture) { - if (currentTextureSlot === null) { - activeTexture(); } - let boundTexture = currentBoundTextures[currentTextureSlot]; + this.view.enabled = true; + this.view.fullWidth = fullWidth; + this.view.fullHeight = fullHeight; + this.view.offsetX = x; + this.view.offsetY = y; + this.view.width = width; + this.view.height = height; - if (boundTexture === undefined) { - boundTexture = { - type: undefined, - texture: undefined - }; - currentBoundTextures[currentTextureSlot] = boundTexture; - } + this.updateProjectionMatrix(); - if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) { - gl.bindTexture(webglType, webglTexture || emptyTextures[webglType]); - boundTexture.type = webglType; - boundTexture.texture = webglTexture; - } } - function unbindTexture() { - const boundTexture = currentBoundTextures[currentTextureSlot]; + clearViewOffset() { - if (boundTexture !== undefined && boundTexture.type !== undefined) { - gl.bindTexture(boundTexture.type, null); - boundTexture.type = undefined; - boundTexture.texture = undefined; - } - } + if ( this.view !== null ) { - function compressedTexImage2D() { - try { - gl.compressedTexImage2D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } + this.view.enabled = false; - function texSubImage2D() { - try { - gl.texSubImage2D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); } - } - function texSubImage3D() { - try { - gl.texSubImage3D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } + this.updateProjectionMatrix(); - function compressedTexSubImage2D() { - try { - gl.compressedTexSubImage2D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } } - function texStorage2D() { - try { - gl.texStorage2D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } + updateProjectionMatrix() { - function texStorage3D() { - try { - gl.texStorage3D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } + const near = this.near; + let top = near * Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom; + let height = 2 * top; + let width = this.aspect * height; + let left = - 0.5 * width; + const view = this.view; - function texImage2D() { - try { - gl.texImage2D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } + if ( this.view !== null && this.view.enabled ) { - function texImage3D() { - try { - gl.texImage3D.apply(gl, arguments); - } catch (error) { - console.error('THREE.WebGLState:', error); - } - } // + const fullWidth = view.fullWidth, + fullHeight = view.fullHeight; + left += view.offsetX * width / fullWidth; + top -= view.offsetY * height / fullHeight; + width *= view.width / fullWidth; + height *= view.height / fullHeight; - function scissor(scissor) { - if (currentScissor.equals(scissor) === false) { - gl.scissor(scissor.x, scissor.y, scissor.z, scissor.w); - currentScissor.copy(scissor); } - } - function viewport(viewport) { - if (currentViewport.equals(viewport) === false) { - gl.viewport(viewport.x, viewport.y, viewport.z, viewport.w); - currentViewport.copy(viewport); - } - } // + const skew = this.filmOffset; + if ( skew !== 0 ) left += near * skew / this.getFilmWidth(); + this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far ); - function reset() { - // reset state - gl.disable(gl.BLEND); - gl.disable(gl.CULL_FACE); - gl.disable(gl.DEPTH_TEST); - gl.disable(gl.POLYGON_OFFSET_FILL); - gl.disable(gl.SCISSOR_TEST); - gl.disable(gl.STENCIL_TEST); - gl.disable(gl.SAMPLE_ALPHA_TO_COVERAGE); - gl.blendEquation(gl.FUNC_ADD); - gl.blendFunc(gl.ONE, gl.ZERO); - gl.blendFuncSeparate(gl.ONE, gl.ZERO, gl.ONE, gl.ZERO); - gl.colorMask(true, true, true, true); - gl.clearColor(0, 0, 0, 0); - gl.depthMask(true); - gl.depthFunc(gl.LESS); - gl.clearDepth(1); - gl.stencilMask(0xffffffff); - gl.stencilFunc(gl.ALWAYS, 0, 0xffffffff); - gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); - gl.clearStencil(0); - gl.cullFace(gl.BACK); - gl.frontFace(gl.CCW); - 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 + this.projectionMatrixInverse.copy( this.projectionMatrix ).invert(); - enabledCapabilities = {}; - currentTextureSlot = null; - currentBoundTextures = {}; - currentBoundFramebuffers = {}; - currentDrawbuffers = new WeakMap(); - defaultDrawbuffers = []; - currentProgram = null; - currentBlendingEnabled = false; - currentBlending = null; - currentBlendEquation = null; - currentBlendSrc = null; - currentBlendDst = null; - currentBlendEquationAlpha = null; - currentBlendSrcAlpha = null; - currentBlendDstAlpha = null; - currentPremultipledAlpha = false; - currentFlipSided = null; - currentCullFace = null; - currentLineWidth = null; - currentPolygonOffsetFactor = null; - currentPolygonOffsetUnits = null; - currentScissor.set(0, 0, gl.canvas.width, gl.canvas.height); - currentViewport.set(0, 0, gl.canvas.width, gl.canvas.height); - colorBuffer.reset(); - depthBuffer.reset(); - stencilBuffer.reset(); } - return { - buffers: { - color: colorBuffer, - depth: depthBuffer, - stencil: stencilBuffer - }, - enable: enable, - disable: disable, - bindFramebuffer: bindFramebuffer, - drawBuffers: drawBuffers, - useProgram: useProgram, - setBlending: setBlending, - setMaterial: setMaterial, - setFlipSided: setFlipSided, - setCullFace: setCullFace, - setLineWidth: setLineWidth, - setPolygonOffset: setPolygonOffset, - setScissorTest: setScissorTest, - activeTexture: activeTexture, - bindTexture: bindTexture, - unbindTexture: unbindTexture, - compressedTexImage2D: compressedTexImage2D, - texImage2D: texImage2D, - texImage3D: texImage3D, - texStorage2D: texStorage2D, - texStorage3D: texStorage3D, - texSubImage2D: texSubImage2D, - texSubImage3D: texSubImage3D, - compressedTexSubImage2D: compressedTexSubImage2D, - scissor: scissor, - viewport: viewport, - reset: reset - }; - } + toJSON( meta ) { - function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info) { - const isWebGL2 = capabilities.isWebGL2; - const maxTextures = capabilities.maxTextures; - const maxCubemapSize = capabilities.maxCubemapSize; - 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 data = super.toJSON( meta ); - const _videoTextures = new WeakMap(); + data.object.fov = this.fov; + data.object.zoom = this.zoom; - let _canvas; + data.object.near = this.near; + data.object.far = this.far; + data.object.focus = this.focus; - 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). + data.object.aspect = this.aspect; + if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); - let useOffscreenCanvas = false; + data.object.filmGauge = this.filmGauge; + data.object.filmOffset = this.filmOffset; - try { - useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' // eslint-disable-next-line compat/compat - && new OffscreenCanvas(1, 1).getContext('2d') !== null; - } catch (err) {// Ignore any errors - } + return data; - function createCanvas(width, height) { - // Use OffscreenCanvas when available. Specially needed in web workers - 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 + } - if (image.width > maxSize || image.height > maxSize) { - scale = maxSize / Math.max(image.width, image.height); - } // only perform resize if necessary + const fov = - 90; // negative fov is not an error + const aspect = 1; + class CubeCamera extends Object3D { - 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 + constructor( near, far, renderTarget ) { - const canvas = needsNewCanvas ? createCanvas(width, height) : _canvas; - canvas.width = width; - canvas.height = height; - const context = canvas.getContext('2d'); - context.drawImage(image, 0, 0, width, height); - console.warn('THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').'); - return canvas; - } else { - if ('data' in image) { - console.warn('THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').'); - } + super(); - return image; - } - } + this.type = 'CubeCamera'; - return image; - } + this.renderTarget = renderTarget; - function isPowerOfTwo$1(image) { - return isPowerOfTwo(image.width) && isPowerOfTwo(image.height); - } + const cameraPX = new PerspectiveCamera( fov, aspect, near, far ); + cameraPX.layers = this.layers; + cameraPX.up.set( 0, 1, 0 ); + cameraPX.lookAt( 1, 0, 0 ); + this.add( cameraPX ); - function textureNeedsPowerOfTwo(texture) { - if (isWebGL2) return false; - return texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping || texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; - } + const cameraNX = new PerspectiveCamera( fov, aspect, near, far ); + cameraNX.layers = this.layers; + cameraNX.up.set( 0, 1, 0 ); + cameraNX.lookAt( - 1, 0, 0 ); + this.add( cameraNX ); - function textureNeedsGenerateMipmaps(texture, supportsMips) { - return texture.generateMipmaps && supportsMips && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; - } + const cameraPY = new PerspectiveCamera( fov, aspect, near, far ); + cameraPY.layers = this.layers; + cameraPY.up.set( 0, 0, - 1 ); + cameraPY.lookAt( 0, 1, 0 ); + this.add( cameraPY ); - function generateMipmap(target) { - _gl.generateMipmap(target); - } + const cameraNY = new PerspectiveCamera( fov, aspect, near, far ); + cameraNY.layers = this.layers; + cameraNY.up.set( 0, 0, 1 ); + cameraNY.lookAt( 0, - 1, 0 ); + this.add( cameraNY ); - function getInternalFormat(internalFormatName, glFormat, glType, encoding, isVideoTexture = false) { - if (isWebGL2 === false) return glFormat; + const cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); + cameraPZ.layers = this.layers; + cameraPZ.up.set( 0, 1, 0 ); + cameraPZ.lookAt( 0, 0, 1 ); + this.add( cameraPZ ); - if (internalFormatName !== null) { - if (_gl[internalFormatName] !== undefined) return _gl[internalFormatName]; - console.warn('THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\''); - } + const cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); + cameraNZ.layers = this.layers; + cameraNZ.up.set( 0, 1, 0 ); + cameraNZ.lookAt( 0, 0, - 1 ); + this.add( cameraNZ ); - 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; - } + update( renderer, scene ) { - 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 ( this.parent === null ) this.updateMatrixWorld(); - 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_SHORT_4_4_4_4) internalFormat = _gl.RGBA4; - if (glType === _gl.UNSIGNED_SHORT_5_5_5_1) internalFormat = _gl.RGB5_A1; - } + const renderTarget = this.renderTarget; - 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'); - } + const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = this.children; - return internalFormat; - } + const currentRenderTarget = renderer.getRenderTarget(); - 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 + const currentToneMapping = renderer.toneMapping; + const currentXrEnabled = renderer.xr.enabled; + renderer.toneMapping = NoToneMapping; + renderer.xr.enabled = false; - function filterFallback(f) { - if (f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter) { - return _gl.NEAREST; - } + const generateMipmaps = renderTarget.texture.generateMipmaps; - return _gl.LINEAR; - } // + renderTarget.texture.generateMipmaps = false; + renderer.setRenderTarget( renderTarget, 0 ); + renderer.render( scene, cameraPX ); - function onTextureDispose(event) { - const texture = event.target; - texture.removeEventListener('dispose', onTextureDispose); - deallocateTexture(texture); + renderer.setRenderTarget( renderTarget, 1 ); + renderer.render( scene, cameraNX ); - if (texture.isVideoTexture) { - _videoTextures.delete(texture); - } - } + renderer.setRenderTarget( renderTarget, 2 ); + renderer.render( scene, cameraPY ); - function onRenderTargetDispose(event) { - const renderTarget = event.target; - renderTarget.removeEventListener('dispose', onRenderTargetDispose); - deallocateRenderTarget(renderTarget); - } // + renderer.setRenderTarget( renderTarget, 3 ); + renderer.render( scene, cameraNY ); + renderer.setRenderTarget( renderTarget, 4 ); + renderer.render( scene, cameraPZ ); - function deallocateTexture(texture) { - const textureProperties = properties.get(texture); - if (textureProperties.__webglInit === undefined) return; // check if it's necessary to remove the WebGLTexture object + renderTarget.texture.generateMipmaps = generateMipmaps; - const source = texture.source; + renderer.setRenderTarget( renderTarget, 5 ); + renderer.render( scene, cameraNZ ); - const webglTextures = _sources.get(source); + renderer.setRenderTarget( currentRenderTarget ); - if (webglTextures) { - const webglTexture = webglTextures[textureProperties.__cacheKey]; - webglTexture.usedTimes--; // the WebGLTexture object is not used anymore, remove it + renderer.toneMapping = currentToneMapping; + renderer.xr.enabled = currentXrEnabled; - if (webglTexture.usedTimes === 0) { - deleteTexture(texture); - } // remove the weak map entry if no WebGLTexture uses the source anymore + renderTarget.texture.needsPMREMUpdate = true; + } - if (Object.keys(webglTextures).length === 0) { - _sources.delete(source); - } - } + } - properties.remove(texture); - } + class CubeTexture extends Texture { - function deleteTexture(texture) { - const textureProperties = properties.get(texture); + constructor( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { + + images = images !== undefined ? images : []; + mapping = mapping !== undefined ? mapping : CubeReflectionMapping; - _gl.deleteTexture(textureProperties.__webglTexture); + super( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); - const source = texture.source; + this.isCubeTexture = true; - const webglTextures = _sources.get(source); + this.flipY = false; - delete webglTextures[textureProperties.__cacheKey]; - info.memory.textures--; } - function deallocateRenderTarget(renderTarget) { - const texture = renderTarget.texture; - const renderTargetProperties = properties.get(renderTarget); - const textureProperties = properties.get(texture); + get images() { - if (textureProperties.__webglTexture !== undefined) { - _gl.deleteTexture(textureProperties.__webglTexture); + return this.image; - info.memory.textures--; - } + } - if (renderTarget.depthTexture) { - renderTarget.depthTexture.dispose(); - } + set images( value ) { - if (renderTarget.isWebGLCubeRenderTarget) { - for (let i = 0; i < 6; i++) { - _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i]); + this.image = value; - 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]); - } - } + class WebGLCubeRenderTarget extends WebGLRenderTarget { - if (renderTargetProperties.__webglDepthRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthRenderbuffer); - } + constructor( size = 1, options = {} ) { - if (renderTarget.isWebGLMultipleRenderTargets) { - for (let i = 0, il = texture.length; i < il; i++) { - const attachmentProperties = properties.get(texture[i]); + super( size, size, options ); - if (attachmentProperties.__webglTexture) { - _gl.deleteTexture(attachmentProperties.__webglTexture); + this.isWebGLCubeRenderTarget = true; - info.memory.textures--; - } + const image = { width: size, height: size, depth: 1 }; + const images = [ image, image, image, image, image, image ]; - properties.remove(texture[i]); - } - } + this.texture = new CubeTexture( images, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); - properties.remove(texture); - properties.remove(renderTarget); - } // + // 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). - let textureUnits = 0; + this.texture.isRenderTargetTexture = true; + + this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; + this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; - function resetTextureUnits() { - textureUnits = 0; } - function allocateTextureUnit() { - const textureUnit = textureUnits; + fromEquirectangularTexture( renderer, texture ) { - if (textureUnit >= maxTextures) { - console.warn('THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures); - } + this.texture.type = texture.type; + this.texture.encoding = texture.encoding; - textureUnits += 1; - return textureUnit; - } + this.texture.generateMipmaps = texture.generateMipmaps; + this.texture.minFilter = texture.minFilter; + this.texture.magFilter = texture.magFilter; - function getTextureCacheKey(texture) { - const array = []; - array.push(texture.wrapS); - array.push(texture.wrapT); - array.push(texture.magFilter); - array.push(texture.minFilter); - array.push(texture.anisotropy); - array.push(texture.internalFormat); - array.push(texture.format); - array.push(texture.type); - array.push(texture.generateMipmaps); - array.push(texture.premultiplyAlpha); - array.push(texture.flipY); - array.push(texture.unpackAlignment); - array.push(texture.encoding); - return array.join(); - } // + const shader = { + uniforms: { + tEquirect: { value: null }, + }, - function setTexture2D(texture, slot) { - const textureProperties = properties.get(texture); - if (texture.isVideoTexture) updateVideoTexture(texture); + vertexShader: /* glsl */` - if (texture.isRenderTargetTexture === false && texture.version > 0 && textureProperties.__version !== texture.version) { - const image = texture.image; + varying vec3 vWorldDirection; - if (image === null) { - console.warn('THREE.WebGLRenderer: Texture marked for update but no image data found.'); - } else if (image.complete === false) { - console.warn('THREE.WebGLRenderer: Texture marked for update but image is incomplete'); - } else { - uploadTexture(textureProperties, texture, slot); - return; - } - } + vec3 transformDirection( in vec3 dir, in mat4 matrix ) { - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_2D, textureProperties.__webglTexture); - } + return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); - function setTexture2DArray(texture, slot) { - const textureProperties = properties.get(texture); + } - if (texture.version > 0 && textureProperties.__version !== texture.version) { - uploadTexture(textureProperties, texture, slot); - return; - } + void main() { - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture); - } + vWorldDirection = transformDirection( position, modelMatrix ); - function setTexture3D(texture, slot) { - const textureProperties = properties.get(texture); + #include + #include - 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); - } + fragmentShader: /* glsl */` - function setTextureCube(texture, slot) { - const textureProperties = properties.get(texture); + uniform sampler2D tEquirect; - if (texture.version > 0 && textureProperties.__version !== texture.version) { - uploadCubeTexture(textureProperties, texture, slot); - return; - } + varying vec3 vWorldDirection; - state.activeTexture(_gl.TEXTURE0 + slot); - state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); - } + #include - const wrappingToGL = { - [RepeatWrapping]: _gl.REPEAT, - [ClampToEdgeWrapping]: _gl.CLAMP_TO_EDGE, - [MirroredRepeatWrapping]: _gl.MIRRORED_REPEAT - }; - const filterToGL = { - [NearestFilter]: _gl.NEAREST, - [NearestMipmapNearestFilter]: _gl.NEAREST_MIPMAP_NEAREST, - [NearestMipmapLinearFilter]: _gl.NEAREST_MIPMAP_LINEAR, - [LinearFilter]: _gl.LINEAR, - [LinearMipmapNearestFilter]: _gl.LINEAR_MIPMAP_NEAREST, - [LinearMipmapLinearFilter]: _gl.LINEAR_MIPMAP_LINEAR - }; + void main() { + + vec3 direction = normalize( vWorldDirection ); - function setTextureParameters(textureType, texture, supportsMips) { - if (supportsMips) { - _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, wrappingToGL[texture.wrapS]); + vec2 sampleUV = equirectUv( direction ); - _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, wrappingToGL[texture.wrapT]); + gl_FragColor = texture2D( tEquirect, sampleUV ); - 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]); + const geometry = new BoxGeometry( 5, 5, 5 ); - _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterToGL[texture.minFilter]); - } else { - _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE); + const material = new ShaderMaterial( { - _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE); + name: 'CubemapFromEquirect', - if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) { - _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, _gl.CLAMP_TO_EDGE); - } + uniforms: cloneUniforms( shader.uniforms ), + vertexShader: shader.vertexShader, + fragmentShader: shader.fragmentShader, + side: BackSide, + blending: NoBlending - 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)); + material.uniforms.tEquirect.value = texture; - _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterFallback(texture.minFilter)); + const mesh = new Mesh( geometry, material ); - 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.'); - } - } + const currentMinFilter = texture.minFilter; - 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 + // Avoid blurred poles + if ( texture.minFilter === LinearMipmapLinearFilter ) texture.minFilter = LinearFilter; - if (isWebGL2 === false && texture.type === HalfFloatType && extensions.has('OES_texture_half_float_linear') === false) return; // verify extension for WebGL 1 only + const camera = new CubeCamera( 1, 10, this ); + camera.update( renderer, mesh ); - if (texture.anisotropy > 1 || properties.get(texture).__currentAnisotropy) { - _gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(texture.anisotropy, capabilities.getMaxAnisotropy())); + texture.minFilter = currentMinFilter; - properties.get(texture).__currentAnisotropy = texture.anisotropy; - } - } - } + mesh.geometry.dispose(); + mesh.material.dispose(); - function initTexture(textureProperties, texture) { - let forceUpload = false; + return this; - if (textureProperties.__webglInit === undefined) { - textureProperties.__webglInit = true; - texture.addEventListener('dispose', onTextureDispose); - } // create Source <-> WebGLTextures mapping if necessary + } + clear( renderer, color, depth, stencil ) { - const source = texture.source; + const currentRenderTarget = renderer.getRenderTarget(); - let webglTextures = _sources.get(source); + for ( let i = 0; i < 6; i ++ ) { - if (webglTextures === undefined) { - webglTextures = {}; + renderer.setRenderTarget( this, i ); - _sources.set(source, webglTextures); - } // check if there is already a WebGLTexture object for the given texture parameters + renderer.clear( color, depth, stencil ); + } - const textureCacheKey = getTextureCacheKey(texture); + renderer.setRenderTarget( currentRenderTarget ); - 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 - // even if the image contents are identical + } - forceUpload = true; - } + } - webglTextures[textureCacheKey].usedTimes++; // 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 _vector1 = /*@__PURE__*/ new Vector3(); + const _vector2 = /*@__PURE__*/ new Vector3(); + const _normalMatrix = /*@__PURE__*/ new Matrix3(); - const webglTexture = webglTextures[textureProperties.__cacheKey]; + class Plane { - if (webglTexture !== undefined) { - webglTextures[textureProperties.__cacheKey].usedTimes--; + constructor( normal = new Vector3( 1, 0, 0 ), constant = 0 ) { - if (webglTexture.usedTimes === 0) { - deleteTexture(texture); - } - } // store references to cache key and WebGLTexture object + this.isPlane = true; + // normal is assumed to be normalized - textureProperties.__cacheKey = textureCacheKey; - textureProperties.__webglTexture = webglTextures[textureCacheKey].texture; - } + this.normal = normal; + this.constant = constant; - return forceUpload; } - function uploadTexture(textureProperties, texture, slot) { - let textureType = _gl.TEXTURE_2D; - if (texture.isDataArrayTexture) 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); + set( normal, constant ) { - if (source.version !== source.__currentVersion || forceUpload === true) { - _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + this.normal.copy( normal ); + this.constant = constant; - _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha); + return this; - _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment); + } - _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE); + setComponents( x, y, z, w ) { - 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); - let glType = utils.convert(texture.type), - 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 levels = getMipLevels(texture, image, supportsMips); + this.normal.set( x, y, z ); + this.constant = w; - if (texture.isDepthTexture) { - // populate depth texture with dummy data - glInternalFormat = _gl.DEPTH_COMPONENT; + return this; - if (isWebGL2) { - if (texture.type === FloatType) { - glInternalFormat = _gl.DEPTH_COMPONENT32F; - } else if (texture.type === UnsignedIntType) { - glInternalFormat = _gl.DEPTH_COMPONENT24; - } else if (texture.type === UnsignedInt248Type) { - glInternalFormat = _gl.DEPTH24_STENCIL8; - } else { - glInternalFormat = _gl.DEPTH_COMPONENT16; // WebGL2 requires sized internalformat for glTexImage2D - } - } else { - if (texture.type === FloatType) { - console.error('WebGLRenderer: Floating point depth texture requires WebGL2.'); - } - } // validation checks for WebGL 1 + } + setFromNormalAndCoplanarPoint( normal, point ) { - if (texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT) { - // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are - // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT - // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) - if (texture.type !== UnsignedShortType && texture.type !== UnsignedIntType) { - console.warn('THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.'); - texture.type = UnsignedIntType; - glType = utils.convert(texture.type); - } - } + this.normal.copy( normal ); + this.constant = - point.dot( this.normal ); - 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 - // DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL. - // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) + return this; - if (texture.type !== UnsignedInt248Type) { - console.warn('THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.'); - texture.type = UnsignedInt248Type; - glType = utils.convert(texture.type); - } - } // + } + setFromCoplanarPoints( a, b, c ) { - if (allocateMemory) { - if (useTexStorage) { - state.texStorage2D(_gl.TEXTURE_2D, 1, glInternalFormat, image.width, image.height); - } else { - state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null); - } - } - } else if (texture.isDataTexture) { - // use manually created mipmaps if available - // if there are no manual mipmaps - // set 0 level mipmap and then use GL to generate other mipmap levels - if (mipmaps.length > 0 && supportsMips) { - if (useTexStorage && allocateMemory) { - state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); - } + const normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize(); - for (let i = 0, il = mipmaps.length; i < il; i++) { - mipmap = mipmaps[i]; + // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? - 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); - } - } + this.setFromNormalAndCoplanarPoint( normal, a ); - texture.generateMipmaps = false; - } else { - if (useTexStorage) { - if (allocateMemory) { - state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); - } + return this; - 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]; + copy( plane ) { - 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 { - 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); - } - } - } - } else if (texture.isDataArrayTexture) { - if (useTexStorage) { - if (allocateMemory) { - state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth); - } + this.normal.copy( plane.normal ); + this.constant = plane.constant; - 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); - } - } else if (texture.isData3DTexture) { - if (useTexStorage) { - if (allocateMemory) { - state.texStorage3D(_gl.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth); - } + return this; - 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); - } - } else if (texture.isFramebufferTexture) { - if (allocateMemory) { - if (useTexStorage) { - state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); - } else { - let width = image.width, - 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; - height >>= 1; - } - } - } - } 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); - } + normalize() { - for (let i = 0, il = mipmaps.length; i < il; i++) { - mipmap = mipmaps[i]; + // Note: will lead to a divide by zero if the plane is invalid. - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap); - } else { - state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap); - } - } + const inverseNormalLength = 1.0 / this.normal.length(); + this.normal.multiplyScalar( inverseNormalLength ); + this.constant *= inverseNormalLength; - texture.generateMipmaps = false; - } else { - if (useTexStorage) { - if (allocateMemory) { - state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); - } + return this; - 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); - } + negate() { - source.__currentVersion = source.version; - if (texture.onUpdate) texture.onUpdate(texture); - } + this.constant *= - 1; + this.normal.negate(); + + return this; - 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); + distanceToPoint( point ) { - if (source.version !== source.__currentVersion || forceUpload === true) { - _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + return this.normal.dot( point ) + this.constant; - _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha); + } - _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment); + distanceToSphere( sphere ) { - _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE); + return this.distanceToPoint( sphere.center ) - sphere.radius; - 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]; - } + projectPoint( point, target ) { - cubeImage[i] = verifyColorSpace(texture, cubeImage[i]); - } + return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point ); - 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); - const useTexStorage = isWebGL2 && texture.isVideoTexture !== true; - const allocateMemory = source.__currentVersion === 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) { - state.compressedTexSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); - } else { - state.compressedTexImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); - } - } else { - console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()'); - } - } else { - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); - } else { - state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); - } - } - } - } - } else { - mipmaps = texture.mipmaps; + intersectLine( line, target ) { - 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); - } + const direction = line.delta( _vector1 ); - for (let i = 0; i < 6; i++) { - if (isDataTexture) { - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[i].width, cubeImage[i].height, glFormat, glType, cubeImage[i].data); - } else { - state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[i].width, cubeImage[i].height, 0, glFormat, glType, cubeImage[i].data); - } + const denominator = this.normal.dot( direction ); - for (let j = 0; j < mipmaps.length; j++) { - const mipmap = mipmaps[j]; - const mipmapImage = mipmap.image[i].image; + if ( denominator === 0 ) { - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data); - } else { - state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data); - } - } - } else { - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i]); - } else { - state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]); - } + // line is coplanar, return origin + if ( this.distanceToPoint( line.start ) === 0 ) { - for (let j = 0; j < mipmaps.length; j++) { - const mipmap = mipmaps[j]; + return target.copy( line.start ); - if (useTexStorage) { - state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]); - } else { - state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]); - } - } - } - } } - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { - // We assume images for cube map have the same size. - generateMipmap(_gl.TEXTURE_CUBE_MAP); - } + // Unsure if this is the correct method to handle this case. + return null; - source.__currentVersion = 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 + const t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; + if ( t < 0 || t > 1 ) { - 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); + return null; - 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); - } else { - state.texImage2D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null); - } } - state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); + return target.copy( direction ).multiplyScalar( t ).add( line.start ); - if (useMultisampledRTT(renderTarget)) { - multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0, getRenderTargetSamples(renderTarget)); - } else { - _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 + intersectsLine( line ) { + // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. - function setupRenderBufferStorage(renderbuffer, renderTarget, isMultisample) { - _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer); + const startSign = this.distanceToPoint( line.start ); + const endSign = this.distanceToPoint( line.end ); - if (renderTarget.depthBuffer && !renderTarget.stencilBuffer) { - let glInternalFormat = _gl.DEPTH_COMPONENT16; + return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); - if (isMultisample || useMultisampledRTT(renderTarget)) { - const depthTexture = renderTarget.depthTexture; + } - if (depthTexture && depthTexture.isDepthTexture) { - if (depthTexture.type === FloatType) { - glInternalFormat = _gl.DEPTH_COMPONENT32F; - } else if (depthTexture.type === UnsignedIntType) { - glInternalFormat = _gl.DEPTH_COMPONENT24; - } - } + intersectsBox( box ) { - const samples = getRenderTargetSamples(renderTarget); + return box.intersectsPlane( this ); - if (useMultisampledRTT(renderTarget)) { - multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); - } else { - _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); - } - } 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); + intersectsSphere( sphere ) { - if (isMultisample && useMultisampledRTT(renderTarget) === false) { - _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height); - } else if (useMultisampledRTT(renderTarget)) { - multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height); - } else { - _gl.renderbufferStorage(_gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height); - } + return sphere.intersectsPlane( this ); - _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)) { - multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); - } else { - _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height); - } - } - } + } - _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); - } // Setup resources for a Depth Texture for a FBO (needs an extension) + coplanarPoint( target ) { + return target.copy( this.normal ).multiplyScalar( - this.constant ); - 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 + applyMatrix4( matrix, optionalNormalMatrix ) { + const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix ); - 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; - } + const referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix ); - setTexture2D(renderTarget.depthTexture, 0); + const normal = this.normal.applyMatrix3( normalMatrix ).normalize(); - const webglDepthTexture = properties.get(renderTarget.depthTexture).__webglTexture; + this.constant = - referencePoint.dot( normal ); - const samples = getRenderTargetSamples(renderTarget); + return this; - if (renderTarget.depthTexture.format === DepthFormat) { - if (useMultisampledRTT(renderTarget)) { - multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples); - } else { - _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0); - } - } else if (renderTarget.depthTexture.format === DepthStencilFormat) { - if (useMultisampledRTT(renderTarget)) { - multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples); - } else { - _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0); - } - } else { - throw new Error('Unknown depthTexture format'); - } - } // Setup GL resources for a non-texture depth buffer + } + translate( offset ) { - function setupDepthRenderbuffer(renderTarget) { - const renderTargetProperties = properties.get(renderTarget); - const isCube = renderTarget.isWebGLCubeRenderTarget === true; + this.constant -= offset.dot( this.normal ); - 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 = []; + return this; - for (let i = 0; i < 6; i++) { - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[i]); - renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer(); - setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer[i], renderTarget, false); - } - } else { - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); - renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); - setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false); - } - } + } - state.bindFramebuffer(_gl.FRAMEBUFFER, null); - } // rebind framebuffer with external textures + equals( plane ) { + return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); - 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); - } + clone() { - if (depthTexture !== undefined) { - setupDepthRenderbuffer(renderTarget); - } - } // Set up GL resources for the render target + return new this.constructor().copy( this ); + } - 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(); - } + const _sphere$2 = /*@__PURE__*/ new Sphere(); + const _vector$7 = /*@__PURE__*/ new Vector3(); - textureProperties.__version = texture.version; - info.memory.textures++; - } + class Frustum { - const isCube = renderTarget.isWebGLCubeRenderTarget === true; - const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true; - const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; // Setup framebuffer + constructor( p0 = new Plane(), p1 = new Plane(), p2 = new Plane(), p3 = new Plane(), p4 = new Plane(), p5 = new Plane() ) { - if (isCube) { - renderTargetProperties.__webglFramebuffer = []; + this.planes = [ p0, p1, p2, p3, p4, p5 ]; - 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; + set( p0, p1, p2, p3, p4, p5 ) { - for (let i = 0, il = textures.length; i < il; i++) { - const attachmentProperties = properties.get(textures[i]); + const planes = this.planes; - if (attachmentProperties.__webglTexture === undefined) { - attachmentProperties.__webglTexture = _gl.createTexture(); - info.memory.textures++; - } - } - } else { - console.warn('THREE.WebGLRenderer: WebGLMultipleRenderTargets can only be used with WebGL2 or WEBGL_draw_buffers extension.'); - } - } + planes[ 0 ].copy( p0 ); + planes[ 1 ].copy( p1 ); + planes[ 2 ].copy( p2 ); + planes[ 3 ].copy( p3 ); + planes[ 4 ].copy( p4 ); + planes[ 5 ].copy( p5 ); - 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); + return this; - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - renderTargetProperties.__webglColorRenderbuffer[i] = _gl.createRenderbuffer(); + } - _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); + copy( frustum ) { - 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); + const planes = this.planes; - _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); + for ( let i = 0; i < 6; i ++ ) { - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); - } + planes[ i ].copy( frustum.planes[ i ] ); - _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); + } - if (renderTarget.depthBuffer) { - renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer(); - setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true); - } + return this; - state.bindFramebuffer(_gl.FRAMEBUFFER, null); - } - } // Setup color buffer + } + setFromProjectionMatrix( m ) { + + const planes = this.planes; + const me = m.elements; + const me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ]; + const me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ]; + const me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ]; + const me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ]; - if (isCube) { - state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); - setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture, supportsMips); + planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize(); + planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize(); + planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize(); + planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize(); + planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize(); + planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize(); - for (let i = 0; i < 6; i++) { - setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i], renderTarget, texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i); - } + return this; - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { - generateMipmap(_gl.TEXTURE_CUBE_MAP); - } + } - state.unbindTexture(); - } else if (isMultipleRenderTargets) { - const textures = renderTarget.texture; + intersectsObject( object ) { - 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); + const geometry = object.geometry; - if (textureNeedsGenerateMipmaps(attachment, supportsMips)) { - generateMipmap(_gl.TEXTURE_2D); - } - } + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - state.unbindTexture(); - } else { - let glTextureType = _gl.TEXTURE_2D; + _sphere$2.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld ); - if (renderTarget.isWebGL3DRenderTarget || renderTarget.isWebGLArrayRenderTarget) { - if (isWebGL2) { - glTextureType = renderTarget.isWebGL3DRenderTarget ? _gl.TEXTURE_3D : _gl.TEXTURE_2D_ARRAY; - } else { - console.error('THREE.WebGLTextures: THREE.Data3DTexture and THREE.DataArrayTexture only supported with WebGL2.'); - } - } + return this.intersectsSphere( _sphere$2 ); - state.bindTexture(glTextureType, textureProperties.__webglTexture); - setTextureParameters(glTextureType, texture, supportsMips); - setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, texture, _gl.COLOR_ATTACHMENT0, glTextureType); + } - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { - generateMipmap(glTextureType); - } + intersectsSprite( sprite ) { - state.unbindTexture(); - } // Setup depth and stencil buffers + _sphere$2.center.set( 0, 0, 0 ); + _sphere$2.radius = 0.7071067811865476; + _sphere$2.applyMatrix4( sprite.matrixWorld ); + return this.intersectsSphere( _sphere$2 ); - if (renderTarget.depthBuffer) { - setupDepthRenderbuffer(renderTarget); - } } - function updateRenderTargetMipmap(renderTarget) { - const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; - const textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [renderTarget.texture]; + intersectsSphere( sphere ) { - for (let i = 0, il = textures.length; i < il; i++) { - const texture = textures[i]; + const planes = this.planes; + const center = sphere.center; + const negRadius = - sphere.radius; - if (textureNeedsGenerateMipmaps(texture, supportsMips)) { - const target = renderTarget.isWebGLCubeRenderTarget ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D; + for ( let i = 0; i < 6; i ++ ) { - const webglTexture = properties.get(texture).__webglTexture; + const distance = planes[ i ].distanceToPoint( center ); - state.bindTexture(target, webglTexture); - generateMipmap(target); - state.unbindTexture(); - } - } - } + if ( distance < negRadius ) { - function updateMultisampleRenderTarget(renderTarget) { - if (isWebGL2 && renderTarget.samples > 0 && useMultisampledRTT(renderTarget) === false) { - const textures = renderTarget.isWebGLMultipleRenderTargets ? renderTarget.texture : [renderTarget.texture]; - const width = renderTarget.width; - const height = renderTarget.height; - let mask = _gl.COLOR_BUFFER_BIT; - 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 + return false; - 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); + return true; - _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); + intersectsBox( box ) { - for (let i = 0; i < textures.length; i++) { - invalidationArray.push(_gl.COLOR_ATTACHMENT0 + i); + const planes = this.planes; - if (renderTarget.depthBuffer) { - invalidationArray.push(depthStyle); - } + for ( let i = 0; i < 6; i ++ ) { - const ignoreDepthValues = renderTargetProperties.__ignoreDepthValues !== undefined ? renderTargetProperties.__ignoreDepthValues : false; + const plane = planes[ i ]; - if (ignoreDepthValues === false) { - if (renderTarget.depthBuffer) mask |= _gl.DEPTH_BUFFER_BIT; - if (renderTarget.stencilBuffer) mask |= _gl.STENCIL_BUFFER_BIT; - } + // corner at max distance - if (isMultipleRenderTargets) { - _gl.framebufferRenderbuffer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); - } + _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 (ignoreDepthValues === true) { - _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, [depthStyle]); + if ( plane.distanceToPoint( _vector$7 ) < 0 ) { - _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, [depthStyle]); - } + return false; - 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); + return true; - 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 + containsPoint( point ) { - if (isMultipleRenderTargets) { - for (let i = 0; i < textures.length; i++) { - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); + const planes = this.planes; - _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); + for ( let i = 0; i < 6; i ++ ) { - const webglTexture = properties.get(textures[i]).__webglTexture; + if ( planes[ i ].distanceToPoint( point ) < 0 ) { - state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); + return false; - _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); - } + return true; - 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 + clone() { - if (_videoTextures.get(texture) !== frame) { - _videoTextures.set(texture, frame); + return new this.constructor().copy( this ); - 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 + function WebGLAnimation() { - 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.'); - } - } - } else { - console.error('THREE.WebGLTextures: Unsupported texture encoding:', encoding); - } - } + let context = null; + let isAnimating = false; + let animationLoop = null; + let requestId = null; - return image; - } // + function onAnimationFrame( time, frame ) { + animationLoop( time, frame ); - this.allocateTextureUnit = allocateTextureUnit; - this.resetTextureUnits = resetTextureUnits; - this.setTexture2D = setTexture2D; - this.setTexture2DArray = setTexture2DArray; - this.setTexture3D = setTexture3D; - this.setTextureCube = setTextureCube; - this.rebindTextures = rebindTextures; - this.setupRenderTarget = setupRenderTarget; - this.updateRenderTargetMipmap = updateRenderTargetMipmap; - this.updateMultisampleRenderTarget = updateMultisampleRenderTarget; - this.setupDepthRenderbuffer = setupDepthRenderbuffer; - this.setupFrameBufferTexture = setupFrameBufferTexture; - this.useMultisampledRTT = useMultisampledRTT; - } + requestId = context.requestAnimationFrame( onAnimationFrame ); - function WebGLUtils(gl, extensions, capabilities) { - const isWebGL2 = capabilities.isWebGL2; + } - function convert(p, encoding = null) { - let extension; - if (p === UnsignedByteType) return gl.UNSIGNED_BYTE; - if (p === UnsignedShort4444Type) return gl.UNSIGNED_SHORT_4_4_4_4; - if (p === UnsignedShort5551Type) return gl.UNSIGNED_SHORT_5_5_5_1; - if (p === ByteType) return gl.BYTE; - if (p === ShortType) return gl.SHORT; - if (p === UnsignedShortType) return gl.UNSIGNED_SHORT; - 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; - } - } + return { - 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; + start: function () { - 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 + if ( isAnimating === true ) return; + if ( animationLoop === null ) return; + requestId = context.requestAnimationFrame( onAnimationFrame ); - if (p === _SRGBAFormat) { - extension = extensions.get('EXT_sRGB'); + isAnimating = true; - if (extension !== null) { - return extension.SRGB_ALPHA_EXT; - } else { - return null; - } - } // WebGL2 formats. + }, + stop: function () { - 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 + context.cancelAnimationFrame( requestId ); - 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'); + isAnimating = false; - 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; - if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; - if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; - } else { - return null; - } - } 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; - if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; - if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; - } else { - return null; - } - } - } // PVRTC + setAnimationLoop: function ( callback ) { + animationLoop = callback; - if (p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format) { - extension = extensions.get('WEBGL_compressed_texture_pvrtc'); + }, - if (extension !== null) { - if (p === RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; - if (p === RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; - if (p === RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; - if (p === RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; - } else { - return null; - } - } // ETC1 + setContext: function ( value ) { + context = value; - 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 + }; + } - if (p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format) { - extension = extensions.get('WEBGL_compressed_texture_etc'); + function WebGLAttributes( gl, capabilities ) { - 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 - - - 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; - if (p === RGBA_ASTC_5x5_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR; - if (p === RGBA_ASTC_6x5_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR; - if (p === RGBA_ASTC_6x6_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR; - if (p === RGBA_ASTC_8x5_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR; - if (p === RGBA_ASTC_8x6_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR; - if (p === RGBA_ASTC_8x8_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR; - if (p === RGBA_ASTC_10x5_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR; - if (p === RGBA_ASTC_10x6_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR; - if (p === RGBA_ASTC_10x8_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR; - if (p === RGBA_ASTC_10x10_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR; - if (p === RGBA_ASTC_12x10_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR; - if (p === RGBA_ASTC_12x12_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR; - } else { - return null; - } - } // BPTC + const isWebGL2 = capabilities.isWebGL2; + const buffers = new WeakMap(); - if (p === RGBA_BPTC_Format) { - extension = extensions.get('EXT_texture_compression_bptc'); + function createBuffer( attribute, bufferType ) { - 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; - } - } // + const array = attribute.array; + const usage = attribute.usage; + const buffer = gl.createBuffer(); - if (p === UnsignedInt248Type) { - if (isWebGL2) return gl.UNSIGNED_INT_24_8; - extension = extensions.get('WEBGL_depth_texture'); + gl.bindBuffer( bufferType, buffer ); + gl.bufferData( bufferType, array, usage ); - 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) + attribute.onUploadCallback(); + let type; - return gl[p] !== undefined ? gl[p] : null; - } + if ( array instanceof Float32Array ) { - return { - convert: convert - }; - } + type = gl.FLOAT; - class ArrayCamera extends PerspectiveCamera { - constructor(array = []) { - super(); - this.isArrayCamera = true; - this.cameras = array; - } + } else if ( array instanceof Uint16Array ) { - } + if ( attribute.isFloat16BufferAttribute ) { - class Group extends Object3D { - constructor() { - super(); - this.isGroup = true; - this.type = 'Group'; - } + if ( isWebGL2 ) { - } + type = gl.HALF_FLOAT; - const _moveEvent = { - type: 'move' - }; + } else { - class WebXRController { - constructor() { - this._targetRay = null; - this._grip = null; - this._hand = null; - } + throw new Error( 'THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2.' ); - getHandSpace() { - if (this._hand === null) { - this._hand = new Group(); - this._hand.matrixAutoUpdate = false; - this._hand.visible = false; - this._hand.joints = {}; - this._hand.inputState = { - pinching: false - }; - } + } - return this._hand; - } + } else { - getTargetRaySpace() { - if (this._targetRay === null) { - this._targetRay = new Group(); - this._targetRay.matrixAutoUpdate = false; - this._targetRay.visible = false; - this._targetRay.hasLinearVelocity = false; - this._targetRay.linearVelocity = new Vector3(); - this._targetRay.hasAngularVelocity = false; - this._targetRay.angularVelocity = new Vector3(); - } + type = gl.UNSIGNED_SHORT; - return this._targetRay; - } + } - getGripSpace() { - if (this._grip === null) { - this._grip = new Group(); - this._grip.matrixAutoUpdate = false; - this._grip.visible = false; - this._grip.hasLinearVelocity = false; - this._grip.linearVelocity = new Vector3(); - this._grip.hasAngularVelocity = false; - this._grip.angularVelocity = new Vector3(); - } + } else if ( array instanceof Int16Array ) { - return this._grip; - } + type = gl.SHORT; - dispatchEvent(event) { - if (this._targetRay !== null) { - this._targetRay.dispatchEvent(event); - } + } else if ( array instanceof Uint32Array ) { - if (this._grip !== null) { - this._grip.dispatchEvent(event); - } + type = gl.UNSIGNED_INT; - if (this._hand !== null) { - this._hand.dispatchEvent(event); - } + } else if ( array instanceof Int32Array ) { - return this; - } + type = gl.INT; - disconnect(inputSource) { - this.dispatchEvent({ - type: 'disconnected', - data: inputSource - }); + } else if ( array instanceof Int8Array ) { - if (this._targetRay !== null) { - this._targetRay.visible = false; - } + type = gl.BYTE; - if (this._grip !== null) { - this._grip.visible = false; - } + } else if ( array instanceof Uint8Array ) { - if (this._hand !== null) { - this._hand.visible = false; - } + type = gl.UNSIGNED_BYTE; - return this; - } + } else if ( array instanceof Uint8ClampedArray ) { - update(inputSource, frame, referenceSpace) { - let inputPose = null; - let gripPose = null; - let handPose = null; - const targetRay = this._targetRay; - const grip = this._grip; - const hand = this._hand; + type = gl.UNSIGNED_BYTE; - if (inputSource && frame.session.visibilityState !== 'visible-blurred') { - if (targetRay !== null) { - inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace); + } else { - if (inputPose !== null) { - targetRay.matrix.fromArray(inputPose.transform.matrix); - targetRay.matrix.decompose(targetRay.position, targetRay.rotation, targetRay.scale); + throw new Error( 'THREE.WebGLAttributes: Unsupported buffer data format: ' + array ); - 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; - } + return { + buffer: buffer, + type: type, + bytesPerElement: array.BYTES_PER_ELEMENT, + version: attribute.version + }; - this.dispatchEvent(_moveEvent); - } - } + } - if (hand && inputSource.hand) { - handPose = true; + function updateBuffer( buffer, attribute, bufferType ) { - for (const inputjoint of inputSource.hand.values()) { - // Update the joints groups with the XRJoint poses - const jointPose = frame.getJointPose(inputjoint, referenceSpace); + const array = attribute.array; + const updateRange = attribute.updateRange; - 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; // ?? + gl.bindBuffer( bufferType, buffer ); - hand.add(joint); - } + if ( updateRange.count === - 1 ) { - const joint = hand.joints[inputjoint.jointName]; + // Not using update ranges - if (jointPose !== null) { - joint.matrix.fromArray(jointPose.transform.matrix); - joint.matrix.decompose(joint.position, joint.rotation, joint.scale); - joint.jointRadius = jointPose.radius; - } + gl.bufferSubData( bufferType, 0, array ); - joint.visible = jointPose !== null; - } // Custom events - // Check pinchz + } else { + if ( isWebGL2 ) { - 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; + gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, + array, updateRange.offset, updateRange.count ); - if (hand.inputState.pinching && distance > distanceToPinch + threshold) { - hand.inputState.pinching = false; - this.dispatchEvent({ - type: 'pinchend', - handedness: inputSource.handedness, - target: this - }); - } else if (!hand.inputState.pinching && distance <= distanceToPinch - threshold) { - hand.inputState.pinching = true; - this.dispatchEvent({ - type: 'pinchstart', - handedness: inputSource.handedness, - target: this - }); - } } else { - if (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; - } + gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, + array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); - if (gripPose.angularVelocity) { - grip.hasAngularVelocity = true; - grip.angularVelocity.copy(gripPose.angularVelocity); - } else { - grip.hasAngularVelocity = false; - } - } - } } - } - if (targetRay !== null) { - targetRay.visible = inputPose !== null; - } + updateRange.count = - 1; // reset range - if (grip !== null) { - grip.visible = gripPose !== null; } - if (hand !== null) { - hand.visible = handPose !== null; - } + attribute.onUploadCallback(); - return this; } - } + // - class DepthTexture extends Texture { - constructor(width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format) { - format = format !== undefined ? format : DepthFormat; + function get( attribute ) { - if (format !== DepthFormat && format !== DepthStencilFormat) { - throw new Error('DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat'); - } + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + + return buffers.get( attribute ); - if (type === undefined && format === DepthFormat) type = UnsignedIntType; - if (type === undefined && format === DepthStencilFormat) type = UnsignedInt248Type; - super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); - this.isDepthTexture = true; - this.image = { - width: width, - height: height - }; - this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; - this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; - this.flipY = false; - this.generateMipmaps = false; } - } + function remove( attribute ) { - class WebXRManager extends EventDispatcher { - constructor(renderer, gl) { - super(); - const scope = this; - let session = null; - let framebufferScaleFactor = 1.0; - let referenceSpace = null; - let referenceSpaceType = 'local-floor'; - let customReferenceSpace = null; - let pose = null; - let glBinding = null; - let glProjLayer = null; - let glBaseLayer = null; - let xrFrame = null; - const attributes = gl.getContextAttributes(); - let initialRenderTarget = null; - let newRenderTarget = null; - const controllers = []; - const inputSourcesMap = new Map(); // + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; - const cameraL = new PerspectiveCamera(); - cameraL.layers.enable(1); - cameraL.viewport = new Vector4(); - const cameraR = new PerspectiveCamera(); - cameraR.layers.enable(2); - cameraR.viewport = new Vector4(); - const cameras = [cameraL, cameraR]; - const cameraVR = new ArrayCamera(); - cameraVR.layers.enable(1); - cameraVR.layers.enable(2); - let _currentDepthNear = null; - let _currentDepthFar = null; // + const data = buffers.get( attribute ); - this.cameraAutoUpdate = true; - this.enabled = false; - this.isPresenting = false; + if ( data ) { - this.getController = function (index) { - let controller = controllers[index]; + gl.deleteBuffer( data.buffer ); - if (controller === undefined) { - controller = new WebXRController(); - controllers[index] = controller; - } + buffers.delete( attribute ); - return controller.getTargetRaySpace(); - }; + } - this.getControllerGrip = function (index) { - let controller = controllers[index]; + } - if (controller === undefined) { - controller = new WebXRController(); - controllers[index] = controller; - } + function update( attribute, bufferType ) { - return controller.getGripSpace(); - }; + if ( attribute.isGLBufferAttribute ) { - this.getHand = function (index) { - let controller = controllers[index]; + const cached = buffers.get( attribute ); - if (controller === undefined) { - controller = new WebXRController(); - controllers[index] = controller; - } + if ( ! cached || cached.version < attribute.version ) { - return controller.getHandSpace(); - }; // + buffers.set( attribute, { + buffer: attribute.buffer, + type: attribute.type, + bytesPerElement: attribute.elementSize, + version: attribute.version + } ); + } - function onSessionEvent(event) { - const controller = inputSourcesMap.get(event.inputSource); + return; - if (controller !== undefined) { - controller.dispatchEvent({ - type: event.type, - data: event.inputSource - }); - } } - function onSessionEnd() { - session.removeEventListener('select', onSessionEvent); - session.removeEventListener('selectstart', onSessionEvent); - session.removeEventListener('selectend', onSessionEvent); - session.removeEventListener('squeeze', onSessionEvent); - session.removeEventListener('squeezestart', onSessionEvent); - session.removeEventListener('squeezeend', onSessionEvent); - session.removeEventListener('end', onSessionEnd); - session.removeEventListener('inputsourceschange', onInputSourcesChange); - inputSourcesMap.forEach(function (controller, inputSource) { - if (controller !== undefined) { - controller.disconnect(inputSource); - } - }); - inputSourcesMap.clear(); - _currentDepthNear = null; - _currentDepthFar = null; // restore framebuffer/rendering state + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; - renderer.setRenderTarget(initialRenderTarget); - glBaseLayer = null; - glProjLayer = null; - glBinding = null; - session = null; - newRenderTarget = null; // + const data = buffers.get( attribute ); - animation.stop(); - scope.isPresenting = false; - scope.dispatchEvent({ - type: 'sessionend' - }); - } + if ( data === undefined ) { - this.setFramebufferScaleFactor = function (value) { - framebufferScaleFactor = value; + buffers.set( attribute, createBuffer( attribute, bufferType ) ); - if (scope.isPresenting === true) { - console.warn('THREE.WebXRManager: Cannot change framebuffer scale while presenting.'); - } - }; + } else if ( data.version < attribute.version ) { - this.setReferenceSpaceType = function (value) { - referenceSpaceType = value; + updateBuffer( data.buffer, attribute, bufferType ); - if (scope.isPresenting === true) { - console.warn('THREE.WebXRManager: Cannot change reference space type while presenting.'); - } - }; + data.version = attribute.version; - 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; - }; + return { - this.getSession = function () { - return session; - }; + get: get, + remove: remove, + update: update - this.setSession = async function (value) { - session = value; + }; - if (session !== null) { - initialRenderTarget = renderer.getRenderTarget(); - session.addEventListener('select', onSessionEvent); - session.addEventListener('selectstart', onSessionEvent); - session.addEventListener('selectend', onSessionEvent); - session.addEventListener('squeeze', onSessionEvent); - session.addEventListener('squeezestart', onSessionEvent); - session.addEventListener('squeezeend', onSessionEvent); - session.addEventListener('end', onSessionEnd); - 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, - alpha: attributes.alpha, - depth: attributes.depth, - stencil: attributes.stencil, - framebufferScaleFactor: framebufferScaleFactor - }; - glBaseLayer = new XRWebGLLayer(session, gl, layerInit); - session.updateRenderState({ - baseLayer: glBaseLayer - }); - newRenderTarget = new WebGLRenderTarget(glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, { - format: RGBAFormat, - type: UnsignedByteType, - encoding: renderer.outputEncoding - }); - } else { - let depthFormat = null; - let depthType = null; - let glDepthFormat = null; + class PlaneGeometry extends BufferGeometry { - if (attributes.depth) { - glDepthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24; - depthFormat = attributes.stencil ? DepthStencilFormat : DepthFormat; - depthType = attributes.stencil ? UnsignedInt248Type : UnsignedIntType; - } + constructor( width = 1, height = 1, widthSegments = 1, heightSegments = 1 ) { - const projectionlayerInit = { - colorFormat: renderer.outputEncoding === sRGBEncoding ? gl.SRGB8_ALPHA8 : gl.RGBA8, - depthFormat: glDepthFormat, - scaleFactor: framebufferScaleFactor - }; - glBinding = new XRWebGLBinding(session, gl); - glProjLayer = glBinding.createProjectionLayer(projectionlayerInit); - session.updateRenderState({ - layers: [glProjLayer] - }); - newRenderTarget = new WebGLRenderTarget(glProjLayer.textureWidth, glProjLayer.textureHeight, { - format: RGBAFormat, - type: UnsignedByteType, - depthTexture: new DepthTexture(glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat), - stencilBuffer: attributes.stencil, - encoding: renderer.outputEncoding, - samples: attributes.antialias ? 4 : 0 - }); - const renderTargetProperties = renderer.properties.get(newRenderTarget); - renderTargetProperties.__ignoreDepthValues = glProjLayer.ignoreDepthValues; - } + super(); - newRenderTarget.isXRRenderTarget = true; // TODO Remove this when possible, see #23278 - // Set foveation to maximum. + this.type = 'PlaneGeometry'; - this.setFoveation(1.0); - customReferenceSpace = null; - referenceSpace = await session.requestReferenceSpace(referenceSpaceType); - animation.setContext(session); - animation.start(); - scope.isPresenting = true; - scope.dispatchEvent({ - type: 'sessionstart' - }); - } + this.parameters = { + width: width, + height: height, + widthSegments: widthSegments, + heightSegments: heightSegments }; - function onInputSourcesChange(event) { - const inputSources = session.inputSources; // Assign controllers to available inputSources + const width_half = width / 2; + const height_half = height / 2; - for (let i = 0; i < inputSources.length; i++) { - const index = inputSources[i].handedness === 'right' ? 1 : 0; - inputSourcesMap.set(inputSources[i], controllers[index]); - } // Notify disconnected + const gridX = Math.floor( widthSegments ); + const gridY = Math.floor( heightSegments ); + const gridX1 = gridX + 1; + const gridY1 = gridY + 1; - for (let i = 0; i < event.removed.length; i++) { - const inputSource = event.removed[i]; - const controller = inputSourcesMap.get(inputSource); + const segment_width = width / gridX; + const segment_height = height / gridY; - if (controller) { - controller.dispatchEvent({ - type: 'disconnected', - data: inputSource - }); - inputSourcesMap.delete(inputSource); - } - } // Notify connected + // + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; - for (let i = 0; i < event.added.length; i++) { - const inputSource = event.added[i]; - const controller = inputSourcesMap.get(inputSource); + for ( let iy = 0; iy < gridY1; iy ++ ) { - if (controller) { - controller.dispatchEvent({ - type: 'connected', - data: inputSource - }); - } - } - } // + const y = iy * segment_height - height_half; + for ( let ix = 0; ix < gridX1; ix ++ ) { - 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 - */ + const x = ix * segment_width - width_half; - 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 - // most likely identical top and bottom frustum extents. - // Use the left camera for these values. + vertices.push( x, - y, 0 ); - const near = projL[14] / (projL[10] - 1); - const far = projL[14] / (projL[10] + 1); - const topFov = (projL[9] + 1) / projL[5]; - const bottomFov = (projL[9] - 1) / projL[5]; - 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`. + normals.push( 0, 0, 1 ); - const zOffset = ipd / (-leftFov + rightFov); - const xOffset = zOffset * -leftFov; // TODO: Better way to apply this offset? + uvs.push( ix / gridX ); + uvs.push( 1 - ( iy / gridY ) ); - 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 - // 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; - const right2 = right + (ipd - xOffset); - const top2 = topFov * far / far2 * near2; - 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); + for ( let iy = 0; iy < gridY; iy ++ ) { + + for ( let ix = 0; ix < gridX; ix ++ ) { + + const a = ix + gridX1 * iy; + const b = ix + gridX1 * ( iy + 1 ); + const c = ( ix + 1 ) + gridX1 * ( iy + 1 ); + const d = ( ix + 1 ) + gridX1 * iy; + + indices.push( a, b, d ); + indices.push( b, c, d ); + } - 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; + this.setIndex( indices ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - if (_currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far) { - // Note that the new renderState won't apply until the next frame. See #18320 - session.updateRenderState({ - depthNear: cameraVR.near, - depthFar: cameraVR.far - }); - _currentDepthNear = cameraVR.near; - _currentDepthFar = cameraVR.far; - } + } - const parent = camera.parent; - const cameras = cameraVR.cameras; - updateCamera(cameraVR, parent); + static fromJSON( data ) { - for (let i = 0; i < cameras.length; i++) { - updateCamera(cameras[i], parent); - } + return new PlaneGeometry( data.width, data.height, data.widthSegments, data.heightSegments ); - cameraVR.matrixWorld.decompose(cameraVR.position, cameraVR.quaternion, cameraVR.scale); // 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); - 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 + var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; + var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; - if (cameras.length === 2) { - setProjectionFromUnion(cameraVR, cameraL, cameraR); - } else { - // assume single camera setup (AR) - cameraVR.projectionMatrix.copy(cameraL.projectionMatrix); - } - }; + var alphatest_fragment = "#ifdef USE_ALPHATEST\n\tif ( diffuseColor.a < alphaTest ) discard;\n#endif"; - this.getCamera = function () { - return cameraVR; - }; + var alphatest_pars_fragment = "#ifdef USE_ALPHATEST\n\tuniform float alphaTest;\n#endif"; - this.getFoveation = function () { - if (glProjLayer !== null) { - return glProjLayer.fixedFoveation; - } + var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\t#endif\n#endif"; - if (glBaseLayer !== null) { - return glBaseLayer.fixedFoveation; - } + var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; - return undefined; - }; + var begin_vertex = "vec3 transformed = vec3( position );"; - this.setFoveation = function (foveation) { - // 0 = no foveation = full resolution - // 1 = maximum foveation = the edges render at lower resolution - if (glProjLayer !== null) { - glProjLayer.fixedFoveation = foveation; - } + var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; - if (glBaseLayer !== null && glBaseLayer.fixedFoveation !== undefined) { - glBaseLayer.fixedFoveation = foveation; - } - }; // Animation Loop + var bsdfs = "vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\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 dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( V * D );\n}\n#ifdef USE_IRIDESCENCE\n\tvec3 BRDF_GGX_Iridescence( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float iridescence, const in vec3 iridescenceFresnel, const in float roughness ) {\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = mix( F_Schlick( f0, f90, dotVH ), iridescenceFresnel, iridescence );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\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"; + var iridescence_fragment = "#ifdef USE_IRIDESCENCE\n\tconst mat3 XYZ_TO_REC709 = mat3(\n\t\t 3.2404542, -0.9692660, 0.0556434,\n\t\t-1.5371385, 1.8760108, -0.2040259,\n\t\t-0.4985314, 0.0415560, 1.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"; - let onAnimationFrameCallback = null; + var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, 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"; - function onAnimationFrame(time, frame) { - pose = frame.getViewerPose(customReferenceSpace || referenceSpace); - xrFrame = frame; + var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; - if (pose !== null) { - const views = pose.views; + var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; - if (glBaseLayer !== null) { - renderer.setRenderTargetFramebuffer(newRenderTarget, glBaseLayer.framebuffer); - renderer.setRenderTarget(newRenderTarget); - } + var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif"; - let cameraVRNeedsUpdate = false; // check if it's necessary to rebuild cameraVR's camera list + var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif"; - if (views.length !== cameraVR.cameras.length) { - cameraVR.cameras.length = 0; - cameraVRNeedsUpdate = true; - } + var color_fragment = "#if defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#elif defined( USE_COLOR )\n\tdiffuseColor.rgb *= vColor;\n#endif"; - for (let i = 0; i < views.length; i++) { - const view = views[i]; - let viewport = null; + var color_pars_fragment = "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR )\n\tvarying vec3 vColor;\n#endif"; - 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. + var 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"; - if (i === 0) { - renderer.setRenderTargetTextures(newRenderTarget, glSubImage.colorTexture, glProjLayer.ignoreDepthValues ? undefined : glSubImage.depthStencilTexture); - renderer.setRenderTarget(newRenderTarget); - } - } + var 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"; - let camera = cameras[i]; + 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}"; - if (camera === undefined) { - camera = new PerspectiveCamera(); - camera.layers.enable(i); - camera.viewport = new Vector4(); - cameras[i] = camera; - } + 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\thighp vec2 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"; - camera.matrix.fromArray(view.transform.matrix); - camera.projectionMatrix.fromArray(view.projectionMatrix); - camera.viewport.set(viewport.x, viewport.y, viewport.width, viewport.height); + 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"; - if (i === 0) { - cameraVR.matrix.copy(camera.matrix); - } + var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif"; - if (cameraVRNeedsUpdate === true) { - cameraVR.cameras.push(camera); - } - } - } // + var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif"; + var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; - const inputSources = session.inputSources; + var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif"; - for (let i = 0; i < controllers.length; i++) { - const inputSource = inputSources[i]; - const controller = inputSourcesMap.get(inputSource); + var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; - if (controller !== undefined) { - controller.update(inputSource, frame, customReferenceSpace || referenceSpace); - } - } + 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}"; - if (onAnimationFrameCallback) onAnimationFrameCallback(time, frame); - xrFrame = null; - } + 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"; - const animation = new WebGLAnimation(); - animation.setAnimationLoop(onAnimationFrame); + 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"; - this.setAnimationLoop = function (callback) { - onAnimationFrameCallback = callback; - }; + 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"; - this.dispose = function () {}; - } + 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"; - function WebGLMaterials(renderer, properties) { - function refreshFogUniforms(uniforms, fog) { - uniforms.fogColor.value.copy(fog.color); + var fog_vertex = "#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif"; - if (fog.isFog) { - uniforms.fogNear.value = fog.near; - uniforms.fogFar.value = fog.far; - } else if (fog.isFogExp2) { - uniforms.fogDensity.value = fog.density; - } - } + var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif"; - function refreshMaterialUniforms(uniforms, material, pixelRatio, height, transmissionRenderTarget) { - if (material.isMeshBasicMaterial) { - refreshUniformsCommon(uniforms, material); - } else if (material.isMeshLambertMaterial) { - refreshUniformsCommon(uniforms, material); - } else if (material.isMeshToonMaterial) { - refreshUniformsCommon(uniforms, material); - refreshUniformsToon(uniforms, material); - } else if (material.isMeshPhongMaterial) { - refreshUniformsCommon(uniforms, material); - refreshUniformsPhong(uniforms, material); - } else if (material.isMeshStandardMaterial) { - refreshUniformsCommon(uniforms, material); - refreshUniformsStandard(uniforms, material); - - if (material.isMeshPhysicalMaterial) { - refreshUniformsPhysical(uniforms, material, transmissionRenderTarget); - } - } else if (material.isMeshMatcapMaterial) { - refreshUniformsCommon(uniforms, material); - refreshUniformsMatcap(uniforms, material); - } else if (material.isMeshDepthMaterial) { - refreshUniformsCommon(uniforms, material); - } else if (material.isMeshDistanceMaterial) { - refreshUniformsCommon(uniforms, material); - refreshUniformsDistance(uniforms, material); - } else if (material.isMeshNormalMaterial) { - refreshUniformsCommon(uniforms, material); - } else if (material.isLineBasicMaterial) { - refreshUniformsLine(uniforms, material); - - if (material.isLineDashedMaterial) { - refreshUniformsDash(uniforms, material); - } - } else if (material.isPointsMaterial) { - refreshUniformsPoints(uniforms, material, pixelRatio, height); - } else if (material.isSpriteMaterial) { - refreshUniformsSprites(uniforms, material); - } else if (material.isShadowMaterial) { - uniforms.color.value.copy(material.color); - uniforms.opacity.value = material.opacity; - } else if (material.isShaderMaterial) { - material.uniformsNeedUpdate = false; // #15581 - } - } + var 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"; - function refreshUniformsCommon(uniforms, material) { - uniforms.opacity.value = material.opacity; + 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"; - if (material.color) { - uniforms.diffuse.value.copy(material.color); - } + 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}"; - if (material.emissive) { - uniforms.emissive.value.copy(material.emissive).multiplyScalar(material.emissiveIntensity); - } + var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\treflectedLight.indirectDiffuse += lightMapIrradiance;\n#endif"; - if (material.map) { - uniforms.map.value = material.map; - } + var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; - if (material.alphaMap) { - uniforms.alphaMap.value = material.alphaMap; - } + var lights_lambert_fragment = "LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;"; - if (material.bumpMap) { - uniforms.bumpMap.value = material.bumpMap; - uniforms.bumpScale.value = material.bumpScale; - if (material.side === BackSide) uniforms.bumpScale.value *= -1; - } + 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"; - if (material.displacementMap) { - uniforms.displacementMap.value = material.displacementMap; - uniforms.displacementScale.value = material.displacementScale; - uniforms.displacementBias.value = material.displacementBias; - } + 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"; - if (material.emissiveMap) { - uniforms.emissiveMap.value = material.emissiveMap; - } + var 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"; - if (material.normalMap) { - uniforms.normalMap.value = material.normalMap; - uniforms.normalScale.value.copy(material.normalScale); - if (material.side === BackSide) uniforms.normalScale.value.negate(); - } + var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;"; - if (material.specularMap) { - uniforms.specularMap.value = material.specularMap; - } + 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"; - if (material.alphaTest > 0) { - uniforms.alphaTest.value = material.alphaTest; - } + var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; - const envMap = properties.get(material).envMap; + 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"; - if (envMap) { - uniforms.envMap.value = envMap; - uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1; - uniforms.reflectivity.value = material.reflectivity; - uniforms.ior.value = material.ior; - uniforms.refractionRatio.value = material.refractionRatio; - } + 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"; - if (material.lightMap) { - uniforms.lightMap.value = material.lightMap; // artist-friendly light intensity scaling factor + 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}"; - const scaleFactor = renderer.physicallyCorrectLights !== true ? Math.PI : 1; - uniforms.lightMapIntensity.value = material.lightMapIntensity * scaleFactor; - } +<<<<<<< HEAD + let camera = cameras[i]; - if (material.aoMap) { - uniforms.aoMap.value = material.aoMap; - uniforms.aoMapIntensity.value = material.aoMapIntensity; - } // uv repeat and offset setting priorities - // 1. color map - // 2. specular map - // 3. displacementMap map - // 4. normal map - // 5. bump map - // 6. roughnessMap map - // 7. metalnessMap map - // 8. alphaMap map - // 9. emissiveMap map - // 10. clearcoat map - // 11. clearcoat normal map - // 12. clearcoat roughnessMap map - // 13. iridescence map - // 14. iridescence thickness map - // 15. specular intensity map - // 16. specular tint map - // 17. transmission map - // 18. thickness map + 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); +======= + 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 *= ( 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 *= ( 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 *= ( 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"; +>>>>>>> mrdoob-dev - let uvScaleMap; + 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"; - if (material.map) { - uvScaleMap = material.map; - } else if (material.specularMap) { - uvScaleMap = material.specularMap; - } else if (material.displacementMap) { - uvScaleMap = material.displacementMap; - } else if (material.normalMap) { - uvScaleMap = material.normalMap; - } else if (material.bumpMap) { - uvScaleMap = material.bumpMap; - } else if (material.roughnessMap) { - uvScaleMap = material.roughnessMap; - } else if (material.metalnessMap) { - uvScaleMap = material.metalnessMap; - } else if (material.alphaMap) { - uvScaleMap = material.alphaMap; - } else if (material.emissiveMap) { - uvScaleMap = material.emissiveMap; - } else if (material.clearcoatMap) { - uvScaleMap = material.clearcoatMap; - } else if (material.clearcoatNormalMap) { - uvScaleMap = material.clearcoatNormalMap; - } else if (material.clearcoatRoughnessMap) { - uvScaleMap = material.clearcoatRoughnessMap; - } else if (material.iridescenceMap) { - uvScaleMap = material.iridescenceMap; - } else if (material.iridescenceThicknessMap) { - uvScaleMap = material.iridescenceThicknessMap; - } else if (material.specularIntensityMap) { - uvScaleMap = material.specularIntensityMap; - } else if (material.specularColorMap) { - uvScaleMap = material.specularColorMap; - } else if (material.transmissionMap) { - uvScaleMap = material.transmissionMap; - } else if (material.thicknessMap) { - uvScaleMap = material.thicknessMap; - } else if (material.sheenColorMap) { - uvScaleMap = material.sheenColorMap; - } else if (material.sheenRoughnessMap) { - uvScaleMap = material.sheenRoughnessMap; - } + var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif"; - if (uvScaleMap !== undefined) { - // backwards compatibility - if (uvScaleMap.isWebGLRenderTarget) { - uvScaleMap = uvScaleMap.texture; - } + var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; - if (uvScaleMap.matrixAutoUpdate === true) { - uvScaleMap.updateMatrix(); - } + var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif"; - uniforms.uvTransform.value.copy(uvScaleMap.matrix); - } // uv repeat and offset setting priorities for uv2 - // 1. ao map - // 2. light map + var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif"; + var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif"; - let uv2ScaleMap; + var 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"; - if (material.aoMap) { - uv2ScaleMap = material.aoMap; - } else if (material.lightMap) { - uv2ScaleMap = material.lightMap; - } + var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif"; - if (uv2ScaleMap !== undefined) { - // backwards compatibility - if (uv2ScaleMap.isWebGLRenderTarget) { - uv2ScaleMap = uv2ScaleMap.texture; - } + var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n\tdiffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif"; - if (uv2ScaleMap.matrixAutoUpdate === true) { - uv2ScaleMap.updateMatrix(); - } + var map_particle_pars_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tuniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; - uniforms.uv2Transform.value.copy(uv2ScaleMap.matrix); - } - } + var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif"; - function refreshUniformsLine(uniforms, material) { - uniforms.diffuse.value.copy(material.color); - uniforms.opacity.value = material.opacity; - } + var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; - function refreshUniformsDash(uniforms, material) { - uniforms.dashSize.value = material.dashSize; - uniforms.totalSize.value = material.dashSize + material.gapSize; - uniforms.scale.value = material.scale; - } + var 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"; - 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; + var 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"; - if (material.map) { - uniforms.map.value = material.map; - } + var 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"; - if (material.alphaMap) { - uniforms.alphaMap.value = material.alphaMap; - } + 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"; - if (material.alphaTest > 0) { - uniforms.alphaTest.value = material.alphaTest; - } // uv repeat and offset setting priorities - // 1. color map - // 2. alpha map + 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"; - let uvScaleMap; + var 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"; - if (material.map) { - uvScaleMap = material.map; - } else if (material.alphaMap) { - uvScaleMap = material.alphaMap; - } + var 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"; - if (uvScaleMap !== undefined) { - if (uvScaleMap.matrixAutoUpdate === true) { - uvScaleMap.updateMatrix(); - } + var 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"; - uniforms.uvTransform.value.copy(uvScaleMap.matrix); - } - } + var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN, 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"; - function refreshUniformsSprites(uniforms, material) { - uniforms.diffuse.value.copy(material.color); - uniforms.opacity.value = material.opacity; - uniforms.rotation.value = material.rotation; + var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif"; - if (material.map) { - uniforms.map.value = material.map; - } + var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN, faceDirection );\n\t#endif\n#endif"; - if (material.alphaMap) { - uniforms.alphaMap.value = material.alphaMap; - } + var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif"; - if (material.alphaTest > 0) { - uniforms.alphaTest.value = material.alphaTest; - } // uv repeat and offset setting priorities - // 1. color map - // 2. alpha map + 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 *= material.transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );"; - let uvScaleMap; + 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}"; - if (material.map) { - uvScaleMap = material.map; - } else if (material.alphaMap) { - uvScaleMap = material.alphaMap; - } + var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; - if (uvScaleMap !== undefined) { - if (uvScaleMap.matrixAutoUpdate === true) { - uvScaleMap.updateMatrix(); - } + var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;"; - uniforms.uvTransform.value.copy(uvScaleMap.matrix); - } - } + var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; - 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 ) - } + var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif"; - function refreshUniformsToon(uniforms, material) { - if (material.gradientMap) { - uniforms.gradientMap.value = material.gradientMap; - } - } + var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; - function refreshUniformsStandard(uniforms, material) { - uniforms.roughness.value = material.roughness; - uniforms.metalness.value = material.metalness; + var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; - if (material.roughnessMap) { - uniforms.roughnessMap.value = material.roughnessMap; - } + 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\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\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"; - if (material.metalnessMap) { - uniforms.metalnessMap.value = material.metalnessMap; - } + 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"; - const envMap = properties.get(material).envMap; + var shadowmap_vertex = "#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\tvec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#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#endif"; - if (envMap) { - //uniforms.envMap.value = material.envMap; // part of uniforms common - uniforms.envMapIntensity.value = material.envMapIntensity; - } - } + 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}"; - function refreshUniformsPhysical(uniforms, material, transmissionRenderTarget) { - uniforms.ior.value = material.ior; // also part of uniforms common + 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"; - if (material.sheen > 0) { - uniforms.sheenColor.value.copy(material.sheenColor).multiplyScalar(material.sheen); - uniforms.sheenRoughness.value = material.sheenRoughness; + var 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"; - if (material.sheenColorMap) { - uniforms.sheenColorMap.value = material.sheenColorMap; - } + var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif"; - if (material.sheenRoughnessMap) { - uniforms.sheenRoughnessMap.value = material.sheenRoughnessMap; - } - } + var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif"; - if (material.clearcoat > 0) { - uniforms.clearcoat.value = material.clearcoat; - uniforms.clearcoatRoughness.value = material.clearcoatRoughness; + var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; - if (material.clearcoatMap) { - uniforms.clearcoatMap.value = material.clearcoatMap; - } + var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; - if (material.clearcoatRoughnessMap) { - uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap; - } + var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; - if (material.clearcoatNormalMap) { - uniforms.clearcoatNormalScale.value.copy(material.clearcoatNormalScale); - uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; + 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; }"; - if (material.side === BackSide) { - uniforms.clearcoatNormalScale.value.negate(); - } - } - } + 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"; - 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]; + 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"; - if (material.iridescenceMap) { - uniforms.iridescenceMap.value = material.iridescenceMap; - } + var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif"; - if (material.iridescenceThicknessMap) { - uniforms.iridescenceThicknessMap.value = material.iridescenceThicknessMap; - } - } + var uv_pars_vertex = "#ifdef USE_UV\n\t#ifdef UVS_VERTEX_ONLY\n\t\tvec2 vUv;\n\t#else\n\t\tvarying vec2 vUv;\n\t#endif\n\tuniform mat3 uvTransform;\n#endif"; - if (material.transmission > 0) { - uniforms.transmission.value = material.transmission; - uniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture; - uniforms.transmissionSamplerSize.value.set(transmissionRenderTarget.width, transmissionRenderTarget.height); + var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; - if (material.transmissionMap) { - uniforms.transmissionMap.value = material.transmissionMap; - } + var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; - uniforms.thickness.value = material.thickness; + var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif"; - if (material.thicknessMap) { - uniforms.thicknessMap.value = material.thicknessMap; - } + var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif"; - uniforms.attenuationDistance.value = material.attenuationDistance; - uniforms.attenuationColor.value.copy(material.attenuationColor); - } + 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"; - uniforms.specularIntensity.value = material.specularIntensity; - uniforms.specularColor.value.copy(material.specularColor); + 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}"; - if (material.specularIntensityMap) { - uniforms.specularIntensityMap.value = material.specularIntensityMap; - } + 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}"; - if (material.specularColorMap) { - uniforms.specularColorMap.value = material.specularColorMap; - } - } + 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}"; - function refreshUniformsMatcap(uniforms, material) { - if (material.matcap) { - uniforms.matcap.value = material.matcap; - } - } + 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}"; - function refreshUniformsDistance(uniforms, material) { - uniforms.referencePosition.value.copy(material.referencePosition); - uniforms.nearDistance.value = material.nearDistance; - uniforms.farDistance.value = material.farDistance; - } + 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}"; - return { - refreshFogUniforms: refreshFogUniforms, - refreshMaterialUniforms: refreshMaterialUniforms - }; - } + 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}"; - function createCanvasElement() { - const canvas = createElementNS('canvas'); - canvas.style.display = 'block'; - return canvas; - } + 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}"; - function WebGLRenderer(parameters = {}) { - this.isWebGLRenderer = true; + 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}"; - 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; + const vertex$d = "#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}"; - let _alpha; + const fragment$d = "#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}"; - if (_context !== null) { - _alpha = _context.getContextAttributes().alpha; - } else { - _alpha = parameters.alpha !== undefined ? parameters.alpha : false; - } + const vertex$c = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}"; - let currentRenderList = null; - 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 fragment$c = "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}"; - const renderListStack = []; - const renderStateStack = []; // public properties + const vertex$b = "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}"; - this.domElement = _canvas; // Debug configuration container + 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}"; - this.debug = { - /** - * Enables error checking and reporting when shader programs are being compiled - * @type {boolean} - */ - checkShaderErrors: true - }; // clearing + 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}"; - this.autoClear = true; - this.autoClearColor = true; - this.autoClearDepth = true; - this.autoClearStencil = true; // scene graph + 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}"; - this.sortObjects = true; // user-defined clipping + 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}"; - this.clippingPlanes = []; - this.localClippingEnabled = false; // physically based shading + 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}"; - this.outputEncoding = LinearEncoding; // physical lights + 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}"; - this.physicallyCorrectLights = false; // tone mapping + 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}"; - this.toneMapping = NoToneMapping; - this.toneMappingExposure = 1.0; // + const vertex$7 = "#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}"; - 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 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 _this = this; + 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}"; - let _isContextLost = false; // internal state cache + 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}"; - let _currentActiveCubeFace = 0; - let _currentActiveMipmapLevel = 0; - let _currentRenderTarget = null; + 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}"; - let _currentMaterialId = -1; + 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}"; - let _currentCamera = null; + const vertex$4 = "#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}"; - const _currentViewport = new Vector4(); + const fragment$4 = "#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}"; - const _currentScissor = new Vector4(); + const vertex$3 = "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}"; - let _currentScissorTest = null; // + const fragment$3 = "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}"; - let _width = _canvas.width; - let _height = _canvas.height; - let _pixelRatio = 1; - let _opaqueSort = null; - let _transparentSort = null; + const vertex$2 = "#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}"; - const _viewport = new Vector4(0, 0, _width, _height); + const fragment$2 = "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}"; - const _scissor = new Vector4(0, 0, _width, _height); + const vertex$1 = "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}"; - let _scissorTest = false; // frustum + const fragment$1 = "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}"; - const _frustum = new Frustum(); // clipping + const ShaderChunk = { + alphamap_fragment: alphamap_fragment, + alphamap_pars_fragment: alphamap_pars_fragment, + alphatest_fragment: alphatest_fragment, + alphatest_pars_fragment: alphatest_pars_fragment, + aomap_fragment: aomap_fragment, + aomap_pars_fragment: aomap_pars_fragment, + begin_vertex: begin_vertex, + beginnormal_vertex: beginnormal_vertex, + bsdfs: bsdfs, + iridescence_fragment: iridescence_fragment, + bumpmap_pars_fragment: bumpmap_pars_fragment, + clipping_planes_fragment: clipping_planes_fragment, + clipping_planes_pars_fragment: clipping_planes_pars_fragment, + clipping_planes_pars_vertex: clipping_planes_pars_vertex, + clipping_planes_vertex: clipping_planes_vertex, + color_fragment: color_fragment, + color_pars_fragment: color_pars_fragment, + color_pars_vertex: color_pars_vertex, + color_vertex: color_vertex, + common: common, + cube_uv_reflection_fragment: cube_uv_reflection_fragment, + defaultnormal_vertex: defaultnormal_vertex, + displacementmap_pars_vertex: displacementmap_pars_vertex, + displacementmap_vertex: displacementmap_vertex, + emissivemap_fragment: emissivemap_fragment, + emissivemap_pars_fragment: emissivemap_pars_fragment, + encodings_fragment: encodings_fragment, + encodings_pars_fragment: encodings_pars_fragment, + envmap_fragment: envmap_fragment, + envmap_common_pars_fragment: envmap_common_pars_fragment, + envmap_pars_fragment: envmap_pars_fragment, + envmap_pars_vertex: envmap_pars_vertex, + envmap_physical_pars_fragment: envmap_physical_pars_fragment, + envmap_vertex: envmap_vertex, + fog_vertex: fog_vertex, + fog_pars_vertex: fog_pars_vertex, + fog_fragment: fog_fragment, + fog_pars_fragment: fog_pars_fragment, + gradientmap_pars_fragment: gradientmap_pars_fragment, + lightmap_fragment: lightmap_fragment, + lightmap_pars_fragment: lightmap_pars_fragment, + lights_lambert_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, + lights_phong_fragment: lights_phong_fragment, + lights_phong_pars_fragment: lights_phong_pars_fragment, + lights_physical_fragment: lights_physical_fragment, + lights_physical_pars_fragment: lights_physical_pars_fragment, + lights_fragment_begin: lights_fragment_begin, + lights_fragment_maps: lights_fragment_maps, + lights_fragment_end: lights_fragment_end, + logdepthbuf_fragment: logdepthbuf_fragment, + logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, + logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, + logdepthbuf_vertex: logdepthbuf_vertex, + map_fragment: map_fragment, + map_pars_fragment: map_pars_fragment, + map_particle_fragment: map_particle_fragment, + map_particle_pars_fragment: map_particle_pars_fragment, + metalnessmap_fragment: metalnessmap_fragment, + metalnessmap_pars_fragment: metalnessmap_pars_fragment, + morphcolor_vertex: morphcolor_vertex, + morphnormal_vertex: morphnormal_vertex, + morphtarget_pars_vertex: morphtarget_pars_vertex, + morphtarget_vertex: morphtarget_vertex, + normal_fragment_begin: normal_fragment_begin, + normal_fragment_maps: normal_fragment_maps, + normal_pars_fragment: normal_pars_fragment, + normal_pars_vertex: normal_pars_vertex, + normal_vertex: normal_vertex, + normalmap_pars_fragment: normalmap_pars_fragment, + clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin, + clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps, + clearcoat_pars_fragment: clearcoat_pars_fragment, + iridescence_pars_fragment: iridescence_pars_fragment, + output_fragment: output_fragment, + packing: packing, + premultiplied_alpha_fragment: premultiplied_alpha_fragment, + project_vertex: project_vertex, + dithering_fragment: dithering_fragment, + dithering_pars_fragment: dithering_pars_fragment, + roughnessmap_fragment: roughnessmap_fragment, + roughnessmap_pars_fragment: roughnessmap_pars_fragment, + shadowmap_pars_fragment: shadowmap_pars_fragment, + shadowmap_pars_vertex: shadowmap_pars_vertex, + shadowmap_vertex: shadowmap_vertex, + shadowmask_pars_fragment: shadowmask_pars_fragment, + skinbase_vertex: skinbase_vertex, + skinning_pars_vertex: skinning_pars_vertex, + skinning_vertex: skinning_vertex, + skinnormal_vertex: skinnormal_vertex, + specularmap_fragment: specularmap_fragment, + specularmap_pars_fragment: specularmap_pars_fragment, + tonemapping_fragment: tonemapping_fragment, + tonemapping_pars_fragment: tonemapping_pars_fragment, + transmission_fragment: transmission_fragment, + transmission_pars_fragment: transmission_pars_fragment, + uv_pars_fragment: uv_pars_fragment, + uv_pars_vertex: uv_pars_vertex, + uv_vertex: uv_vertex, + uv2_pars_fragment: uv2_pars_fragment, + uv2_pars_vertex: uv2_pars_vertex, + uv2_vertex: uv2_vertex, + worldpos_vertex: worldpos_vertex, + background_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, + depth_frag: fragment$e, + distanceRGBA_vert: vertex$d, + distanceRGBA_frag: fragment$d, + equirect_vert: vertex$c, + equirect_frag: fragment$c, + linedashed_vert: vertex$b, + linedashed_frag: fragment$b, + meshbasic_vert: vertex$a, + meshbasic_frag: fragment$a, + meshlambert_vert: vertex$9, + meshlambert_frag: fragment$9, + meshmatcap_vert: vertex$8, + meshmatcap_frag: fragment$8, + meshnormal_vert: vertex$7, + meshnormal_frag: fragment$7, + meshphong_vert: vertex$6, + meshphong_frag: fragment$6, + meshphysical_vert: vertex$5, + meshphysical_frag: fragment$5, + meshtoon_vert: vertex$4, + meshtoon_frag: fragment$4, + points_vert: vertex$3, + points_frag: fragment$3, + shadow_vert: vertex$2, + shadow_frag: fragment$2, + sprite_vert: vertex$1, + sprite_frag: fragment$1 + }; - let _clippingEnabled = false; - let _localClippingEnabled = false; // transmission + /** + * Uniforms library for shared webgl shaders + */ - let _transmissionRenderTarget = null; // camera matrices cache + const UniformsLib = { - const _projScreenMatrix = new Matrix4(); + common: { - const _vector2 = new Vector2(); + diffuse: { value: /*@__PURE__*/ new Color( 0xffffff ) }, + opacity: { value: 1.0 }, - const _vector3 = new Vector3(); + map: { value: null }, + uvTransform: { value: /*@__PURE__*/ new Matrix3() }, + uv2Transform: { value: /*@__PURE__*/ new Matrix3() }, - const _emptyScene = { - background: null, - fog: null, - environment: null, - overrideMaterial: null, - isScene: true - }; + alphaMap: { value: null }, + alphaTest: { value: 0 } - function getTargetPixelRatio() { - return _currentRenderTarget === null ? _pixelRatio : 1; - } // initialize + }, + specularmap: { - let _gl = _context; + specularMap: { value: null }, - function getContext(contextNames, contextAttributes) { - for (let i = 0; i < contextNames.length; i++) { - const contextName = contextNames[i]; + }, - const context = _canvas.getContext(contextName, contextAttributes); + envmap: { - if (context !== null) return context; - } + envMap: { value: null }, + flipEnvMap: { value: - 1 }, + reflectivity: { value: 1.0 }, // basic, lambert, phong + ior: { value: 1.5 }, // physical + refractionRatio: { value: 0.98 }, // basic, lambert, phong - return null; - } + }, - try { - const contextAttributes = { - alpha: true, - depth: _depth, - stencil: _stencil, - antialias: _antialias, - premultipliedAlpha: _premultipliedAlpha, - preserveDrawingBuffer: _preserveDrawingBuffer, - powerPreference: _powerPreference, - failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat - }; // OffscreenCanvas does not have setAttribute, see #22811 + aomap: { - if ('setAttribute' in _canvas) _canvas.setAttribute('data-engine', `three.js r${REVISION}`); // event listeners must be registered before WebGL context is created, see #12753 + aoMap: { value: null }, + aoMapIntensity: { value: 1 } - _canvas.addEventListener('webglcontextlost', onContextLost, false); + }, - _canvas.addEventListener('webglcontextrestored', onContextRestore, false); + lightmap: { - _canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false); + lightMap: { value: null }, + lightMapIntensity: { value: 1 } - if (_gl === null) { - const contextNames = ['webgl2', 'webgl', 'experimental-webgl']; + }, - if (_this.isWebGL1Renderer === true) { - contextNames.shift(); - } + emissivemap: { - _gl = getContext(contextNames, contextAttributes); + emissiveMap: { value: null } - if (_gl === null) { - if (getContext(contextNames)) { - throw new Error('Error creating WebGL context with your selected attributes.'); - } else { - throw new Error('Error creating WebGL context.'); - } - } - } // Some experimental-webgl implementations do not have getShaderPrecisionFormat + }, + bumpmap: { - if (_gl.getShaderPrecisionFormat === undefined) { - _gl.getShaderPrecisionFormat = function () { - return { - 'rangeMin': 1, - 'rangeMax': 1, - 'precision': 1 - }; - }; - } - } catch (error) { - console.error('THREE.WebGLRenderer: ' + error.message); - throw error; - } + bumpMap: { value: null }, + bumpScale: { value: 1 } - 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; + }, - function initGLContext() { - extensions = new WebGLExtensions(_gl); - capabilities = new WebGLCapabilities(_gl, extensions, parameters); - extensions.init(capabilities); - utils = new WebGLUtils(_gl, extensions, capabilities); - state = new WebGLState(_gl, extensions, capabilities); - info = new WebGLInfo(_gl); - properties = new WebGLProperties(); - textures = new WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info); - cubemaps = new WebGLCubeMaps(_this); - cubeuvmaps = new WebGLCubeUVMaps(_this); - attributes = new WebGLAttributes(_gl, capabilities); - bindingStates = new WebGLBindingStates(_gl, extensions, attributes, capabilities); - geometries = new WebGLGeometries(_gl, attributes, info, bindingStates); - objects = new WebGLObjects(_gl, geometries, attributes, info); - morphtargets = new WebGLMorphtargets(_gl, capabilities, textures); - clipping = new WebGLClipping(properties); - programCache = new WebGLPrograms(_this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping); - materials = new WebGLMaterials(_this, properties); - renderLists = new WebGLRenderLists(); - renderStates = new WebGLRenderStates(extensions, capabilities); - background = new WebGLBackground(_this, cubemaps, state, objects, _alpha, _premultipliedAlpha); - shadowMap = new WebGLShadowMap(_this, objects, capabilities); - bufferRenderer = new WebGLBufferRenderer(_gl, extensions, info, capabilities); - indexedBufferRenderer = new WebGLIndexedBufferRenderer(_gl, extensions, info, capabilities); - info.programs = programCache.programs; - _this.capabilities = capabilities; - _this.extensions = extensions; - _this.properties = properties; - _this.renderLists = renderLists; - _this.shadowMap = shadowMap; - _this.state = state; - _this.info = info; - } + normalmap: { - initGLContext(); // xr + normalMap: { value: null }, + normalScale: { value: /*@__PURE__*/ new Vector2( 1, 1 ) } - const xr = new WebXRManager(_this, _gl); - this.xr = xr; // API + }, - this.getContext = function () { - return _gl; - }; + displacementmap: { - this.getContextAttributes = function () { - return _gl.getContextAttributes(); - }; + displacementMap: { value: null }, + displacementScale: { value: 1 }, + displacementBias: { value: 0 } - 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(); - }; + roughnessmap: { - this.getPixelRatio = function () { - return _pixelRatio; - }; + roughnessMap: { value: null } - this.setPixelRatio = function (value) { - if (value === undefined) return; - _pixelRatio = value; - this.setSize(_width, _height, false); - }; + }, - this.getSize = function (target) { - return target.set(_width, _height); - }; + metalnessmap: { - this.setSize = function (width, height, updateStyle) { - if (xr.isPresenting) { - console.warn('THREE.WebGLRenderer: Can\'t change size while VR device is presenting.'); - return; - } + metalnessMap: { value: null } - _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'; - } + gradientmap: { - this.setViewport(0, 0, width, height); - }; + gradientMap: { value: null } - this.getDrawingBufferSize = function (target) { - return target.set(_width * _pixelRatio, _height * _pixelRatio).floor(); - }; + }, - this.setDrawingBufferSize = function (width, height, pixelRatio) { - _width = width; - _height = height; - _pixelRatio = pixelRatio; - _canvas.width = Math.floor(width * pixelRatio); - _canvas.height = Math.floor(height * pixelRatio); - this.setViewport(0, 0, width, height); - }; + fog: { - this.getCurrentViewport = function (target) { - return target.copy(_currentViewport); - }; + fogDensity: { value: 0.00025 }, + fogNear: { value: 1 }, + fogFar: { value: 2000 }, + fogColor: { value: /*@__PURE__*/ new Color( 0xffffff ) } - 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); - } + lights: { - state.viewport(_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor()); - }; + 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: {} + } }, - this.getScissor = function (target) { - return target.copy(_scissor); - }; + // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src + rectAreaLights: { value: [], properties: { + color: {}, + position: {}, + width: {}, + height: {} + } }, - 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); - } + ltc_1: { value: null }, + ltc_2: { value: null } - state.scissor(_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor()); - }; + }, - this.getScissorTest = function () { - return _scissorTest; - }; + points: { - this.setScissorTest = function (boolean) { - state.setScissorTest(_scissorTest = boolean); - }; + diffuse: { value: /*@__PURE__*/ new Color( 0xffffff ) }, + opacity: { value: 1.0 }, + size: { value: 1.0 }, + scale: { value: 1.0 }, + map: { value: null }, + alphaMap: { value: null }, + alphaTest: { value: 0 }, + uvTransform: { value: /*@__PURE__*/ new Matrix3() } - this.setOpaqueSort = function (method) { - _opaqueSort = method; - }; + }, - this.setTransparentSort = function (method) { - _transparentSort = method; - }; // Clearing + sprite: { + diffuse: { value: /*@__PURE__*/ new Color( 0xffffff ) }, + opacity: { value: 1.0 }, + center: { value: /*@__PURE__*/ new Vector2( 0.5, 0.5 ) }, + rotation: { value: 0.0 }, + map: { value: null }, + alphaMap: { value: null }, + alphaTest: { value: 0 }, + uvTransform: { value: /*@__PURE__*/ new Matrix3() } - this.getClearColor = function (target) { - return target.copy(background.getClearColor()); - }; + } - this.setClearColor = function () { - background.setClearColor.apply(background, arguments); - }; + }; - this.getClearAlpha = function () { - return background.getClearAlpha(); - }; + const ShaderLib = { - this.setClearAlpha = function () { - background.setClearAlpha.apply(background, arguments); - }; + basic: { - 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; + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.fog + ] ), - _gl.clear(bits); - }; + vertexShader: ShaderChunk.meshbasic_vert, + fragmentShader: ShaderChunk.meshbasic_frag - this.clearColor = function () { - this.clear(true, false, false); - }; + }, - this.clearDepth = function () { - this.clear(false, true, false); - }; + lambert: { - this.clearStencil = function () { - this.clear(false, false, true); - }; // + 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 ) } + } + ] ), + vertexShader: ShaderChunk.meshlambert_vert, + fragmentShader: ShaderChunk.meshlambert_frag - this.dispose = function () { - _canvas.removeEventListener('webglcontextlost', onContextLost, false); + }, - _canvas.removeEventListener('webglcontextrestored', onContextRestore, false); + phong: { - _canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false); + 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 ) }, + specular: { value: /*@__PURE__*/ new Color( 0x111111 ) }, + shininess: { value: 30 } + } + ] ), - renderLists.dispose(); - renderStates.dispose(); - properties.dispose(); - cubemaps.dispose(); - cubeuvmaps.dispose(); - objects.dispose(); - bindingStates.dispose(); - programCache.dispose(); - xr.dispose(); - xr.removeEventListener('sessionstart', onXRSessionStart); - xr.removeEventListener('sessionend', onXRSessionEnd); + vertexShader: ShaderChunk.meshphong_vert, + fragmentShader: ShaderChunk.meshphong_frag - if (_transmissionRenderTarget) { - _transmissionRenderTarget.dispose(); + }, - _transmissionRenderTarget = null; - } + standard: { - animation.stop(); - }; // Events + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.roughnessmap, + UniformsLib.metalnessmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: /*@__PURE__*/ new Color( 0x000000 ) }, + roughness: { value: 1.0 }, + metalness: { value: 0.0 }, + envMapIntensity: { value: 1 } // temporary + } + ] ), + vertexShader: ShaderChunk.meshphysical_vert, + fragmentShader: ShaderChunk.meshphysical_frag - function onContextLost(event) { - event.preventDefault(); - console.log('THREE.WebGLRenderer: Context Lost.'); - _isContextLost = true; - } + }, - function - /* event */ - onContextRestore() { - console.log('THREE.WebGLRenderer: Context Restored.'); - _isContextLost = false; - const infoAutoReset = info.autoReset; - const shadowMapEnabled = shadowMap.enabled; - const shadowMapAutoUpdate = shadowMap.autoUpdate; - const shadowMapNeedsUpdate = shadowMap.needsUpdate; - const shadowMapType = shadowMap.type; - initGLContext(); - info.autoReset = infoAutoReset; - shadowMap.enabled = shadowMapEnabled; - shadowMap.autoUpdate = shadowMapAutoUpdate; - shadowMap.needsUpdate = shadowMapNeedsUpdate; - shadowMap.type = shadowMapType; - } + toon: { - function onContextCreationError(event) { - console.error('THREE.WebGLRenderer: A WebGL context could not be created. Reason: ', event.statusMessage); - } + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.gradientmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: /*@__PURE__*/ new Color( 0x000000 ) } + } + ] ), - function onMaterialDispose(event) { - const material = event.target; - material.removeEventListener('dispose', onMaterialDispose); - deallocateMaterial(material); - } // Buffer deallocation + vertexShader: ShaderChunk.meshtoon_vert, + fragmentShader: ShaderChunk.meshtoon_frag + }, - function deallocateMaterial(material) { - releaseMaterialProgramReferences(material); - properties.remove(material); - } + matcap: { - function releaseMaterialProgramReferences(material) { - const programs = properties.get(material).programs; + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.fog, + { + matcap: { value: null } + } + ] ), - if (programs !== undefined) { - programs.forEach(function (program) { - programCache.releaseProgram(program); - }); + vertexShader: ShaderChunk.meshmatcap_vert, + fragmentShader: ShaderChunk.meshmatcap_frag - if (material.isShaderMaterial) { - programCache.releaseShaderCache(material); - } - } - } // Buffer rendering + }, + points: { - this.renderBufferDirect = function (camera, scene, geometry, material, object, group) { - if (scene === null) scene = _emptyScene; // renderBufferDirect second parameter used to be fog (could be null) + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.points, + UniformsLib.fog + ] ), - const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; - const program = setProgram(camera, scene, geometry, material, object); - state.setMaterial(material, frontFaceCW); // + vertexShader: ShaderChunk.points_vert, + fragmentShader: ShaderChunk.points_frag - 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; - } // + dashed: { + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.fog, + { + scale: { value: 1 }, + dashSize: { value: 1 }, + totalSize: { value: 2 } + } + ] ), - let rangeFactor = 1; + vertexShader: ShaderChunk.linedashed_vert, + fragmentShader: ShaderChunk.linedashed_frag - if (material.wireframe === true) { - index = geometries.getWireframeAttribute(geometry); - rangeFactor = 2; - } + }, - bindingStates.setup(object, material, program, geometry, index); - let attribute; - let renderer = bufferRenderer; + depth: { - if (index !== null) { - attribute = attributes.get(index); - renderer = indexedBufferRenderer; - renderer.setIndex(attribute); - } // + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.displacementmap + ] ), + vertexShader: ShaderChunk.depth_vert, + fragmentShader: ShaderChunk.depth_frag - 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) { - state.setLineWidth(material.wireframeLinewidth * getTargetPixelRatio()); - renderer.setMode(_gl.LINES); - } else { - renderer.setMode(_gl.TRIANGLES); - } - } else if (object.isLine) { - let lineWidth = material.linewidth; - if (lineWidth === undefined) lineWidth = 1; // Not using Line*Material + }, - state.setLineWidth(lineWidth * getTargetPixelRatio()); + normal: { - if (object.isLineSegments) { - renderer.setMode(_gl.LINES); - } else if (object.isLineLoop) { - renderer.setMode(_gl.LINE_LOOP); - } else { - renderer.setMode(_gl.LINE_STRIP); + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + { + opacity: { value: 1.0 } } - } else if (object.isPoints) { - renderer.setMode(_gl.POINTS); - } 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); - renderer.renderInstances(drawStart, drawCount, instanceCount); - } else { - renderer.render(drawStart, drawCount); - } - }; // Compile + vertexShader: ShaderChunk.meshnormal_vert, + fragmentShader: ShaderChunk.meshnormal_frag + }, - this.compile = function (scene, camera) { - currentRenderState = renderStates.get(scene); - currentRenderState.init(); - renderStateStack.push(currentRenderState); - scene.traverseVisible(function (object) { - if (object.isLight && object.layers.test(camera.layers)) { - currentRenderState.pushLight(object); + sprite: { - if (object.castShadow) { - currentRenderState.pushShadow(object); - } - } - }); - currentRenderState.setupLights(_this.physicallyCorrectLights); - scene.traverse(function (object) { - const material = object.material; + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.sprite, + UniformsLib.fog + ] ), - if (material) { - if (Array.isArray(material)) { - for (let i = 0; i < material.length; i++) { - const material2 = material[i]; - getProgram(material2, scene, object); - } - } else { - getProgram(material, scene, object); - } - } - }); - renderStateStack.pop(); - currentRenderState = null; - }; // Animation Loop + vertexShader: ShaderChunk.sprite_vert, + fragmentShader: ShaderChunk.sprite_frag + }, - let onAnimationFrameCallback = null; + background: { - function onAnimationFrame(time) { - if (onAnimationFrameCallback) onAnimationFrameCallback(time); - } + uniforms: { + uvTransform: { value: /*@__PURE__*/ new Matrix3() }, + t2D: { value: null }, + backgroundIntensity: { value: 1 } + }, - function onXRSessionStart() { - animation.stop(); - } + vertexShader: ShaderChunk.background_vert, + fragmentShader: ShaderChunk.background_frag - function onXRSessionEnd() { - animation.start(); - } + }, - const animation = new WebGLAnimation(); - animation.setAnimationLoop(onAnimationFrame); - if (typeof self !== 'undefined') animation.setContext(self); + backgroundCube: { - this.setAnimationLoop = function (callback) { - onAnimationFrameCallback = callback; - xr.setAnimationLoop(callback); - callback === null ? animation.stop() : animation.start(); - }; + uniforms: { + envMap: { value: null }, + flipEnvMap: { value: - 1 }, + backgroundBlurriness: { value: 0 }, + backgroundIntensity: { value: 1 } + }, - xr.addEventListener('sessionstart', onXRSessionStart); - xr.addEventListener('sessionend', onXRSessionEnd); // Rendering + vertexShader: ShaderChunk.backgroundCube_vert, + fragmentShader: ShaderChunk.backgroundCube_frag - 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; // update scene graph + cube: { - if (scene.autoUpdate === true) scene.updateMatrixWorld(); // update camera matrices and frustum + uniforms: { + tCube: { value: null }, + tFlip: { value: - 1 }, + opacity: { value: 1.0 } + }, - if (camera.parent === null) camera.updateMatrixWorld(); + vertexShader: ShaderChunk.cube_vert, + fragmentShader: ShaderChunk.cube_frag - if (xr.enabled === true && xr.isPresenting === true) { - if (xr.cameraAutoUpdate === true) xr.updateCamera(camera); - camera = xr.getCamera(); // use XR camera for rendering - } // + }, + equirect: { - if (scene.isScene === true) scene.onBeforeRender(_this, scene, camera, _currentRenderTarget); - currentRenderState = renderStates.get(scene, renderStateStack.length); - currentRenderState.init(); - renderStateStack.push(currentRenderState); + uniforms: { + tEquirect: { value: null }, + }, - _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); + vertexShader: ShaderChunk.equirect_vert, + fragmentShader: ShaderChunk.equirect_frag - _frustum.setFromProjectionMatrix(_projScreenMatrix); + }, - _localClippingEnabled = this.localClippingEnabled; - _clippingEnabled = clipping.init(this.clippingPlanes, _localClippingEnabled, camera); - currentRenderList = renderLists.get(scene, renderListStack.length); - currentRenderList.init(); - renderListStack.push(currentRenderList); - projectObject(scene, camera, 0, _this.sortObjects); - currentRenderList.finish(); + distanceRGBA: { - if (_this.sortObjects === true) { - currentRenderList.sort(_opaqueSort, _transparentSort); - } // + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.common, + UniformsLib.displacementmap, + { + referencePosition: { value: /*@__PURE__*/ new Vector3() }, + nearDistance: { value: 1 }, + farDistance: { value: 1000 } + } + ] ), + vertexShader: ShaderChunk.distanceRGBA_vert, + fragmentShader: ShaderChunk.distanceRGBA_frag - if (_clippingEnabled === true) clipping.beginShadows(); - const shadowsArray = currentRenderState.state.shadowsArray; - shadowMap.render(shadowsArray, scene, camera); - if (_clippingEnabled === true) clipping.endShadows(); // + }, - if (this.info.autoReset === true) this.info.reset(); // + shadow: { - background.render(currentRenderList, scene); // render scene + uniforms: /*@__PURE__*/ mergeUniforms( [ + UniformsLib.lights, + UniformsLib.fog, + { + color: { value: /*@__PURE__*/ new Color( 0x00000 ) }, + opacity: { value: 1.0 } + }, + ] ), - currentRenderState.setupLights(_this.physicallyCorrectLights); + vertexShader: ShaderChunk.shadow_vert, + fragmentShader: ShaderChunk.shadow_frag - 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); - } // + }; + ShaderLib.physical = { - 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 + uniforms: /*@__PURE__*/ mergeUniforms( [ + ShaderLib.standard.uniforms, + { + clearcoat: { value: 0 }, + clearcoatMap: { value: null }, + clearcoatRoughness: { value: 0 }, + clearcoatRoughnessMap: { value: null }, + clearcoatNormalScale: { value: /*@__PURE__*/ new Vector2( 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: /*@__PURE__*/ new Color( 0x000000 ) }, + sheenColorMap: { value: null }, + sheenRoughness: { value: 1 }, + sheenRoughnessMap: { value: null }, + transmission: { value: 0 }, + transmissionMap: { value: null }, + transmissionSamplerSize: { value: /*@__PURE__*/ new Vector2() }, + transmissionSamplerMap: { value: null }, + thickness: { value: 0 }, + thicknessMap: { value: null }, + attenuationDistance: { value: 0 }, + attenuationColor: { value: /*@__PURE__*/ new Color( 0x000000 ) }, + specularIntensity: { value: 1 }, + specularIntensityMap: { value: null }, + specularColor: { value: /*@__PURE__*/ new Color( 1, 1, 1 ) }, + specularColorMap: { value: null }, + } + ] ), - textures.updateRenderTargetMipmap(_currentRenderTarget); - } // + vertexShader: ShaderChunk.meshphysical_vert, + fragmentShader: ShaderChunk.meshphysical_frag + }; - if (scene.isScene === true) scene.onAfterRender(_this, scene, camera); // _gl.finish(); + const _rgb = { r: 0, b: 0, g: 0 }; - bindingStates.resetDefaultState(); - _currentMaterialId = -1; - _currentCamera = null; - renderStateStack.pop(); + function WebGLBackground( renderer, cubemaps, cubeuvmaps, state, objects, alpha, premultipliedAlpha ) { - if (renderStateStack.length > 0) { - currentRenderState = renderStateStack[renderStateStack.length - 1]; - } else { - currentRenderState = null; - } + const clearColor = new Color( 0x000000 ); + let clearAlpha = alpha === true ? 0 : 1; - renderListStack.pop(); + let planeMesh; + let boxMesh; - if (renderListStack.length > 0) { - currentRenderList = renderListStack[renderListStack.length - 1]; - } else { - currentRenderList = null; - } - }; + let currentBackground = null; + let currentBackgroundVersion = 0; + let currentTonemapping = null; - function projectObject(object, camera, groupOrder, sortObjects) { - if (object.visible === false) return; - const visible = object.layers.test(camera.layers); + function render( renderList, scene ) { - if (visible) { - if (object.isGroup) { - groupOrder = object.renderOrder; - } else if (object.isLOD) { - if (object.autoUpdate === true) object.update(camera); - } else if (object.isLight) { - currentRenderState.pushLight(object); - - if (object.castShadow) { - currentRenderState.pushShadow(object); - } - } else if (object.isSprite) { - if (!object.frustumCulled || _frustum.intersectsSprite(object)) { - if (sortObjects) { - _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); - } + let forceClear = false; + let background = scene.isScene === true ? scene.background : null; - const geometry = objects.update(object); - const material = object.material; + if ( background && background.isTexture ) { - if (material.visible) { - currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null); - } - } - } else if (object.isMesh || object.isLine || object.isPoints) { - if (object.isSkinnedMesh) { - // update skeleton only once in a frame - if (object.skeleton.frame !== info.render.frame) { - object.skeleton.update(); - object.skeleton.frame = info.render.frame; - } - } + const usePMREM = scene.backgroundBlurriness > 0; // use PMREM if the user wants to blur the background + background = ( usePMREM ? cubeuvmaps : cubemaps ).get( background ); - if (!object.frustumCulled || _frustum.intersectsObject(object)) { - if (sortObjects) { - _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); - } + } - const geometry = objects.update(object); - const material = object.material; + // Ignore background in AR + // TODO: Reconsider this. - if (Array.isArray(material)) { - const groups = geometry.groups; + const xr = renderer.xr; + const session = xr.getSession && xr.getSession(); - for (let i = 0, l = groups.length; i < l; i++) { - const group = groups[i]; - const groupMaterial = material[group.materialIndex]; + if ( session && session.environmentBlendMode === 'additive' ) { + + background = null; - if (groupMaterial && groupMaterial.visible) { - currentRenderList.push(object, geometry, groupMaterial, groupOrder, _vector3.z, group); - } - } - } else if (material.visible) { - currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null); - } - } - } } - const children = object.children; + if ( background === null ) { - for (let i = 0, l = children.length; i < l; i++) { - projectObject(children[i], camera, groupOrder, sortObjects); - } - } + setClear( clearColor, clearAlpha ); - function renderScene(currentRenderList, scene, camera, viewport) { - const opaqueObjects = currentRenderList.opaque; - const transmissiveObjects = currentRenderList.transmissive; - const transparentObjects = currentRenderList.transparent; - currentRenderState.setupLightsView(camera); - if (transmissiveObjects.length > 0) renderTransmissionPass(opaqueObjects, scene, camera); - 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 + } else if ( background && background.isColor ) { - state.buffers.depth.setTest(true); - state.buffers.depth.setMask(true); - state.buffers.color.setMask(true); - state.setPolygonOffset(false); - } + setClear( background, 1 ); + forceClear = true; - function renderTransmissionPass(opaqueObjects, scene, camera) { - const isWebGL2 = capabilities.isWebGL2; + } + + if ( renderer.autoClear || forceClear ) { + + renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil ); - if (_transmissionRenderTarget === null) { - _transmissionRenderTarget = new WebGLRenderTarget(1, 1, { - generateMipmaps: true, - type: extensions.has('EXT_color_buffer_half_float') ? HalfFloatType : UnsignedByteType, - minFilter: LinearMipmapLinearFilter, - samples: isWebGL2 && _antialias === true ? 4 : 0 - }); } - _this.getDrawingBufferSize(_vector2); + if ( background && ( background.isCubeTexture || background.mapping === CubeUVReflectionMapping ) ) { - if (isWebGL2) { - _transmissionRenderTarget.setSize(_vector2.x, _vector2.y); - } else { - _transmissionRenderTarget.setSize(floorPowerOfTwo(_vector2.x), floorPowerOfTwo(_vector2.y)); - } // + if ( boxMesh === undefined ) { + boxMesh = new Mesh( + new BoxGeometry( 1, 1, 1 ), + new ShaderMaterial( { + name: 'BackgroundCubeMaterial', + uniforms: cloneUniforms( ShaderLib.backgroundCube.uniforms ), + vertexShader: ShaderLib.backgroundCube.vertexShader, + fragmentShader: ShaderLib.backgroundCube.fragmentShader, + side: BackSide, + depthTest: false, + depthWrite: false, + fog: false + } ) + ); - const currentRenderTarget = _this.getRenderTarget(); + boxMesh.geometry.deleteAttribute( 'normal' ); + boxMesh.geometry.deleteAttribute( 'uv' ); - _this.setRenderTarget(_transmissionRenderTarget); + boxMesh.onBeforeRender = function ( renderer, scene, camera ) { - _this.clear(); // 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. + this.matrixWorld.copyPosition( camera.matrixWorld ); + }; - const currentToneMapping = _this.toneMapping; - _this.toneMapping = NoToneMapping; - renderObjects(opaqueObjects, scene, camera); - _this.toneMapping = currentToneMapping; - textures.updateMultisampleRenderTarget(_transmissionRenderTarget); - textures.updateRenderTargetMipmap(_transmissionRenderTarget); + // add "envMap" material property so the renderer can evaluate it like for built-in materials + Object.defineProperty( boxMesh.material, 'envMap', { - _this.setRenderTarget(currentRenderTarget); - } + get: function () { - function renderObjects(renderList, scene, camera) { - const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null; + return this.uniforms.envMap.value; - 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; + } + + } ); + + objects.update( boxMesh ); - 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); + 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; + boxMesh.material.toneMapped = ( background.encoding === sRGBEncoding ) ? false : true; - if (material.transparent === true && material.side === DoubleSide) { - material.side = BackSide; - material.needsUpdate = true; + if ( currentBackground !== background || + currentBackgroundVersion !== background.version || + currentTonemapping !== renderer.toneMapping ) { - _this.renderBufferDirect(camera, scene, geometry, material, object, group); + boxMesh.material.needsUpdate = true; - material.side = FrontSide; - material.needsUpdate = true; + currentBackground = background; + currentBackgroundVersion = background.version; + currentTonemapping = renderer.toneMapping; - _this.renderBufferDirect(camera, scene, geometry, material, object, group); + } - material.side = DoubleSide; - } else { - _this.renderBufferDirect(camera, scene, geometry, material, object, group); - } + boxMesh.layers.enableAll(); - object.onAfterRender(_this, scene, camera, geometry, material, group); - } + // push to the pre-sorted opaque render list + renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null ); - function getProgram(material, scene, object) { - if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... + } else if ( background && background.isTexture ) { - const materialProperties = properties.get(material); - const lights = currentRenderState.state.lights; - const shadowsArray = currentRenderState.state.shadowsArray; - 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 + if ( planeMesh === undefined ) { - materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null; - materialProperties.fog = scene.fog; - materialProperties.envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || materialProperties.environment); + planeMesh = new Mesh( + new PlaneGeometry( 2, 2 ), + new ShaderMaterial( { + name: 'BackgroundMaterial', + uniforms: cloneUniforms( ShaderLib.background.uniforms ), + vertexShader: ShaderLib.background.vertexShader, + fragmentShader: ShaderLib.background.fragmentShader, + side: FrontSide, + depthTest: false, + depthWrite: false, + fog: false + } ) + ); - if (programs === undefined) { - // new material - material.addEventListener('dispose', onMaterialDispose); - programs = new Map(); - materialProperties.programs = programs; - } + planeMesh.geometry.deleteAttribute( 'normal' ); - let program = programs.get(programCacheKey); + // 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; + + } + + } ); + + objects.update( planeMesh ); - if (program !== undefined) { - // early out if program and light state is identical - if (materialProperties.currentProgram === program && materialProperties.lightsStateVersion === lightsStateVersion) { - updateCommonMaterialProperties(material, parameters); - return program; } - } else { - parameters.uniforms = programCache.getUniforms(material); - material.onBuild(object, parameters, _this); - material.onBeforeCompile(parameters, _this); - program = programCache.acquireProgram(parameters, programCacheKey); - programs.set(programCacheKey, program); - materialProperties.uniforms = parameters.uniforms; - } - const uniforms = materialProperties.uniforms; + planeMesh.material.uniforms.t2D.value = background; + planeMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; + planeMesh.material.toneMapped = ( background.encoding === sRGBEncoding ) ? false : true; - if (!material.isShaderMaterial && !material.isRawShaderMaterial || material.clipping === true) { - uniforms.clippingPlanes = clipping.uniform; - } + if ( background.matrixAutoUpdate === true ) { - updateCommonMaterialProperties(material, parameters); // store the light setup it was created for + background.updateMatrix(); - materialProperties.needsLights = materialNeedsLights(material); - materialProperties.lightsStateVersion = lightsStateVersion; + } + + 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(); + + // push to the pre-sorted opaque render list + renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null ); - if (materialProperties.needsLights) { - // wire up the material to this renderer's lighting state - uniforms.ambientLightColor.value = lights.state.ambient; - uniforms.lightProbe.value = lights.state.probe; - uniforms.directionalLights.value = lights.state.directional; - uniforms.directionalLightShadows.value = lights.state.directionalShadow; - uniforms.spotLights.value = lights.state.spot; - uniforms.spotLightShadows.value = lights.state.spotShadow; - uniforms.rectAreaLights.value = lights.state.rectArea; - uniforms.ltc_1.value = lights.state.rectAreaLTC1; - uniforms.ltc_2.value = lights.state.rectAreaLTC2; - uniforms.pointLights.value = lights.state.point; - uniforms.pointLightShadows.value = lights.state.pointShadow; - uniforms.hemisphereLights.value = lights.state.hemi; - uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; - uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix; - uniforms.spotShadowMap.value = lights.state.spotShadowMap; - uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix; - uniforms.pointShadowMap.value = lights.state.pointShadowMap; - uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; // TODO (abelnation): add area lights shadow info to uniforms } - const progUniforms = program.getUniforms(); - const uniformsList = WebGLUniforms.seqWithValue(progUniforms.seq, uniforms); - materialProperties.currentProgram = program; - materialProperties.uniformsList = uniformsList; - return program; } + function setClear( color, alpha ) { + + color.getRGB( _rgb, getUnlitUniformColorSpace( renderer ) ); + + state.buffers.color.setClear( _rgb.r, _rgb.g, _rgb.b, alpha, premultipliedAlpha ); + + } + + return { + + getClearColor: function () { + + return clearColor; + + }, + setClearColor: function ( color, alpha = 1 ) { + + clearColor.set( color ); + clearAlpha = alpha; + setClear( clearColor, clearAlpha ); + + }, + getClearAlpha: function () { + + return clearAlpha; + + }, + setClearAlpha: function ( alpha ) { + +<<<<<<< HEAD function updateCommonMaterialProperties(material, parameters) { const materialProperties = properties.get(material); materialProperties.outputEncoding = parameters.outputEncoding; @@ -20335,10 +14408,15 @@ materialProperties.toneMapping = parameters.toneMapping; materialProperties.extraProgramCacheKey = parameters.extraProgramCacheKey; } +======= + clearAlpha = alpha; + setClear( clearColor, clearAlpha ); +>>>>>>> mrdoob-dev - function setProgram(camera, scene, geometry, material, object) { - if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... + }, + render: render +<<<<<<< HEAD textures.resetTextureUnits(); const fog = scene.fog; const environment = material.isMeshStandardMaterial ? scene.environment : null; @@ -20355,20 +14433,20 @@ const materialProperties = properties.get(material); const lights = currentRenderState.state.lights; const extraProgramCacheKey = _this.extraProgramCacheKey; +======= + }; +>>>>>>> mrdoob-dev - 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 - // object instead of the material, once it becomes feasible - // (#8465, #8379) + } - clipping.setState(material, camera, useCache); - } - } // + function WebGLBindingStates( gl, extensions, attributes, capabilities ) { + const maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); - let needsProgramChange = false; + const extension = capabilities.isWebGL2 ? null : extensions.get( 'OES_vertex_array_object' ); + const vaoAvailable = capabilities.isWebGL2 || extension !== null; +<<<<<<< HEAD if (material.version === materialProperties.__version) { if (materialProperties.needsLights && materialProperties.lightsStateVersion !== lights.state.version) { needsProgramChange = true; @@ -20409,14729 +14487,36094 @@ needsProgramChange = true; materialProperties.__version = material.version; } // +======= + const bindingStates = {}; +>>>>>>> mrdoob-dev + const defaultState = createBindingState( null ); + let currentState = defaultState; + let forceUpdate = false; - let program = materialProperties.currentProgram; + function setup( object, material, program, geometry, index ) { - if (needsProgramChange === true) { - program = getProgram(material, scene, object); - } + let updateBuffers = false; - let refreshProgram = false; - let refreshMaterial = false; - let refreshLights = false; - const p_uniforms = program.getUniforms(), - m_uniforms = materialProperties.uniforms; + if ( vaoAvailable ) { - if (state.useProgram(program.program)) { - refreshProgram = true; - refreshMaterial = true; - refreshLights = true; - } + const state = getBindingState( geometry, program, material ); - if (material.id !== _currentMaterialId) { - _currentMaterialId = material.id; - refreshMaterial = true; - } + if ( currentState !== state ) { - if (refreshProgram || _currentCamera !== camera) { - p_uniforms.setValue(_gl, 'projectionMatrix', camera.projectionMatrix); + currentState = state; + bindVertexArrayObject( currentState.object ); - if (capabilities.logarithmicDepthBuffer) { - p_uniforms.setValue(_gl, 'logDepthBufFC', 2.0 / (Math.log(camera.far + 1.0) / Math.LN2)); } - if (_currentCamera !== camera) { - _currentCamera = camera; // lighting uniforms depend on the camera so enforce an update - // now, in case this material supports lights - or later, when - // the next material that does gets activated: + updateBuffers = needsUpdate( object, geometry, program, index ); - refreshMaterial = true; // set to true on material change + if ( updateBuffers ) saveCache( object, geometry, program, index ); - refreshLights = true; // remains set until update done - } // load material specific uniforms - // (shader material also gets them for the sake of genericity) + } else { + const wireframe = ( material.wireframe === true ); - if (material.isShaderMaterial || material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshStandardMaterial || material.envMap) { - const uCamPos = p_uniforms.map.cameraPosition; + if ( currentState.geometry !== geometry.id || + currentState.program !== program.id || + currentState.wireframe !== wireframe ) { - if (uCamPos !== undefined) { - uCamPos.setValue(_gl, _vector3.setFromMatrixPosition(camera.matrixWorld)); - } - } + currentState.geometry = geometry.id; + currentState.program = program.id; + currentState.wireframe = wireframe; - if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial) { - p_uniforms.setValue(_gl, 'isOrthographic', camera.isOrthographicCamera === true); - } + updateBuffers = 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 - // 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(); - p_uniforms.setValue(_gl, 'boneTexture', skeleton.boneTexture, textures); - p_uniforms.setValue(_gl, 'boneTextureSize', skeleton.boneTextureSize); - } else { - console.warn('THREE.WebGLRenderer: SkinnedMesh can only be used with WebGL 2. With WebGL 1 OES_texture_float and vertex textures support is required.'); - } - } } - const morphAttributes = geometry.morphAttributes; + if ( index !== null ) { - if (morphAttributes.position !== undefined || morphAttributes.normal !== undefined || morphAttributes.color !== undefined && capabilities.isWebGL2 === true) { - morphtargets.update(object, geometry, material, program); - } + attributes.update( index, gl.ELEMENT_ARRAY_BUFFER ); - if (refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow) { - materialProperties.receiveShadow = object.receiveShadow; - p_uniforms.setValue(_gl, 'receiveShadow', object.receiveShadow); } - if (refreshMaterial) { - p_uniforms.setValue(_gl, 'toneMappingExposure', _this.toneMappingExposure); + if ( updateBuffers || forceUpdate ) { - 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 + forceUpdate = false; + + setupVertexAttributes( object, material, program, geometry ); + if ( index !== null ) { + + gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, attributes.get( index ).buffer ); - 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 + function createVertexArrayObject() { + if ( capabilities.isWebGL2 ) return gl.createVertexArray(); - p_uniforms.setValue(_gl, 'modelViewMatrix', object.modelViewMatrix); - p_uniforms.setValue(_gl, 'normalMatrix', object.normalMatrix); - p_uniforms.setValue(_gl, 'modelMatrix', object.matrixWorld); - return program; - } // If uniforms are marked as clean, they don't need to be loaded to the GPU. + return extension.createVertexArrayOES(); + } + + function bindVertexArrayObject( vao ) { + + if ( capabilities.isWebGL2 ) return gl.bindVertexArray( vao ); + + return extension.bindVertexArrayOES( vao ); - function markUniformsLightsNeedsUpdate(uniforms, value) { - uniforms.ambientLightColor.needsUpdate = value; - uniforms.lightProbe.needsUpdate = value; - uniforms.directionalLights.needsUpdate = value; - uniforms.directionalLightShadows.needsUpdate = value; - uniforms.pointLights.needsUpdate = value; - uniforms.pointLightShadows.needsUpdate = value; - uniforms.spotLights.needsUpdate = value; - uniforms.spotLightShadows.needsUpdate = value; - uniforms.rectAreaLights.needsUpdate = value; - uniforms.hemisphereLights.needsUpdate = value; } - function materialNeedsLights(material) { - return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isShadowMaterial || material.isShaderMaterial && material.lights === true; + function deleteVertexArrayObject( vao ) { + + if ( capabilities.isWebGL2 ) return gl.deleteVertexArray( vao ); + + return extension.deleteVertexArrayOES( vao ); + } - this.getActiveCubeFace = function () { - return _currentActiveCubeFace; - }; + function getBindingState( geometry, program, material ) { - this.getActiveMipmapLevel = function () { - return _currentActiveMipmapLevel; - }; + const wireframe = ( material.wireframe === true ); - this.getRenderTarget = function () { - return _currentRenderTarget; - }; + let programMap = bindingStates[ geometry.id ]; - 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 ( programMap === undefined ) { - if (renderTargetProperties.__hasExternalTextures) { - renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined; + programMap = {}; + bindingStates[ geometry.id ] = programMap; - 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. - if (extensions.has('WEBGL_multisampled_render_to_texture') === true) { - console.warn('THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided'); - renderTargetProperties.__useRenderToTexture = false; - } - } } - }; - this.setRenderTargetFramebuffer = function (renderTarget, defaultFramebuffer) { - const renderTargetProperties = properties.get(renderTarget); - renderTargetProperties.__webglFramebuffer = defaultFramebuffer; - renderTargetProperties.__useDefaultFramebuffer = defaultFramebuffer === undefined; - }; + let stateMap = programMap[ program.id ]; - this.setRenderTarget = function (renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { - _currentRenderTarget = renderTarget; - _currentActiveCubeFace = activeCubeFace; - _currentActiveMipmapLevel = activeMipmapLevel; - let useDefaultFramebuffer = true; + if ( stateMap === undefined ) { - if (renderTarget) { - const renderTargetProperties = properties.get(renderTarget); + stateMap = {}; + programMap[ program.id ] = stateMap; - if (renderTargetProperties.__useDefaultFramebuffer !== undefined) { - // We need to make sure to rebind the framebuffer. - state.bindFramebuffer(_gl.FRAMEBUFFER, null); - useDefaultFramebuffer = false; - } else if (renderTargetProperties.__webglFramebuffer === undefined) { - textures.setupRenderTarget(renderTarget); - } else if (renderTargetProperties.__hasExternalTextures) { - // 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; + let state = stateMap[ wireframe ]; - if (renderTarget) { - const texture = renderTarget.texture; + if ( state === undefined ) { - if (texture.isData3DTexture || texture.isDataArrayTexture) { - isRenderTarget3D = true; - } + state = createBindingState( createVertexArrayObject() ); + stateMap[ wireframe ] = state; - const __webglFramebuffer = properties.get(renderTarget).__webglFramebuffer; + } - if (renderTarget.isWebGLCubeRenderTarget) { - framebuffer = __webglFramebuffer[activeCubeFace]; - isCube = true; - } else if (capabilities.isWebGL2 && renderTarget.samples > 0 && textures.useMultisampledRTT(renderTarget) === false) { - framebuffer = properties.get(renderTarget).__webglMultisampledFramebuffer; - } else { - framebuffer = __webglFramebuffer; - } - - _currentViewport.copy(renderTarget.viewport); + return state; - _currentScissor.copy(renderTarget.scissor); + } - _currentScissorTest = renderTarget.scissorTest; - } else { - _currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor(); + function createBindingState( vao ) { - _currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor(); + const newAttributes = []; + const enabledAttributes = []; + const attributeDivisors = []; - _currentScissorTest = _scissorTest; - } + for ( let i = 0; i < maxVertexAttributes; i ++ ) { - const framebufferBound = state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); + newAttributes[ i ] = 0; + enabledAttributes[ i ] = 0; + attributeDivisors[ i ] = 0; - 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; + return { - _gl.framebufferTextureLayer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureProperties.__webglTexture, activeMipmapLevel || 0, layer); - } + // for backward compatibility on non-VAO support browser + geometry: null, + program: null, + wireframe: false, - _currentMaterialId = -1; // reset current material to ensure correct uniform bindings - }; + newAttributes: newAttributes, + enabledAttributes: enabledAttributes, + attributeDivisors: attributeDivisors, + object: vao, + attributes: {}, + index: null - this.readRenderTargetPixels = function (renderTarget, x, y, width, height, buffer, activeCubeFaceIndex) { - if (!(renderTarget && renderTarget.isWebGLRenderTarget)) { - console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.'); - return; - } + }; - let framebuffer = properties.get(renderTarget).__webglFramebuffer; + } - if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined) { - framebuffer = framebuffer[activeCubeFaceIndex]; - } + function needsUpdate( object, geometry, program, index ) { - if (framebuffer) { - state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); + const cachedAttributes = currentState.attributes; + const geometryAttributes = geometry.attributes; - try { - const texture = renderTarget.texture; - const textureFormat = texture.format; - const textureType = texture.type; + let attributesNum = 0; - 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 programAttributes = program.getAttributes(); - const halfFloatSupportedByExt = textureType === HalfFloatType && (extensions.has('EXT_color_buffer_half_float') || capabilities.isWebGL2 && extensions.has('EXT_color_buffer_float')); + for ( const name in programAttributes ) { - 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) + const programAttribute = programAttributes[ name ]; + if ( programAttribute.location >= 0 ) { - 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); - } - } - }; + const cachedAttribute = cachedAttributes[ name ]; + let geometryAttribute = geometryAttributes[ name ]; - 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); + if ( geometryAttribute === undefined ) { - _gl.copyTexSubImage2D(_gl.TEXTURE_2D, level, 0, 0, position.x, position.y, width, height); + if ( name === 'instanceMatrix' && object.instanceMatrix ) geometryAttribute = object.instanceMatrix; + if ( name === 'instanceColor' && object.instanceColor ) geometryAttribute = object.instanceColor; - 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 + if ( cachedAttribute === undefined ) return true; - _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); + if ( cachedAttribute.attribute !== geometryAttribute ) return true; - _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); + if ( geometryAttribute && cachedAttribute.data !== geometryAttribute.data ) return true; - _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); + attributesNum ++; - if (srcTexture.isDataTexture) { - _gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data); - } else { - if (srcTexture.isCompressedTexture) { - _gl.compressedTexSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, srcTexture.mipmaps[0].width, srcTexture.mipmaps[0].height, glFormat, srcTexture.mipmaps[0].data); - } else { - _gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image); } - } // Generate mipmaps only when copying level 0 + } - if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(_gl.TEXTURE_2D); - state.unbindTexture(); - }; + if ( currentState.attributesNum !== attributesNum ) return true; - this.copyTextureToTexture3D = function (sourceBox, position, srcTexture, dstTexture, level = 0) { - if (_this.isWebGL1Renderer) { - console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: can only be used with WebGL2.'); - return; - } + if ( currentState.index !== index ) return true; - 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; + return false; - if (dstTexture.isData3DTexture) { - textures.setTexture3D(dstTexture, 0); - glTarget = _gl.TEXTURE_3D; - } else if (dstTexture.isDataArrayTexture) { - textures.setTexture2DArray(dstTexture, 0); - glTarget = _gl.TEXTURE_2D_ARRAY; - } else { - console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.'); - return; - } + } + + function saveCache( object, geometry, program, index ) { - _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); + const cache = {}; + const attributes = geometry.attributes; + let attributesNum = 0; - _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); + const programAttributes = program.getAttributes(); - _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); + for ( const name in programAttributes ) { - const unpackRowLen = _gl.getParameter(_gl.UNPACK_ROW_LENGTH); + const programAttribute = programAttributes[ name ]; - const unpackImageHeight = _gl.getParameter(_gl.UNPACK_IMAGE_HEIGHT); + if ( programAttribute.location >= 0 ) { - const unpackSkipPixels = _gl.getParameter(_gl.UNPACK_SKIP_PIXELS); + let attribute = attributes[ name ]; - const unpackSkipRows = _gl.getParameter(_gl.UNPACK_SKIP_ROWS); + if ( attribute === undefined ) { - const unpackSkipImages = _gl.getParameter(_gl.UNPACK_SKIP_IMAGES); + if ( name === 'instanceMatrix' && object.instanceMatrix ) attribute = object.instanceMatrix; + if ( name === 'instanceColor' && object.instanceColor ) attribute = object.instanceColor; - const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[0] : srcTexture.image; + } - _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, image.width); + const data = {}; + data.attribute = attribute; - _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, image.height); + if ( attribute && attribute.data ) { - _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, sourceBox.min.x); + data.data = attribute.data; - _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, sourceBox.min.y); + } - _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, sourceBox.min.z); + cache[ name ] = data; - 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) { - console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture.'); + attributesNum ++; - _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); + currentState.attributes = cache; + currentState.attributesNum = attributesNum; - _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, unpackSkipPixels); + currentState.index = index; - _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, unpackSkipRows); + } - _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, unpackSkipImages); // Generate mipmaps only when copying level 0 + function initAttributes() { + const newAttributes = currentState.newAttributes; - if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(glTarget); - state.unbindTexture(); - }; + for ( let i = 0, il = newAttributes.length; i < il; i ++ ) { - this.initTexture = function (texture) { - textures.setTexture2D(texture, 0); - state.unbindTexture(); - }; + newAttributes[ i ] = 0; - this.resetState = function () { - _currentActiveCubeFace = 0; - _currentActiveMipmapLevel = 0; - _currentRenderTarget = null; - state.reset(); - bindingStates.reset(); - }; + } - if (typeof __THREE_DEVTOOLS__ !== 'undefined') { - __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', { - detail: this - })); } - } - class WebGL1Renderer extends WebGLRenderer {} + function enableAttribute( attribute ) { - WebGL1Renderer.prototype.isWebGL1Renderer = true; + enableAttributeAndDivisor( attribute, 0 ); - class FogExp2 { - constructor(color, density = 0.00025) { - this.isFogExp2 = true; - this.name = ''; - this.color = new Color(color); - this.density = density; } - clone() { - return new FogExp2(this.color, this.density); - } + function enableAttributeAndDivisor( attribute, meshPerAttribute ) { - toJSON() { - return { - type: 'FogExp2', - color: this.color.getHex(), - density: this.density - }; - } + const newAttributes = currentState.newAttributes; + const enabledAttributes = currentState.enabledAttributes; + const attributeDivisors = currentState.attributeDivisors; - } + newAttributes[ attribute ] = 1; - class Fog { - constructor(color, near = 1, far = 1000) { - this.isFog = true; - this.name = ''; - this.color = new Color(color); - this.near = near; - this.far = far; - } + if ( enabledAttributes[ attribute ] === 0 ) { - clone() { - return new Fog(this.color, this.near, this.far); - } + gl.enableVertexAttribArray( attribute ); + enabledAttributes[ attribute ] = 1; - toJSON() { - return { - type: 'Fog', - color: this.color.getHex(), - near: this.near, - far: this.far - }; - } + } - } + if ( attributeDivisors[ attribute ] !== meshPerAttribute ) { - class Scene extends Object3D { - constructor() { - super(); - this.isScene = true; - this.type = 'Scene'; - this.background = null; - this.environment = null; - this.fog = null; - this.overrideMaterial = null; - this.autoUpdate = true; // checked by the renderer + const extension = capabilities.isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' ); - if (typeof __THREE_DEVTOOLS__ !== 'undefined') { - __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', { - detail: this - })); - } - } + extension[ capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute ); + attributeDivisors[ attribute ] = meshPerAttribute; - 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(); - 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(); - return data; } - } - - class InterleavedBuffer { - constructor(array, stride) { - this.isInterleavedBuffer = true; - this.array = array; - this.stride = stride; - this.count = array !== undefined ? array.length / stride : 0; - this.usage = StaticDrawUsage; - this.updateRange = { - offset: 0, - count: -1 - }; - this.version = 0; - this.uuid = generateUUID(); - } + function disableUnusedAttributes() { - onUploadCallback() {} + const newAttributes = currentState.newAttributes; + const enabledAttributes = currentState.enabledAttributes; - set needsUpdate(value) { - if (value === true) this.version++; - } + for ( let i = 0, il = enabledAttributes.length; i < il; i ++ ) { - setUsage(value) { - this.usage = value; - return this; - } + if ( enabledAttributes[ i ] !== newAttributes[ i ] ) { - copy(source) { - this.array = new source.array.constructor(source.array); - this.count = source.count; - this.stride = source.stride; - this.usage = source.usage; - return this; - } + gl.disableVertexAttribArray( i ); + enabledAttributes[ i ] = 0; - 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; - } + function vertexAttribPointer( index, size, type, normalized, stride, offset ) { - clone(data) { - if (data.arrayBuffers === undefined) { - data.arrayBuffers = {}; - } + if ( capabilities.isWebGL2 === true && ( type === gl.INT || type === gl.UNSIGNED_INT ) ) { - if (this.array.buffer._uuid === undefined) { - this.array.buffer._uuid = generateUUID(); - } + gl.vertexAttribIPointer( index, size, type, stride, offset ); + + } else { + + gl.vertexAttribPointer( index, size, type, normalized, stride, offset ); - 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; - } + function setupVertexAttributes( object, material, program, geometry ) { - toJSON(data) { - if (data.arrayBuffers === undefined) { - data.arrayBuffers = {}; - } // generate UUID for array buffer if necessary + if ( capabilities.isWebGL2 === false && ( object.isInstancedMesh || geometry.isInstancedBufferGeometry ) ) { + if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) return; - 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.prototype.slice.call(new Uint32Array(this.array.buffer)); - } // + initAttributes(); + const geometryAttributes = geometry.attributes; - return { - uuid: this.uuid, - buffer: this.array.buffer._uuid, - type: this.array.constructor.name, - stride: this.stride - }; - } + const programAttributes = program.getAttributes(); - } + const materialDefaultAttributeValues = material.defaultAttributeValues; - const _vector$6 = /*@__PURE__*/new Vector3(); + for ( const name in programAttributes ) { - class InterleavedBufferAttribute { - constructor(interleavedBuffer, itemSize, offset, normalized = false) { - this.isInterleavedBufferAttribute = true; - this.name = ''; - this.data = interleavedBuffer; - this.itemSize = itemSize; - this.offset = offset; - this.normalized = normalized === true; - } + const programAttribute = programAttributes[ name ]; - get count() { - return this.data.count; - } + if ( programAttribute.location >= 0 ) { - get array() { - return this.data.array; - } + let geometryAttribute = geometryAttributes[ name ]; - set needsUpdate(value) { - this.data.needsUpdate = value; - } + if ( geometryAttribute === undefined ) { - applyMatrix4(m) { - for (let i = 0, l = this.data.count; i < l; i++) { - _vector$6.fromBufferAttribute(this, i); + if ( name === 'instanceMatrix' && object.instanceMatrix ) geometryAttribute = object.instanceMatrix; + if ( name === 'instanceColor' && object.instanceColor ) geometryAttribute = object.instanceColor; - _vector$6.applyMatrix4(m); + } - this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); - } + if ( geometryAttribute !== undefined ) { - return this; - } + const normalized = geometryAttribute.normalized; + const size = geometryAttribute.itemSize; - applyNormalMatrix(m) { - for (let i = 0, l = this.count; i < l; i++) { - _vector$6.fromBufferAttribute(this, i); + const attribute = attributes.get( geometryAttribute ); - _vector$6.applyNormalMatrix(m); + // TODO Attribute may not be available on context restore - this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); - } + if ( attribute === undefined ) continue; - return this; - } + const buffer = attribute.buffer; + const type = attribute.type; + const bytesPerElement = attribute.bytesPerElement; - transformDirection(m) { - for (let i = 0, l = this.count; i < l; i++) { - _vector$6.fromBufferAttribute(this, i); + if ( geometryAttribute.isInterleavedBufferAttribute ) { - _vector$6.transformDirection(m); + const data = geometryAttribute.data; + const stride = data.stride; + const offset = geometryAttribute.offset; - this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); - } + if ( data.isInstancedInterleavedBuffer ) { - return this; - } + for ( let i = 0; i < programAttribute.locationSize; i ++ ) { - setX(index, x) { - this.data.array[index * this.data.stride + this.offset] = x; - return this; - } + enableAttributeAndDivisor( programAttribute.location + i, data.meshPerAttribute ); - setY(index, y) { - this.data.array[index * this.data.stride + this.offset + 1] = y; - return this; - } - - setZ(index, z) { - this.data.array[index * this.data.stride + this.offset + 2] = z; - return this; - } - - setW(index, w) { - 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]; - } + } - getY(index) { - return this.data.array[index * this.data.stride + this.offset + 1]; - } + if ( object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined ) { - getZ(index) { - return this.data.array[index * this.data.stride + this.offset + 2]; - } + geometry._maxInstanceCount = data.meshPerAttribute * data.count; - getW(index) { - return this.data.array[index * this.data.stride + this.offset + 3]; - } + } - setXY(index, x, y) { - index = index * this.data.stride + this.offset; - this.data.array[index + 0] = x; - this.data.array[index + 1] = y; - return this; - } + } else { - setXYZ(index, x, y, z) { - index = index * this.data.stride + this.offset; - this.data.array[index + 0] = x; - this.data.array[index + 1] = y; - this.data.array[index + 2] = z; - return this; - } + for ( let i = 0; i < programAttribute.locationSize; i ++ ) { - setXYZW(index, x, y, z, w) { - index = index * this.data.stride + this.offset; - this.data.array[index + 0] = x; - this.data.array[index + 1] = y; - this.data.array[index + 2] = z; - this.data.array[index + 3] = w; - return this; - } + enableAttribute( programAttribute.location + i ); - clone(data) { - if (data === undefined) { - console.log('THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave 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]); - } - } + gl.bindBuffer( gl.ARRAY_BUFFER, buffer ); - return new BufferAttribute(new this.array.constructor(array), this.itemSize, this.normalized); - } else { - if (data.interleavedBuffers === undefined) { - data.interleavedBuffers = {}; - } + for ( let i = 0; i < programAttribute.locationSize; i ++ ) { - if (data.interleavedBuffers[this.data.uuid] === undefined) { - data.interleavedBuffers[this.data.uuid] = this.data.clone(data); - } + vertexAttribPointer( + programAttribute.location + i, + size / programAttribute.locationSize, + type, + normalized, + stride * bytesPerElement, + ( offset + ( size / programAttribute.locationSize ) * i ) * bytesPerElement + ); - 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 interlaved buffer attribute will deinterleave buffer data.'); - const array = []; + } else { - for (let i = 0; i < this.count; i++) { - const index = i * this.data.stride + this.offset; + if ( geometryAttribute.isInstancedBufferAttribute ) { - 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 + for ( let i = 0; i < programAttribute.locationSize; i ++ ) { + enableAttributeAndDivisor( programAttribute.location + i, geometryAttribute.meshPerAttribute ); - return { - itemSize: this.itemSize, - type: this.array.constructor.name, - array: array, - normalized: this.normalized - }; - } else { - // save as true interlaved attribtue - if (data.interleavedBuffers === undefined) { - data.interleavedBuffers = {}; - } + } - if (data.interleavedBuffers[this.data.uuid] === undefined) { - data.interleavedBuffers[this.data.uuid] = this.data.toJSON(data); - } + if ( object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined ) { - return { - isInterleavedBufferAttribute: true, - itemSize: this.itemSize, - data: this.data.uuid, - offset: this.offset, - normalized: this.normalized - }; - } - } + geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; - } + } - class SpriteMaterial extends Material { - constructor(parameters) { - super(); - this.isSpriteMaterial = true; - this.type = 'SpriteMaterial'; - this.color = new Color(0xffffff); - this.map = null; - this.alphaMap = null; - this.rotation = 0; - this.sizeAttenuation = true; - this.transparent = true; - this.fog = true; - this.setValues(parameters); - } + } else { - copy(source) { - super.copy(source); - this.color.copy(source.color); - this.map = source.map; - this.alphaMap = source.alphaMap; - this.rotation = source.rotation; - this.sizeAttenuation = source.sizeAttenuation; - this.fog = source.fog; - return this; - } + for ( let i = 0; i < programAttribute.locationSize; i ++ ) { - } + enableAttribute( programAttribute.location + i ); - let _geometry; + } - const _intersectPoint = /*@__PURE__*/new Vector3(); + } - const _worldScale = /*@__PURE__*/new Vector3(); + gl.bindBuffer( gl.ARRAY_BUFFER, buffer ); - const _mvPosition = /*@__PURE__*/new Vector3(); + for ( let i = 0; i < programAttribute.locationSize; i ++ ) { - const _alignedPosition = /*@__PURE__*/new Vector2(); + vertexAttribPointer( + programAttribute.location + i, + size / programAttribute.locationSize, + type, + normalized, + size * bytesPerElement, + ( size / programAttribute.locationSize ) * i * bytesPerElement + ); - const _rotatedPosition = /*@__PURE__*/new Vector2(); + } - const _viewWorldMatrix = /*@__PURE__*/new Matrix4(); + } - const _vA = /*@__PURE__*/new Vector3(); + } else if ( materialDefaultAttributeValues !== undefined ) { - const _vB = /*@__PURE__*/new Vector3(); + const value = materialDefaultAttributeValues[ name ]; - const _vC = /*@__PURE__*/new Vector3(); + if ( value !== undefined ) { - const _uvA = /*@__PURE__*/new Vector2(); + switch ( value.length ) { - const _uvB = /*@__PURE__*/new Vector2(); + case 2: + gl.vertexAttrib2fv( programAttribute.location, value ); + break; - const _uvC = /*@__PURE__*/new Vector2(); + case 3: + gl.vertexAttrib3fv( programAttribute.location, value ); + break; - class Sprite extends Object3D { - constructor(material) { - super(); - this.isSprite = true; - this.type = 'Sprite'; + case 4: + gl.vertexAttrib4fv( programAttribute.location, value ); + break; - 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); + default: + gl.vertexAttrib1fv( programAttribute.location, value ); - _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); + disableUnusedAttributes(); - this.modelViewMatrix.multiplyMatrices(raycaster.camera.matrixWorldInverse, this.matrixWorld); + } - _mvPosition.setFromMatrixPosition(this.modelViewMatrix); + function dispose() { - if (raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false) { - _worldScale.multiplyScalar(-_mvPosition.z); - } + reset(); - const rotation = this.material.rotation; - let sin, cos; + for ( const geometryId in bindingStates ) { - if (rotation !== 0) { - cos = Math.cos(rotation); - sin = Math.sin(rotation); - } + const programMap = bindingStates[ geometryId ]; - 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); + for ( const programId in programMap ) { - _uvA.set(0, 0); + const stateMap = programMap[ programId ]; - _uvB.set(1, 0); + for ( const wireframe in stateMap ) { - _uvC.set(1, 1); // check first triangle + deleteVertexArrayObject( stateMap[ wireframe ].object ); + delete stateMap[ wireframe ]; - 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); + delete programMap[ programId ]; - _uvB.set(0, 1); + } - intersect = raycaster.ray.intersectTriangle(_vA, _vC, _vB, false, _intersectPoint); + delete bindingStates[ geometryId ]; - if (intersect === null) { - return; - } } - const distance = raycaster.ray.origin.distanceTo(_intersectPoint); - if (distance < raycaster.near || distance > raycaster.far) return; - intersects.push({ - distance: distance, - point: _intersectPoint.clone(), - uv: Triangle.getUV(_intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2()), - face: null, - 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 releaseStatesOfGeometry( geometry ) { - 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 + if ( bindingStates[ geometry.id ] === undefined ) return; + const programMap = bindingStates[ geometry.id ]; - if (sin !== undefined) { - _rotatedPosition.x = cos * _alignedPosition.x - sin * _alignedPosition.y; - _rotatedPosition.y = sin * _alignedPosition.x + cos * _alignedPosition.y; - } else { - _rotatedPosition.copy(_alignedPosition); - } + for ( const programId in programMap ) { - vertexPosition.copy(mvPosition); - vertexPosition.x += _rotatedPosition.x; - vertexPosition.y += _rotatedPosition.y; // transform to world space + const stateMap = programMap[ programId ]; - vertexPosition.applyMatrix4(_viewWorldMatrix); - } + for ( const wireframe in stateMap ) { - const _v1$2 = /*@__PURE__*/new Vector3(); + deleteVertexArrayObject( stateMap[ wireframe ].object ); - const _v2$1 = /*@__PURE__*/new Vector3(); + delete stateMap[ wireframe ]; - class LOD extends Object3D { - constructor() { - super(); - this._currentLevel = 0; - this.type = 'LOD'; - Object.defineProperties(this, { - levels: { - enumerable: true, - value: [] - }, - isLOD: { - value: true } - }); - this.autoUpdate = true; - } - copy(source) { - super.copy(source, false); - const levels = source.levels; + delete programMap[ programId ]; - for (let i = 0, l = levels.length; i < l; i++) { - const level = levels[i]; - this.addLevel(level.object.clone(), level.distance); } - this.autoUpdate = source.autoUpdate; - return this; + delete bindingStates[ geometry.id ]; + } - addLevel(object, distance = 0) { - distance = Math.abs(distance); - const levels = this.levels; - let l; + function releaseStatesOfProgram( program ) { - for (l = 0; l < levels.length; l++) { - if (distance < levels[l].distance) { - break; - } - } + for ( const geometryId in bindingStates ) { - levels.splice(l, 0, { - distance: distance, - object: object - }); - this.add(object); - return this; - } + const programMap = bindingStates[ geometryId ]; - getCurrentLevel() { - return this._currentLevel; - } + if ( programMap[ program.id ] === undefined ) continue; - getObjectForDistance(distance) { - const levels = this.levels; + const stateMap = programMap[ program.id ]; - if (levels.length > 0) { - let i, l; + for ( const wireframe in stateMap ) { + + deleteVertexArrayObject( stateMap[ wireframe ].object ); + + delete stateMap[ wireframe ]; - for (i = 1, l = levels.length; i < l; i++) { - if (distance < levels[i].distance) { - break; - } } - return levels[i - 1].object; + delete programMap[ program.id ]; + } - return null; } - raycast(raycaster, intersects) { - const levels = this.levels; - - if (levels.length > 0) { - _v1$2.setFromMatrixPosition(this.matrixWorld); + function reset() { - const distance = raycaster.ray.origin.distanceTo(_v1$2); - this.getObjectForDistance(distance).raycast(raycaster, intersects); - } - } + resetDefaultState(); + forceUpdate = true; - update(camera) { - const levels = this.levels; + if ( currentState === defaultState ) return; - if (levels.length > 1) { - _v1$2.setFromMatrixPosition(camera.matrixWorld); + currentState = defaultState; + bindVertexArrayObject( currentState.object ); - _v2$1.setFromMatrixPosition(this.matrixWorld); + } - const distance = _v1$2.distanceTo(_v2$1) / camera.zoom; - levels[0].object.visible = true; - let i, l; + // for backward-compatibility - for (i = 1, l = levels.length; i < l; i++) { - if (distance >= levels[i].distance) { - levels[i - 1].object.visible = false; - levels[i].object.visible = true; - } else { - break; - } - } + function resetDefaultState() { - this._currentLevel = i - 1; + defaultState.geometry = null; + defaultState.program = null; + defaultState.wireframe = false; - 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; + return { - 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 - }); - } + setup: setup, + reset: reset, + resetDefaultState: resetDefaultState, + dispose: dispose, + releaseStatesOfGeometry: releaseStatesOfGeometry, + releaseStatesOfProgram: releaseStatesOfProgram, - return data; - } + initAttributes: initAttributes, + enableAttribute: enableAttribute, + disableUnusedAttributes: disableUnusedAttributes - } + }; - const _basePosition = /*@__PURE__*/new Vector3(); + } - const _skinIndex = /*@__PURE__*/new Vector4(); + function WebGLBufferRenderer( gl, extensions, info, capabilities ) { - const _skinWeight = /*@__PURE__*/new Vector4(); + const isWebGL2 = capabilities.isWebGL2; - const _vector$5 = /*@__PURE__*/new Vector3(); + let mode; - const _matrix = /*@__PURE__*/new Matrix4(); + function setMode( value ) { - class SkinnedMesh extends Mesh { - constructor(geometry, material) { - super(geometry, material); - this.isSkinnedMesh = true; - this.type = 'SkinnedMesh'; - this.bindMode = 'attached'; - this.bindMatrix = new Matrix4(); - this.bindMatrixInverse = new Matrix4(); - } + mode = value; - copy(source, recursive) { - super.copy(source, recursive); - this.bindMode = source.bindMode; - this.bindMatrix.copy(source.bindMatrix); - this.bindMatrixInverse.copy(source.bindMatrixInverse); - this.skeleton = source.skeleton; - return this; } - bind(skeleton, bindMatrix) { - this.skeleton = skeleton; + function render( start, count ) { - if (bindMatrix === undefined) { - this.updateMatrixWorld(true); - this.skeleton.calculateInverses(); - bindMatrix = this.matrixWorld; - } + gl.drawArrays( mode, start, count ); - this.bindMatrix.copy(bindMatrix); - this.bindMatrixInverse.copy(bindMatrix).invert(); - } + info.update( count, mode, 1 ); - pose() { - this.skeleton.pose(); } - normalizeSkinWeights() { - const vector = new Vector4(); - const skinWeight = this.geometry.attributes.skinWeight; + function renderInstances( start, count, primcount ) { - for (let i = 0, l = skinWeight.count; i < l; i++) { - vector.fromBufferAttribute(skinWeight, i); - const scale = 1.0 / vector.manhattanLength(); + if ( primcount === 0 ) return; - if (scale !== Infinity) { - vector.multiplyScalar(scale); - } else { - vector.set(1, 0, 0, 0); // do something reasonable - } + let extension, methodName; - skinWeight.setXYZW(i, vector.x, vector.y, vector.z, vector.w); - } - } + if ( isWebGL2 ) { - updateMatrixWorld(force) { - super.updateMatrixWorld(force); + extension = gl; + methodName = 'drawArraysInstanced'; - if (this.bindMode === 'attached') { - this.bindMatrixInverse.copy(this.matrixWorld).invert(); - } else if (this.bindMode === 'detached') { - this.bindMatrixInverse.copy(this.bindMatrix).invert(); } else { - console.warn('THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode); - } - } - boneTransform(index, target) { - const skeleton = this.skeleton; - const geometry = this.geometry; + extension = extensions.get( 'ANGLE_instanced_arrays' ); + methodName = 'drawArraysInstancedANGLE'; - _skinIndex.fromBufferAttribute(geometry.attributes.skinIndex, index); + if ( extension === null ) { - _skinWeight.fromBufferAttribute(geometry.attributes.skinWeight, index); + console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); + return; - _basePosition.copy(target).applyMatrix4(this.bindMatrix); + } - target.set(0, 0, 0); + } - for (let i = 0; i < 4; i++) { - const weight = _skinWeight.getComponent(i); + extension[ methodName ]( mode, start, count, primcount ); - if (weight !== 0) { - const boneIndex = _skinIndex.getComponent(i); + info.update( count, mode, primcount ); - _matrix.multiplyMatrices(skeleton.bones[boneIndex].matrixWorld, skeleton.boneInverses[boneIndex]); + } - target.addScaledVector(_vector$5.copy(_basePosition).applyMatrix4(_matrix), weight); - } - } + // - return target.applyMatrix4(this.bindMatrixInverse); - } + this.setMode = setMode; + this.render = render; + this.renderInstances = renderInstances; } - class Bone extends Object3D { - constructor() { - super(); - this.isBone = true; - this.type = 'Bone'; - } - - } + function WebGLCapabilities( gl, extensions, parameters ) { - class DataTexture extends Texture { - constructor(data = null, width = 1, height = 1, format, type, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, encoding) { - super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); - this.isDataTexture = true; - this.image = { - data: data, - width: width, - height: height - }; - this.generateMipmaps = false; - this.flipY = false; - this.unpackAlignment = 1; - } + let maxAnisotropy; - } + function getMaxAnisotropy() { - const _offsetMatrix = /*@__PURE__*/new Matrix4(); + if ( maxAnisotropy !== undefined ) return maxAnisotropy; - const _identityMatrix = /*@__PURE__*/new Matrix4(); + if ( extensions.has( 'EXT_texture_filter_anisotropic' ) === true ) { - class Skeleton { - constructor(bones = [], boneInverses = []) { - this.uuid = generateUUID(); - this.bones = bones.slice(0); - this.boneInverses = boneInverses; - this.boneMatrices = null; - this.boneTexture = null; - this.boneTextureSize = 0; - this.frame = -1; - this.init(); - } + const extension = extensions.get( 'EXT_texture_filter_anisotropic' ); - init() { - const bones = this.bones; - const boneInverses = this.boneInverses; - this.boneMatrices = new Float32Array(bones.length * 16); // calculate inverse bone matrices if necessary + maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT ); - 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; + maxAnisotropy = 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(); - } + return maxAnisotropy; - 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 + function getMaxPrecision( precision ) { + if ( precision === 'highp' ) { - for (let i = 0, il = this.bones.length; i < il; i++) { - const bone = this.bones[i]; + if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 && + gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) { - if (bone) { - if (bone.parent && bone.parent.isBone) { - bone.matrix.copy(bone.parent.matrixWorld).invert(); - bone.matrix.multiply(bone.matrixWorld); - } else { - bone.matrix.copy(bone.matrixWorld); - } + return 'highp'; - 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 - 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; - - _offsetMatrix.multiplyMatrices(matrix, boneInverses[i]); - - _offsetMatrix.toArray(boneMatrices, i * 16); - } + precision = 'mediump'; - 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) - // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8) - // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16) - // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32) - // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64) - 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 + if ( precision === 'mediump' ) { - const boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType); - boneTexture.needsUpdate = true; - this.boneMatrices = boneMatrices; - this.boneTexture = boneTexture; - this.boneTextureSize = size; - return this; - } + if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 && + gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) { - getBoneByName(name) { - for (let i = 0, il = this.bones.length; i < il; i++) { - const bone = this.bones[i]; + return 'mediump'; - if (bone.name === name) { - return bone; } + } - return undefined; - } + return 'lowp'; - dispose() { - if (this.boneTexture !== null) { - this.boneTexture.dispose(); - this.boneTexture = null; - } } - fromJSON(json, bones) { - this.uuid = json.uuid; + const isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext; - for (let i = 0, l = json.bones.length; i < l; i++) { - const uuid = json.bones[i]; - let bone = bones[uuid]; + let precision = parameters.precision !== undefined ? parameters.precision : 'highp'; + const maxPrecision = getMaxPrecision( precision ); - if (bone === undefined) { - console.warn('THREE.Skeleton: No bone found with UUID:', uuid); - bone = new Bone(); - } + if ( maxPrecision !== precision ) { - this.bones.push(bone); - this.boneInverses.push(new Matrix4().fromArray(json.boneInverses[i])); - } + console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' ); + precision = maxPrecision; - this.init(); - return this; } - toJSON() { - const data = { - metadata: { - version: 4.5, - type: 'Skeleton', - generator: 'Skeleton.toJSON' - }, - bones: [], - boneInverses: [] - }; - data.uuid = this.uuid; - const bones = this.bones; - const boneInverses = this.boneInverses; + const drawBuffers = isWebGL2 || extensions.has( 'WEBGL_draw_buffers' ); - 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()); - } + const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; - return data; - } + const maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS ); + const maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); + const maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE ); + const maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE ); - } + const maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); + const maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS ); + const maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS ); + const maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS ); - 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.'); - } + const vertexTextures = maxVertexTextures > 0; + const floatFragmentTextures = isWebGL2 || extensions.has( 'OES_texture_float' ); + const floatVertexTextures = vertexTextures && floatFragmentTextures; - super(array, itemSize, normalized); - this.isInstancedBufferAttribute = true; - this.meshPerAttribute = meshPerAttribute; - } + const maxSamples = isWebGL2 ? gl.getParameter( gl.MAX_SAMPLES ) : 0; - copy(source) { - super.copy(source); - this.meshPerAttribute = source.meshPerAttribute; - return this; - } + return { - toJSON() { - const data = super.toJSON(); - data.meshPerAttribute = this.meshPerAttribute; - data.isInstancedBufferAttribute = true; - return data; - } + isWebGL2: isWebGL2, - } + drawBuffers: drawBuffers, - const _instanceLocalMatrix = /*@__PURE__*/new Matrix4(); + getMaxAnisotropy: getMaxAnisotropy, + getMaxPrecision: getMaxPrecision, - const _instanceWorldMatrix = /*@__PURE__*/new Matrix4(); + precision: precision, + logarithmicDepthBuffer: logarithmicDepthBuffer, - const _instanceIntersects = []; + maxTextures: maxTextures, + maxVertexTextures: maxVertexTextures, + maxTextureSize: maxTextureSize, + maxCubemapSize: maxCubemapSize, - const _mesh = /*@__PURE__*/new Mesh(); + maxAttributes: maxAttributes, + maxVertexUniforms: maxVertexUniforms, + maxVaryings: maxVaryings, + maxFragmentUniforms: maxFragmentUniforms, - class InstancedMesh extends Mesh { - constructor(geometry, material, count) { - super(geometry, material); - this.isInstancedMesh = true; - this.instanceMatrix = new InstancedBufferAttribute(new Float32Array(count * 16), 16); - this.instanceColor = null; - this.count = count; - this.frustumCulled = false; - } + vertexTextures: vertexTextures, + floatFragmentTextures: floatFragmentTextures, + floatVertexTextures: floatVertexTextures, - copy(source, recursive) { - super.copy(source, recursive); - this.instanceMatrix.copy(source.instanceMatrix); - if (source.instanceColor !== null) this.instanceColor = source.instanceColor.clone(); - this.count = source.count; - return this; - } + maxSamples: maxSamples - 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; + function WebGLClipping( properties ) { - for (let instanceId = 0; instanceId < raycastTimes; instanceId++) { - // calculate the world matrix for each instance - this.getMatrixAt(instanceId, _instanceLocalMatrix); + const scope = this; - _instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix); // the mesh represents this single instance + let globalState = null, + numGlobalPlanes = 0, + localClippingEnabled = false, + renderingShadows = false; + const plane = new Plane(), + viewNormalMatrix = new Matrix3(), - _mesh.matrixWorld = _instanceWorldMatrix; + uniform = { value: null, needsUpdate: false }; - _mesh.raycast(raycaster, _instanceIntersects); // process the result of raycast + this.uniform = uniform; + this.numPlanes = 0; + this.numIntersection = 0; + this.init = function ( planes, enableLocalClipping ) { - for (let i = 0, l = _instanceIntersects.length; i < l; i++) { - const intersect = _instanceIntersects[i]; - intersect.instanceId = instanceId; - intersect.object = this; - intersects.push(intersect); - } + 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; - _instanceIntersects.length = 0; - } - } + localClippingEnabled = enableLocalClipping; - setColorAt(index, color) { - if (this.instanceColor === null) { - this.instanceColor = new InstancedBufferAttribute(new Float32Array(this.instanceMatrix.count * 3), 3); - } + numGlobalPlanes = planes.length; - color.toArray(this.instanceColor.array, index * 3); - } + return enabled; - setMatrixAt(index, matrix) { - matrix.toArray(this.instanceMatrix.array, index * 16); - } + }; - updateMorphTargets() {} + this.beginShadows = function () { - dispose() { - this.dispatchEvent({ - type: 'dispose' - }); - } + renderingShadows = true; + projectPlanes( null ); - } + }; - class LineBasicMaterial extends Material { - constructor(parameters) { - super(); - this.isLineBasicMaterial = true; - this.type = 'LineBasicMaterial'; - this.color = new Color(0xffffff); - this.linewidth = 1; - this.linecap = 'round'; - this.linejoin = 'round'; - this.fog = true; - this.setValues(parameters); - } + this.endShadows = function () { - copy(source) { - super.copy(source); - this.color.copy(source.color); - this.linewidth = source.linewidth; - this.linecap = source.linecap; - this.linejoin = source.linejoin; - this.fog = source.fog; - return this; - } + renderingShadows = false; - } + }; - const _start$1 = /*@__PURE__*/new Vector3(); + this.setGlobalState = function ( planes, camera ) { - const _end$1 = /*@__PURE__*/new Vector3(); + globalState = projectPlanes( planes, camera, 0 ); - const _inverseMatrix$1 = /*@__PURE__*/new Matrix4(); + }; - const _ray$1 = /*@__PURE__*/new Ray(); + this.setState = function ( material, camera, useCache ) { - const _sphere$1 = /*@__PURE__*/new Sphere(); + const planes = material.clippingPlanes, + clipIntersection = material.clipIntersection, + clipShadows = material.clipShadows; - class Line extends Object3D { - constructor(geometry = new BufferGeometry(), material = new LineBasicMaterial()) { - super(); - this.isLine = true; - this.type = 'Line'; - this.geometry = geometry; - this.material = material; - this.updateMorphTargets(); - } + const materialProperties = properties.get( material ); - copy(source, recursive) { - super.copy(source, recursive); - this.material = source.material; - this.geometry = source.geometry; - return this; - } + if ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) { - computeLineDistances() { - const geometry = this.geometry; // we assume non-indexed geometry + // there's no local clipping - if (geometry.index === null) { - const positionAttribute = geometry.attributes.position; - const lineDistances = [0]; + if ( renderingShadows ) { + + // there's no global clipping - for (let i = 1, l = positionAttribute.count; i < l; i++) { - _start$1.fromBufferAttribute(positionAttribute, i - 1); + projectPlanes( null ); - _end$1.fromBufferAttribute(positionAttribute, i); + } else { + + resetGlobalState(); - 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 nGlobal = renderingShadows ? 0 : numGlobalPlanes, + lGlobal = nGlobal * 4; - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + let dstArray = materialProperties.clippingState || null; - _sphere$1.copy(geometry.boundingSphere); + uniform.value = dstArray; // ensure unique state - _sphere$1.applyMatrix4(matrixWorld); + dstArray = projectPlanes( planes, camera, lGlobal, useCache ); - _sphere$1.radius += threshold; - if (raycaster.ray.intersectsSphere(_sphere$1) === false) return; // + for ( let i = 0; i !== lGlobal; ++ i ) { - _inverseMatrix$1.copy(matrixWorld).invert(); + dstArray[ i ] = globalState[ i ]; - _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(); - const vEnd = new Vector3(); - const interSegment = new Vector3(); - const interRay = new Vector3(); - const step = this.isLineSegments ? 2 : 1; - const index = geometry.index; - const attributes = geometry.attributes; - const positionAttribute = attributes.position; + materialProperties.clippingState = dstArray; + this.numIntersection = clipIntersection ? this.numPlanes : 0; + this.numPlanes += nGlobal; - 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 + function resetGlobalState() { - const distance = raycaster.ray.origin.distanceTo(interRay); - if (distance < raycaster.near || distance > raycaster.far) continue; - intersects.push({ - distance: distance, - // What do we want? intersection point on the ray or on the segment?? - // point: raycaster.ray.at( distance ), - point: interSegment.clone().applyMatrix4(this.matrixWorld), - index: i, - face: null, - faceIndex: null, - object: this - }); - } - } else { - const start = Math.max(0, drawRange.start); - const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count); + if ( uniform.value !== globalState ) { - for (let i = start, l = end - 1; i < l; i += step) { - vStart.fromBufferAttribute(positionAttribute, i); - vEnd.fromBufferAttribute(positionAttribute, i + 1); + uniform.value = globalState; + uniform.needsUpdate = numGlobalPlanes > 0; - 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 + scope.numPlanes = numGlobalPlanes; + scope.numIntersection = 0; - const distance = raycaster.ray.origin.distanceTo(interRay); - if (distance < raycaster.near || distance > raycaster.far) continue; - intersects.push({ - distance: distance, - // What do we want? intersection point on the ray or on the segment?? - // point: raycaster.ray.at( distance ), - point: interSegment.clone().applyMatrix4(this.matrixWorld), - index: i, - face: null, - faceIndex: null, - object: this - }); - } - } } - updateMorphTargets() { - const geometry = this.geometry; - const morphAttributes = geometry.morphAttributes; - const keys = Object.keys(morphAttributes); + function projectPlanes( planes, camera, dstOffset, skipTransform ) { - if (keys.length > 0) { - const morphAttribute = morphAttributes[keys[0]]; + const nPlanes = planes !== null ? planes.length : 0; + let dstArray = null; - if (morphAttribute !== undefined) { - this.morphTargetInfluences = []; - this.morphTargetDictionary = {}; + if ( nPlanes !== 0 ) { - for (let m = 0, ml = morphAttribute.length; m < ml; m++) { - const name = morphAttribute[m].name || String(m); - this.morphTargetInfluences.push(0); - this.morphTargetDictionary[name] = m; - } - } - } - } + dstArray = uniform.value; - } + if ( skipTransform !== true || dstArray === null ) { - const _start = /*@__PURE__*/new Vector3(); + const flatSize = dstOffset + nPlanes * 4, + viewMatrix = camera.matrixWorldInverse; - const _end = /*@__PURE__*/new Vector3(); + viewNormalMatrix.getNormalMatrix( viewMatrix ); - class LineSegments extends Line { - constructor(geometry, material) { - super(geometry, material); - this.isLineSegments = true; - this.type = 'LineSegments'; - } + if ( dstArray === null || dstArray.length < flatSize ) { - computeLineDistances() { - const geometry = this.geometry; // we assume non-indexed geometry + dstArray = new Float32Array( flatSize ); - if (geometry.index === null) { - const positionAttribute = geometry.attributes.position; - const lineDistances = []; + } + + for ( let i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) { - for (let i = 0, l = positionAttribute.count; i < l; i += 2) { - _start.fromBufferAttribute(positionAttribute, i); + plane.copy( planes[ i ] ).applyMatrix4( viewMatrix, viewNormalMatrix ); - _end.fromBufferAttribute(positionAttribute, i + 1); + plane.normal.toArray( dstArray, i4 ); + dstArray[ i4 + 3 ] = plane.constant; + + } - 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.'); + uniform.value = dstArray; + uniform.needsUpdate = true; + } - return this; - } + scope.numPlanes = nPlanes; + scope.numIntersection = 0; - } + return dstArray; - class LineLoop extends Line { - constructor(geometry, material) { - super(geometry, material); - this.isLineLoop = true; - this.type = 'LineLoop'; } } - class PointsMaterial extends Material { - constructor(parameters) { - super(); - this.isPointsMaterial = true; - this.type = 'PointsMaterial'; - this.color = new Color(0xffffff); - this.map = null; - this.alphaMap = null; - this.size = 1; - this.sizeAttenuation = true; - this.fog = true; - this.setValues(parameters); - } + function WebGLCubeMaps( renderer ) { - copy(source) { - super.copy(source); - this.color.copy(source.color); - this.map = source.map; - this.alphaMap = source.alphaMap; - this.size = source.size; - this.sizeAttenuation = source.sizeAttenuation; - this.fog = source.fog; - return this; - } + let cubemaps = new WeakMap(); - } + function mapTextureMapping( texture, mapping ) { - const _inverseMatrix = /*@__PURE__*/new Matrix4(); + if ( mapping === EquirectangularReflectionMapping ) { + + texture.mapping = CubeReflectionMapping; - const _ray = /*@__PURE__*/new Ray(); + } else if ( mapping === EquirectangularRefractionMapping ) { - const _sphere = /*@__PURE__*/new Sphere(); + texture.mapping = CubeRefractionMapping; - const _position$2 = /*@__PURE__*/new Vector3(); + } - class Points extends Object3D { - constructor(geometry = new BufferGeometry(), material = new PointsMaterial()) { - super(); - this.isPoints = true; - this.type = 'Points'; - this.geometry = geometry; - this.material = material; - this.updateMorphTargets(); - } + return texture; - 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 - - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + function get( texture ) { - _sphere.copy(geometry.boundingSphere); + if ( texture && texture.isTexture && texture.isRenderTargetTexture === false ) { - _sphere.applyMatrix4(matrixWorld); + const mapping = texture.mapping; - _sphere.radius += threshold; - if (raycaster.ray.intersectsSphere(_sphere) === false) return; // + if ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping ) { - _inverseMatrix.copy(matrixWorld).invert(); + if ( cubemaps.has( texture ) ) { - _ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix); + const cubemap = cubemaps.get( texture ).texture; + return mapTextureMapping( cubemap, texture.mapping ); - 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; + } else { - if (index !== null) { - const start = Math.max(0, drawRange.start); - const end = Math.min(index.count, drawRange.start + drawRange.count); + const image = texture.image; - for (let i = start, il = end; i < il; i++) { - const a = index.getX(i); + if ( image && image.height > 0 ) { - _position$2.fromBufferAttribute(positionAttribute, a); + const renderTarget = new WebGLCubeRenderTarget( image.height / 2 ); + renderTarget.fromEquirectangularTexture( renderer, texture ); + cubemaps.set( texture, renderTarget ); - 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); + texture.addEventListener( 'dispose', onTextureDispose ); - for (let i = start, l = end; i < l; i++) { - _position$2.fromBufferAttribute(positionAttribute, i); + return mapTextureMapping( renderTarget.texture, texture.mapping ); - testPoint(_position$2, i, localThresholdSq, matrixWorld, raycaster, intersects, this); - } - } - } + } else { - updateMorphTargets() { - const geometry = this.geometry; - const morphAttributes = geometry.morphAttributes; - const keys = Object.keys(morphAttributes); + // image not yet ready. try the conversion next frame - if (keys.length > 0) { - const morphAttribute = morphAttributes[keys[0]]; + return null; - 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); - this.morphTargetDictionary[name] = m; } + } + } + + return texture; + } - } + function onTextureDispose( event ) { - function testPoint(point, index, localThresholdSq, matrixWorld, raycaster, intersects, object) { - const rayPointDistanceSq = _ray.distanceSqToPoint(point); + const texture = event.target; - if (rayPointDistanceSq < localThresholdSq) { - const intersectPoint = new Vector3(); + texture.removeEventListener( 'dispose', onTextureDispose ); - _ray.closestPointToPoint(point, intersectPoint); + const cubemap = cubemaps.get( texture ); - intersectPoint.applyMatrix4(matrixWorld); - const distance = raycaster.ray.origin.distanceTo(intersectPoint); - if (distance < raycaster.near || distance > raycaster.far) return; - intersects.push({ - distance: distance, - distanceToRay: Math.sqrt(rayPointDistanceSq), - point: intersectPoint, - index: index, - face: null, - object: object - }); - } - } + if ( cubemap !== undefined ) { - class VideoTexture extends Texture { - constructor(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) { - super(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); - this.isVideoTexture = true; - this.minFilter = minFilter !== undefined ? minFilter : LinearFilter; - this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; - this.generateMipmaps = false; - const scope = this; + cubemaps.delete( texture ); + cubemap.dispose(); - function updateVideo() { - scope.needsUpdate = true; - video.requestVideoFrameCallback(updateVideo); } - if ('requestVideoFrameCallback' in video) { - video.requestVideoFrameCallback(updateVideo); - } } - clone() { - return new this.constructor(this.image).copy(this); - } + function dispose() { - update() { - const video = this.image; - const hasVideoFrameCallback = ('requestVideoFrameCallback' in video); + cubemaps = new WeakMap(); - if (hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA) { - this.needsUpdate = true; - } } - } - - class FramebufferTexture extends Texture { - constructor(width, height, format) { - super({ - width, - height - }); - this.isFramebufferTexture = true; - this.format = format; - this.magFilter = NearestFilter; - this.minFilter = NearestFilter; - this.generateMipmaps = false; - this.needsUpdate = true; - } + return { + get: get, + dispose: dispose + }; } - class CompressedTexture extends Texture { - constructor(mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding) { - super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); - this.isCompressedTexture = true; - this.image = { - width: width, - height: height - }; - this.mipmaps = mipmaps; // no flipping for cube textures - // (also flipping doesn't work for compressed textures ) + class OrthographicCamera extends Camera { - this.flipY = false; // can't generate mipmaps for compressed textures - // mips must be embedded in DDS files + constructor( left = - 1, right = 1, top = 1, bottom = - 1, near = 0.1, far = 2000 ) { - this.generateMipmaps = false; - } + super(); - } + this.isOrthographicCamera = true; - class CanvasTexture extends Texture { - constructor(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) { - super(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); - this.isCanvasTexture = true; - this.needsUpdate = true; - } + this.type = 'OrthographicCamera'; - } + this.zoom = 1; + this.view = null; - /** - * Extensible curve object. - * - * Some common of curve methods: - * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget ) - * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget ) - * .getPoints(), .getSpacedPoints() - * .getLength() - * .updateArcLengths() - * - * This following curves inherit from THREE.Curve: - * - * -- 2D curves -- - * THREE.ArcCurve - * THREE.CubicBezierCurve - * THREE.EllipseCurve - * THREE.LineCurve - * THREE.QuadraticBezierCurve - * THREE.SplineCurve - * - * -- 3D curves -- - * THREE.CatmullRomCurve3 - * THREE.CubicBezierCurve3 - * THREE.LineCurve3 - * THREE.QuadraticBezierCurve3 - * - * A series of curves can be represented as a THREE.CurvePath. - * - **/ + this.left = left; + this.right = right; + this.top = top; + this.bottom = bottom; - class Curve { - constructor() { - this.type = 'Curve'; - this.arcLengthDivisions = 200; - } // Virtual base class method to overwrite and implement in subclasses - // - t [0 .. 1] + this.near = near; + this.far = far; + this.updateProjectionMatrix(); - getPoint() { - console.warn('THREE.Curve: .getPoint() not implemented.'); - return null; - } // Get point at relative position in curve according to arc length - // - u [0 .. 1] + } + copy( source, recursive ) { - getPointAt(u, optionalTarget) { - const t = this.getUtoTmapping(u); - return this.getPoint(t, optionalTarget); - } // Get sequence of points using getPoint( t ) + super.copy( source, recursive ); + this.left = source.left; + this.right = source.right; + this.top = source.top; + this.bottom = source.bottom; + this.near = source.near; + this.far = source.far; - getPoints(divisions = 5) { - const points = []; + this.zoom = source.zoom; + this.view = source.view === null ? null : Object.assign( {}, source.view ); - for (let d = 0; d <= divisions; d++) { - points.push(this.getPoint(d / divisions)); - } + return this; - return points; - } // Get sequence of points using getPointAt( u ) + } + setViewOffset( fullWidth, fullHeight, x, y, width, height ) { - getSpacedPoints(divisions = 5) { - const points = []; + if ( this.view === null ) { + + this.view = { + enabled: true, + fullWidth: 1, + fullHeight: 1, + offsetX: 0, + offsetY: 0, + width: 1, + height: 1 + }; - for (let d = 0; d <= divisions; d++) { - points.push(this.getPointAt(d / divisions)); } - return points; - } // Get total curve arc length + this.view.enabled = true; + this.view.fullWidth = fullWidth; + this.view.fullHeight = fullHeight; + this.view.offsetX = x; + this.view.offsetY = y; + this.view.width = width; + this.view.height = height; + this.updateProjectionMatrix(); - getLength() { - const lengths = this.getLengths(); - return lengths[lengths.length - 1]; - } // Get list of cumulative segment lengths + } + clearViewOffset() { + + if ( this.view !== null ) { + + this.view.enabled = false; - 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); - let sum = 0; - cache.push(0); + this.updateProjectionMatrix(); + + } + + updateProjectionMatrix() { + + const dx = ( this.right - this.left ) / ( 2 * this.zoom ); + const dy = ( this.top - this.bottom ) / ( 2 * this.zoom ); + const cx = ( this.right + this.left ) / 2; + const cy = ( this.top + this.bottom ) / 2; + + let left = cx - dx; + let right = cx + dx; + let top = cy + dy; + let bottom = cy - dy; + + if ( this.view !== null && this.view.enabled ) { + + const scaleW = ( this.right - this.left ) / this.view.fullWidth / this.zoom; + const scaleH = ( this.top - this.bottom ) / this.view.fullHeight / this.zoom; + + left += scaleW * this.view.offsetX; + right = left + scaleW * this.view.width; + top -= scaleH * this.view.offsetY; + bottom = top - scaleH * this.view.height; - 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. + this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far ); + + this.projectionMatrixInverse.copy( this.projectionMatrix ).invert(); + } - updateArcLengths() { - this.needsUpdate = true; - this.getLengths(); - } // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant + toJSON( meta ) { + const data = super.toJSON( meta ); - getUtoTmapping(u, distance) { - const arcLengths = this.getLengths(); - let i = 0; - const il = arcLengths.length; - let targetArcLength; // The targeted u distance value to get + data.object.zoom = this.zoom; + data.object.left = this.left; + data.object.right = this.right; + data.object.top = this.top; + data.object.bottom = this.bottom; + data.object.near = this.near; + data.object.far = this.far; - if (distance) { - targetArcLength = distance; - } else { - targetArcLength = u * arcLengths[il - 1]; - } // binary search for the index with largest value smaller than target u distance + if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); + return data; - let low = 0, - high = il - 1, - comparison; + } - while (low <= high) { - i = Math.floor(low + (high - low) / 2); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats + } - comparison = arcLengths[i] - targetArcLength; + const LOD_MIN = 4; - if (comparison < 0) { - low = i + 1; - } else if (comparison > 0) { - high = i - 1; - } else { - high = i; - break; // DONE - } - } + // 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 ]; - i = high; + // 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; - if (arcLengths[i] === targetArcLength) { - return i / (il - 1); - } // we could get finer grain at lengths, or use simple interpolation between two points + const _flatCamera = /*@__PURE__*/ new OrthographicCamera(); + const _clearColor = /*@__PURE__*/ new Color(); + let _oldTarget = null; + + // 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 _axisDirections = [ + /*@__PURE__*/ new Vector3( 1, 1, 1 ), + /*@__PURE__*/ new Vector3( - 1, 1, 1 ), + /*@__PURE__*/ new Vector3( 1, 1, - 1 ), + /*@__PURE__*/ new Vector3( - 1, 1, - 1 ), + /*@__PURE__*/ new Vector3( 0, PHI, INV_PHI ), + /*@__PURE__*/ new Vector3( 0, PHI, - INV_PHI ), + /*@__PURE__*/ new Vector3( INV_PHI, 0, PHI ), + /*@__PURE__*/ new Vector3( - INV_PHI, 0, PHI ), + /*@__PURE__*/ new Vector3( PHI, INV_PHI, 0 ), + /*@__PURE__*/ new Vector3( - PHI, INV_PHI, 0 ) ]; + + /** + * This class generates a Prefiltered, Mipmapped Radiance Environment Map + * (PMREM) from a cubeMap environment texture. This allows different levels of + * blur to be quickly accessed based on material roughness. It is packed into a + * special CubeUV format that allows us to perform custom interpolation so that + * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap + * chain, it only goes down to the LOD_MIN level (above), and then creates extra + * even more filtered 'mips' at the same LOD_MIN resolution, associated with + * higher roughness levels. In this way we maintain resolution to smoothly + * interpolate diffuse lighting while limiting sampling computation. + * + * Paper: Fast, Accurate Image-Based Lighting + * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view + */ + class PMREMGenerator { - const lengthBefore = arcLengths[i]; - const lengthAfter = arcLengths[i + 1]; - const segmentLength = lengthAfter - lengthBefore; // determine where we are between the 'before' and 'after' points + constructor( renderer ) { - const segmentFraction = (targetArcLength - lengthBefore) / segmentLength; // add that fractional amount to t + this._renderer = renderer; + this._pingPongRenderTarget = null; - const t = (i + segmentFraction) / (il - 1); - return t; - } // Returns a unit vector tangent at t - // In case any sub curve does not implement its tangent derivation, - // 2 points a small delta apart will be used to find its gradient - // which seems to give a reasonable approximation + this._lodMax = 0; + this._cubeSize = 0; + this._lodPlanes = []; + this._sizeLods = []; + this._sigmas = []; + this._blurMaterial = null; + this._cubemapMaterial = null; + this._equirectMaterial = null; - getTangent(t, optionalTarget) { - const delta = 0.0001; - let t1 = t - delta; - let t2 = t + delta; // Capping in case of danger - - if (t1 < 0) t1 = 0; - if (t2 > 1) t2 = 1; - const pt1 = this.getPoint(t1); - const pt2 = this.getPoint(t2); - const tangent = optionalTarget || (pt1.isVector2 ? new Vector2() : new Vector3()); - tangent.copy(pt2).sub(pt1).normalize(); - return tangent; - } + this._compileMaterial( this._blurMaterial ); - 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 + /** + * Generates a PMREM from a supplied Scene, which can be faster than using an + * image if networking bandwidth is low. Optional sigma specifies a blur radius + * in radians to be applied to the scene before PMREM generation. Optional near + * and far planes ensure the scene is rendered in its entirety (the cubeCamera + * is placed at the origin). + */ + fromScene( scene, sigma = 0, near = 0.1, far = 100 ) { - 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 + _oldTarget = this._renderer.getRenderTarget(); + this._setSize( 256 ); - normals[0] = new Vector3(); - binormals[0] = new Vector3(); - let min = Number.MAX_VALUE; - const tx = Math.abs(tangents[0].x); - const ty = Math.abs(tangents[0].y); - const tz = Math.abs(tangents[0].z); + const cubeUVRenderTarget = this._allocateTargets(); + cubeUVRenderTarget.depthBuffer = true; - if (tx <= min) { - min = tx; - normal.set(1, 0, 0); - } + this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget ); - if (ty <= min) { - min = ty; - normal.set(0, 1, 0); - } + if ( sigma > 0 ) { + + this._blur( cubeUVRenderTarget, 0, 0, sigma ); - 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 + this._applyPMREM( cubeUVRenderTarget ); + this._cleanup( cubeUVRenderTarget ); - 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]); + return cubeUVRenderTarget; - 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)); - } + /** + * 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 ) { - 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 + return this._fromTexture( equirectangular, renderTarget ); + } - if (closed === true) { - let theta = Math.acos(clamp(normals[0].dot(normals[segments]), -1, 1)); - theta /= segments; + /** + * 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 ) { - if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) { - theta = -theta; - } + 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 ); - 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); - } + /** + * 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() { - copy(source) { - this.arcLengthDivisions = source.arcLengthDivisions; - return this; - } + if ( this._equirectMaterial === null ) { + + this._equirectMaterial = _getEquirectMaterial(); + this._compileMaterial( this._equirectMaterial ); + + } - toJSON() { - const data = { - metadata: { - version: 4.5, - type: 'Curve', - generator: 'Curve.toJSON' - } - }; - data.arcLengthDivisions = this.arcLengthDivisions; - data.type = this.type; - return data; } - fromJSON(json) { - this.arcLengthDivisions = json.arcLengthDivisions; - return this; + /** + * 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 + + _setSize( cubeSize ) { + + this._lodMax = Math.floor( Math.log2( cubeSize ) ); + this._cubeSize = Math.pow( 2, this._lodMax ); - class EllipseCurve extends Curve { - constructor(aX = 0, aY = 0, xRadius = 1, yRadius = 1, aStartAngle = 0, aEndAngle = Math.PI * 2, aClockwise = false, aRotation = 0) { - super(); - this.isEllipseCurve = true; - this.type = 'EllipseCurve'; - this.aX = aX; - this.aY = aY; - this.xRadius = xRadius; - this.yRadius = yRadius; - this.aStartAngle = aStartAngle; - this.aEndAngle = aEndAngle; - 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 + _dispose() { - while (deltaAngle < 0) deltaAngle += twoPi; + if ( this._blurMaterial !== null ) this._blurMaterial.dispose(); - while (deltaAngle > twoPi) deltaAngle -= twoPi; + if ( this._pingPongRenderTarget !== null ) this._pingPongRenderTarget.dispose(); - if (deltaAngle < Number.EPSILON) { - if (samePoints) { - deltaAngle = 0; - } else { - deltaAngle = twoPi; - } - } + for ( let i = 0; i < this._lodPlanes.length; i ++ ) { + + this._lodPlanes[ i ].dispose(); - if (this.aClockwise === true && !samePoints) { - if (deltaAngle === twoPi) { - deltaAngle = -twoPi; - } else { - 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. + _cleanup( outputTarget ) { - x = tx * cos - ty * sin + this.aX; - y = tx * sin + ty * cos + this.aY; - } + this._renderer.setRenderTarget( _oldTarget ); + outputTarget.scissorTest = false; + _setViewport( outputTarget, 0, 0, outputTarget.width, outputTarget.height ); - return point.set(x, y); } - copy(source) { - super.copy(source); - this.aX = source.aX; - this.aY = source.aY; - this.xRadius = source.xRadius; - this.yRadius = source.yRadius; - this.aStartAngle = source.aStartAngle; - this.aEndAngle = source.aEndAngle; - this.aClockwise = source.aClockwise; - this.aRotation = source.aRotation; - return this; - } - - toJSON() { - const data = super.toJSON(); - data.aX = this.aX; - data.aY = this.aY; - data.xRadius = this.xRadius; - data.yRadius = this.yRadius; - data.aStartAngle = this.aStartAngle; - data.aEndAngle = this.aEndAngle; - data.aClockwise = this.aClockwise; - data.aRotation = this.aRotation; - return data; - } + _fromTexture( texture, renderTarget ) { - fromJSON(json) { - super.fromJSON(json); - this.aX = json.aX; - this.aY = json.aY; - this.xRadius = json.xRadius; - this.yRadius = json.yRadius; - this.aStartAngle = json.aStartAngle; - this.aEndAngle = json.aEndAngle; - this.aClockwise = json.aClockwise; - this.aRotation = json.aRotation; - return this; - } + if ( texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping ) { - } + this._setSize( texture.image.length === 0 ? 16 : ( texture.image[ 0 ].width || texture.image[ 0 ].image.width ) ); - class ArcCurve extends EllipseCurve { - constructor(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { - super(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); - this.isArcCurve = true; - this.type = 'ArcCurve'; - } + } else { // Equirectangular - } + this._setSize( texture.image.width / 4 ); - /** - * Centripetal CatmullRom Curve - which is useful for avoiding - * cusps and self-intersections in non-uniform catmull rom curves. - * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf - * - * curve.type accepts centripetal(default), chordal and catmullrom - * curve.tension is used for catmullrom which defaults to 0.5 - */ + } - /* - Based on an optimized c++ solution in - - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/ - - http://ideone.com/NoEbVM + _oldTarget = this._renderer.getRenderTarget(); - This CubicPoly class could be used for reusing some variables and calculations, - but for three.js curve use, it could be possible inlined and flatten into a single function call - which can be placed in CurveUtils. - */ + const cubeUVRenderTarget = renderTarget || this._allocateTargets(); + this._textureToCubeUV( texture, cubeUVRenderTarget ); + this._applyPMREM( cubeUVRenderTarget ); + this._cleanup( cubeUVRenderTarget ); - function CubicPoly() { - let c0 = 0, - c1 = 0, - c2 = 0, - c3 = 0; - /* - * Compute coefficients for a cubic polynomial - * p(s) = c0 + c1*s + c2*s^2 + c3*s^3 - * such that - * p(0) = x0, p(1) = x1 - * and - * p'(0) = t0, p'(1) = t1. - */ + return cubeUVRenderTarget; - 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)); - }, - 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] - - t1 *= dt1; - t2 *= dt1; - init(x1, x2, t1, t2); - }, - calc: function (t) { - const t2 = t * t; - const t3 = t2 * t; - return c0 + c1 * t + c2 * t2 + c3 * t3; - } - }; - } // - + _allocateTargets() { - const tmp = new Vector3(); - const px = new CubicPoly(), - py = new CubicPoly(), - pz = new CubicPoly(); + const width = 3 * Math.max( this._cubeSize, 16 * 7 ); + const height = 4 * this._cubeSize; - class CatmullRomCurve3 extends Curve { - constructor(points = [], closed = false, curveType = 'centripetal', tension = 0.5) { - super(); - this.isCatmullRomCurve3 = true; - this.type = 'CatmullRomCurve3'; - this.points = points; - this.closed = closed; - this.curveType = curveType; - this.tension = tension; - } + const params = { + magFilter: LinearFilter, + minFilter: LinearFilter, + generateMipmaps: false, + type: HalfFloatType, + format: RGBAFormat, + encoding: LinearEncoding, + depthBuffer: false + }; - getPoint(t, optionalTarget = new Vector3()) { - const point = optionalTarget; - const points = this.points; - const l = points.length; - const p = (l - (this.closed ? 0 : 1)) * t; - let intPoint = Math.floor(p); - let weight = p - intPoint; + const cubeUVRenderTarget = _createRenderTarget( width, height, params ); - 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; - } + if ( this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width || this._pingPongRenderTarget.height !== height ) { - let p0, p3; // 4 points (p1 & p2 defined below) + if ( this._pingPongRenderTarget !== null ) { - if (this.closed || intPoint > 0) { - p0 = points[(intPoint - 1) % l]; - } else { - // extrapolate first point - tmp.subVectors(points[0], points[1]).add(points[0]); - p0 = tmp; - } + this._dispose(); - const p1 = points[intPoint % l]; - const p2 = points[(intPoint + 1) % l]; + } - if (this.closed || intPoint + 2 < l) { - p3 = points[(intPoint + 2) % l]; - } else { - // extrapolate last point - tmp.subVectors(points[l - 1], points[l - 2]).add(points[l - 1]); - p3 = tmp; - } + this._pingPongRenderTarget = _createRenderTarget( width, height, params ); - 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 - - if (dt1 < 1e-4) dt1 = 1.0; - if (dt0 < 1e-4) dt0 = dt1; - if (dt2 < 1e-4) dt2 = dt1; - px.initNonuniformCatmullRom(p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2); - py.initNonuniformCatmullRom(p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2); - pz.initNonuniformCatmullRom(p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2); - } else if (this.curveType === 'catmullrom') { - px.initCatmullRom(p0.x, p1.x, p2.x, p3.x, this.tension); - py.initCatmullRom(p0.y, p1.y, p2.y, p3.y, this.tension); - pz.initCatmullRom(p0.z, p1.z, p2.z, p3.z, this.tension); - } - - point.set(px.calc(weight), py.calc(weight), pz.calc(weight)); - return point; - } + const { _lodMax } = this; + ( { sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas } = _createPlanes( _lodMax ) ); - copy(source) { - super.copy(source); - this.points = []; + this._blurMaterial = _getBlurShader( _lodMax, width, height ); - 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; + return cubeUVRenderTarget; + } - toJSON() { - const data = super.toJSON(); - data.points = []; + _compileMaterial( material ) { - for (let i = 0, l = this.points.length; i < l; i++) { - const point = this.points[i]; - data.points.push(point.toArray()); - } + const tmpMesh = new Mesh( this._lodPlanes[ 0 ], material ); + this._renderer.compile( tmpMesh, _flatCamera ); - data.closed = this.closed; - data.curveType = this.curveType; - data.tension = this.tension; - return data; } - fromJSON(json) { - super.fromJSON(json); - this.points = []; + _sceneToCubeUV( scene, near, far, cubeUVRenderTarget ) { - for (let i = 0, l = json.points.length; i < l; i++) { - const point = json.points[i]; - this.points.push(new Vector3().fromArray(point)); - } + const fov = 90; + const aspect = 1; + const cubeCamera = new PerspectiveCamera( fov, aspect, near, far ); + const upSign = [ 1, - 1, 1, 1, 1, 1 ]; + const forwardSign = [ 1, 1, 1, - 1, - 1, - 1 ]; + const renderer = this._renderer; - this.closed = json.closed; - this.curveType = json.curveType; - this.tension = json.tension; - return this; - } + const originalAutoClear = renderer.autoClear; + const toneMapping = renderer.toneMapping; + renderer.getClearColor( _clearColor ); - } + renderer.toneMapping = NoToneMapping; + renderer.autoClear = false; - /** - * 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; - } // + const backgroundMaterial = new MeshBasicMaterial( { + name: 'PMREM.Background', + side: BackSide, + depthWrite: false, + depthTest: false, + } ); + const backgroundBox = new Mesh( new BoxGeometry(), backgroundMaterial ); - function QuadraticBezierP0(t, p) { - const k = 1 - t; - return k * k * p; - } + let useSolidColor = false; + const background = scene.background; - function QuadraticBezierP1(t, p) { - return 2 * (1 - t) * t * p; - } + if ( background ) { - function QuadraticBezierP2(t, p) { - return t * t * p; - } + if ( background.isColor ) { - function QuadraticBezier(t, p0, p1, p2) { - return QuadraticBezierP0(t, p0) + QuadraticBezierP1(t, p1) + QuadraticBezierP2(t, p2); - } // + backgroundMaterial.color.copy( background ); + scene.background = null; + useSolidColor = true; + } - function CubicBezierP0(t, p) { - const k = 1 - t; - return k * k * k * p; - } + } else { - function CubicBezierP1(t, p) { - const k = 1 - t; - return 3 * k * k * t * p; - } + backgroundMaterial.color.copy( _clearColor ); + useSolidColor = true; - function CubicBezierP2(t, p) { - return 3 * (1 - t) * t * t * p; - } + } - function CubicBezierP3(t, p) { - return t * t * t * p; - } + for ( let i = 0; i < 6; i ++ ) { - function CubicBezier(t, p0, p1, p2, p3) { - return CubicBezierP0(t, p0) + CubicBezierP1(t, p1) + CubicBezierP2(t, p2) + CubicBezierP3(t, p3); - } + const col = i % 3; - class CubicBezierCurve extends Curve { - constructor(v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2(), v3 = new Vector2()) { - super(); - this.isCubicBezierCurve = true; - this.type = 'CubicBezierCurve'; - this.v0 = v0; - this.v1 = v1; - this.v2 = v2; - this.v3 = v3; - } + if ( col === 0 ) { - getPoint(t, optionalTarget = new Vector2()) { - const point = optionalTarget; - const v0 = this.v0, - v1 = this.v1, - v2 = this.v2, - v3 = this.v3; - point.set(CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.y, v3.y)); - return point; - } + cubeCamera.up.set( 0, upSign[ i ], 0 ); + cubeCamera.lookAt( forwardSign[ i ], 0, 0 ); - copy(source) { - super.copy(source); - this.v0.copy(source.v0); - this.v1.copy(source.v1); - this.v2.copy(source.v2); - this.v3.copy(source.v3); - return this; - } + } else if ( col === 1 ) { - toJSON() { - const data = super.toJSON(); - data.v0 = this.v0.toArray(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); - data.v3 = this.v3.toArray(); - return data; - } + cubeCamera.up.set( 0, 0, upSign[ i ] ); + cubeCamera.lookAt( 0, forwardSign[ i ], 0 ); - fromJSON(json) { - super.fromJSON(json); - this.v0.fromArray(json.v0); - this.v1.fromArray(json.v1); - this.v2.fromArray(json.v2); - this.v3.fromArray(json.v3); - return this; - } + } else { - } + cubeCamera.up.set( 0, upSign[ i ], 0 ); + cubeCamera.lookAt( 0, 0, forwardSign[ i ] ); - class CubicBezierCurve3 extends Curve { - constructor(v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3(), v3 = new Vector3()) { - super(); - this.isCubicBezierCurve3 = true; - this.type = 'CubicBezierCurve3'; - this.v0 = v0; - this.v1 = v1; - 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; - 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; - } + const size = this._cubeSize; - copy(source) { - super.copy(source); - this.v0.copy(source.v0); - this.v1.copy(source.v1); - this.v2.copy(source.v2); - this.v3.copy(source.v3); - return this; - } + _setViewport( cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size ); - toJSON() { - const data = super.toJSON(); - data.v0 = this.v0.toArray(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); - data.v3 = this.v3.toArray(); - return data; - } + renderer.setRenderTarget( cubeUVRenderTarget ); - fromJSON(json) { - super.fromJSON(json); - this.v0.fromArray(json.v0); - this.v1.fromArray(json.v1); - this.v2.fromArray(json.v2); - this.v3.fromArray(json.v3); - return this; - } + if ( useSolidColor ) { - } + renderer.render( backgroundBox, cubeCamera ); - class LineCurve extends Curve { - constructor(v1 = new Vector2(), v2 = new Vector2()) { - super(); - this.isLineCurve = true; - this.type = 'LineCurve'; - this.v1 = v1; - this.v2 = v2; - } + } - getPoint(t, optionalTarget = new Vector2()) { - const point = optionalTarget; + renderer.render( scene, cubeCamera ); - 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 + backgroundBox.geometry.dispose(); + backgroundBox.material.dispose(); + renderer.toneMapping = toneMapping; + renderer.autoClear = originalAutoClear; + scene.background = background; - 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; - } + _textureToCubeUV( texture, cubeUVRenderTarget ) { - copy(source) { - super.copy(source); - this.v1.copy(source.v1); - this.v2.copy(source.v2); - return this; - } + const renderer = this._renderer; - toJSON() { - const data = super.toJSON(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); - return data; - } + const isCubeTexture = ( texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping ); - fromJSON(json) { - super.fromJSON(json); - this.v1.fromArray(json.v1); - this.v2.fromArray(json.v2); - return this; - } + if ( isCubeTexture ) { - } + if ( this._cubemapMaterial === null ) { - class LineCurve3 extends Curve { - constructor(v1 = new Vector3(), v2 = new Vector3()) { - super(); - this.isLineCurve3 = true; - this.type = 'LineCurve3'; - this.v1 = v1; - this.v2 = v2; - } + this._cubemapMaterial = _getCubemapMaterial(); - getPoint(t, optionalTarget = new Vector3()) { - const point = optionalTarget; + } + + this._cubemapMaterial.uniforms.flipEnvMap.value = ( texture.isRenderTargetTexture === false ) ? - 1 : 1; - 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 + if ( this._equirectMaterial === null ) { + this._equirectMaterial = _getEquirectMaterial(); - 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; - } + const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; + const mesh = new Mesh( this._lodPlanes[ 0 ], material ); - fromJSON(json) { - super.fromJSON(json); - this.v1.fromArray(json.v1); - this.v2.fromArray(json.v2); - return this; - } + const uniforms = material.uniforms; - } + uniforms[ 'envMap' ].value = texture; - class QuadraticBezierCurve extends Curve { - constructor(v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2()) { - super(); - this.isQuadraticBezierCurve = true; - this.type = 'QuadraticBezierCurve'; - this.v0 = v0; - this.v1 = v1; - this.v2 = v2; - } + const size = this._cubeSize; - getPoint(t, optionalTarget = new Vector2()) { - const point = optionalTarget; - const v0 = this.v0, - v1 = this.v1, - v2 = this.v2; - point.set(QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y)); - return point; - } + _setViewport( cubeUVRenderTarget, 0, 0, 3 * size, 2 * size ); - copy(source) { - super.copy(source); - this.v0.copy(source.v0); - this.v1.copy(source.v1); - this.v2.copy(source.v2); - return this; - } + renderer.setRenderTarget( cubeUVRenderTarget ); + renderer.render( mesh, _flatCamera ); - toJSON() { - const data = super.toJSON(); - data.v0 = this.v0.toArray(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); - return data; } - fromJSON(json) { - super.fromJSON(json); - this.v0.fromArray(json.v0); - this.v1.fromArray(json.v1); - this.v2.fromArray(json.v2); - return this; - } + _applyPMREM( cubeUVRenderTarget ) { - } + const renderer = this._renderer; + const autoClear = renderer.autoClear; + renderer.autoClear = false; - class QuadraticBezierCurve3 extends Curve { - constructor(v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3()) { - super(); - this.isQuadraticBezierCurve3 = true; - this.type = 'QuadraticBezierCurve3'; - this.v0 = v0; - this.v1 = v1; - this.v2 = v2; - } + for ( let i = 1; i < this._lodPlanes.length; i ++ ) { - getPoint(t, optionalTarget = new Vector3()) { - const point = optionalTarget; - const v0 = this.v0, - v1 = this.v1, - v2 = this.v2; - point.set(QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y), QuadraticBezier(t, v0.z, v1.z, v2.z)); - return point; - } + const sigma = Math.sqrt( this._sigmas[ i ] * this._sigmas[ i ] - this._sigmas[ i - 1 ] * this._sigmas[ i - 1 ] ); - copy(source) { - super.copy(source); - this.v0.copy(source.v0); - this.v1.copy(source.v1); - this.v2.copy(source.v2); - return this; - } + const poleAxis = _axisDirections[ ( i - 1 ) % _axisDirections.length ]; - toJSON() { - const data = super.toJSON(); - data.v0 = this.v0.toArray(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); - return data; - } + this._blur( cubeUVRenderTarget, i - 1, i, sigma, poleAxis ); - fromJSON(json) { - super.fromJSON(json); - this.v0.fromArray(json.v0); - this.v1.fromArray(json.v1); - this.v2.fromArray(json.v2); - return this; - } + } - } + renderer.autoClear = autoClear; - class SplineCurve extends Curve { - constructor(points = []) { - super(); - this.isSplineCurve = true; - this.type = 'SplineCurve'; - this.points = points; } - getPoint(t, optionalTarget = new Vector2()) { - const point = optionalTarget; - const points = this.points; - const p = (points.length - 1) * t; - const intPoint = Math.floor(p); - const weight = p - intPoint; - const p0 = points[intPoint === 0 ? intPoint : intPoint - 1]; - const p1 = points[intPoint]; - const p2 = points[intPoint > points.length - 2 ? points.length - 1 : intPoint + 1]; - const p3 = points[intPoint > points.length - 3 ? points.length - 1 : intPoint + 2]; - point.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y)); - return point; - } + /** + * This is a two-pass Gaussian blur for a cubemap. Normally this is done + * vertically and horizontally, but this breaks down on a cube. Here we apply + * the blur latitudinally (around the poles), and then longitudinally (towards + * the poles) to approximate the orthogonally-separable blur. It is least + * accurate at the poles, but still does a decent job. + */ + _blur( cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis ) { - copy(source) { - super.copy(source); - this.points = []; + const pingPongRenderTarget = this._pingPongRenderTarget; - for (let i = 0, l = source.points.length; i < l; i++) { - const point = source.points[i]; - this.points.push(point.clone()); - } + this._halfBlur( + cubeUVRenderTarget, + pingPongRenderTarget, + lodIn, + lodOut, + sigma, + 'latitudinal', + poleAxis ); + + this._halfBlur( + pingPongRenderTarget, + cubeUVRenderTarget, + lodOut, + lodOut, + sigma, + 'longitudinal', + poleAxis ); - return this; } - toJSON() { - const data = super.toJSON(); - data.points = []; + _halfBlur( targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis ) { - for (let i = 0, l = this.points.length; i < l; i++) { - const point = this.points[i]; - data.points.push(point.toArray()); - } + const renderer = this._renderer; + const blurMaterial = this._blurMaterial; - return data; - } + if ( direction !== 'latitudinal' && direction !== 'longitudinal' ) { - fromJSON(json) { - super.fromJSON(json); - this.points = []; + console.error( + 'blur direction must be either latitudinal or longitudinal!' ); - 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; - } + // 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; - var Curves = /*#__PURE__*/Object.freeze({ - __proto__: null, - ArcCurve: ArcCurve, - CatmullRomCurve3: CatmullRomCurve3, - CubicBezierCurve: CubicBezierCurve, - CubicBezierCurve3: CubicBezierCurve3, - EllipseCurve: EllipseCurve, - LineCurve: LineCurve, - LineCurve3: LineCurve3, - QuadraticBezierCurve: QuadraticBezierCurve, - QuadraticBezierCurve3: QuadraticBezierCurve3, - SplineCurve: SplineCurve - }); + const pixels = this._sizeLods[ lodIn ] - 1; + 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; - /************************************************************** - * Curved Path - a curve path is simply a array of connected - * curves, but retains the api of a curve - **************************************************************/ + if ( samples > MAX_SAMPLES ) { - class CurvePath extends Curve { - constructor() { - super(); - this.type = 'CurvePath'; - this.curves = []; - this.autoClose = false; // Automatically closes the path - } + console.warn( `sigmaRadians, ${ + sigmaRadians}, is too large and will clip, as it requested ${ + samples} samples when the maximum is set to ${MAX_SAMPLES}` ); - 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); + const weights = []; + let sum = 0; - if (!startPoint.equals(endPoint)) { - this.curves.push(new LineCurve(endPoint, startPoint)); - } - } // To get accurate point with reference to - // entire path distance at time t, - // following has to be done: - // 1. Length of each sub path have to be known - // 2. Locate and identify type of curve - // 3. Get t for the curve - // 4. Return curve.getPointAt(t') + for ( let i = 0; i < MAX_SAMPLES; ++ i ) { + const x = i / sigmaPixels; + const weight = Math.exp( - x * x / 2 ); + weights.push( weight ); - getPoint(t, optionalTarget) { - const d = t * this.getLength(); - const curveLengths = this.getCurveLengths(); - let i = 0; // To think about boundaries points. + if ( i === 0 ) { + + sum += weight; + + } else if ( i < samples ) { + + sum += 2 * weight; - while (i < curveLengths.length) { - if (curveLengths[i] >= d) { - const diff = curveLengths[i] - d; - const curve = this.curves[i]; - const segmentLength = curve.getLength(); - const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; - return curve.getPointAt(u, optionalTarget); } - i++; } - return null; // loop where sum != 0, sum > d , sum+1 _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0 ); + const y = 4 * ( this._cubeSize - outputSize ); - for (let i = 0, l = this.curves.length; i < l; i++) { - sums += this.curves[i].getLength(); - lengths.push(sums); - } + _setViewport( targetOut, x, y, 3 * outputSize, 2 * outputSize ); + renderer.setRenderTarget( targetOut ); + renderer.render( blurMesh, _flatCamera ); - this.cacheLengths = lengths; - return lengths; } - getSpacedPoints(divisions = 40) { - const points = []; - - for (let i = 0; i <= divisions; i++) { - points.push(this.getPoint(i / divisions)); - } + } - if (this.autoClose) { - points.push(points[0]); - } - return points; - } - getPoints(divisions = 12) { - const points = []; - let last; + function _createPlanes( lodMax ) { - for (let i = 0, curves = this.curves; i < curves.length; i++) { - const curve = curves[i]; - const resolution = curve.isEllipseCurve ? divisions * 2 : curve.isLineCurve || curve.isLineCurve3 ? 1 : curve.isSplineCurve ? divisions * curve.points.length : divisions; - const pts = curve.getPoints(resolution); + const lodPlanes = []; + const sizeLods = []; + const sigmas = []; - for (let j = 0; j < pts.length; j++) { - const point = pts[j]; - if (last && last.equals(point)) continue; // ensures no consecutive points are duplicates + let lod = lodMax; - points.push(point); - last = point; - } - } + const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; - if (this.autoClose && points.length > 1 && !points[points.length - 1].equals(points[0])) { - points.push(points[0]); - } + for ( let i = 0; i < totalLods; i ++ ) { - return points; - } + const sizeLod = Math.pow( 2, lod ); + sizeLods.push( sizeLod ); + let sigma = 1.0 / sizeLod; - copy(source) { - super.copy(source); - this.curves = []; + if ( i > lodMax - LOD_MIN ) { - for (let i = 0, l = source.curves.length; i < l; i++) { - const curve = source.curves[i]; - this.curves.push(curve.clone()); - } + sigma = EXTRA_LOD_SIGMA[ i - lodMax + LOD_MIN - 1 ]; - this.autoClose = source.autoClose; - return this; - } + } else if ( i === 0 ) { - toJSON() { - const data = super.toJSON(); - data.autoClose = this.autoClose; - data.curves = []; + sigma = 0; - for (let i = 0, l = this.curves.length; i < l; i++) { - const curve = this.curves[i]; - data.curves.push(curve.toJSON()); } - return data; - } + sigmas.push( sigma ); - fromJSON(json) { - super.fromJSON(json); - this.autoClose = json.autoClose; - this.curves = []; + const texelSize = 1.0 / ( sizeLod - 2 ); + const min = - texelSize; + const max = 1 + texelSize; + const uv1 = [ min, min, max, min, max, max, min, min, max, max, min, max ]; - 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)); - } + const cubeFaces = 6; + const vertices = 6; + const positionSize = 3; + const uvSize = 2; + const faceIndexSize = 1; - return this; - } + 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 ++ ) { - class Path extends CurvePath { - constructor(points) { - super(); - this.type = 'Path'; - this.currentPoint = new Vector2(); + const x = ( face % 3 ) * 2 / 3 - 1; + const y = face > 2 ? 0 : - 1; + const coordinates = [ + x, y, 0, + x + 2 / 3, y, 0, + x + 2 / 3, y + 1, 0, + x, y, 0, + x + 2 / 3, y + 1, 0, + x, y + 1, 0 + ]; + position.set( coordinates, positionSize * vertices * face ); + uv.set( uv1, uvSize * vertices * face ); + const fill = [ face, face, face, face, face, face ]; + faceIndex.set( fill, faceIndexSize * vertices * face ); - if (points) { - this.setFromPoints(points); } - } - setFromPoints(points) { - this.moveTo(points[0].x, points[0].y); + 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 ); - for (let i = 1, l = points.length; i < l; i++) { - this.lineTo(points[i].x, points[i].y); - } + if ( lod > LOD_MIN ) { - return this; - } + lod --; - 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; - } + return { lodPlanes, sizeLods, sigmas }; - 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*/ - ) { - 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; - } + function _createRenderTarget( width, height, params ) { - 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; - } + const cubeUVRenderTarget = new WebGLRenderTarget( width, height, params ); + cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; + cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; + cubeUVRenderTarget.scissorTest = true; + return cubeUVRenderTarget; - 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; - } + function _setViewport( target, x, y, width, height ) { - absellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { - const curve = new EllipseCurve(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); + target.viewport.set( x, y, width, height ); + target.scissor.set( x, y, width, height ); - 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); - } - } + function _getBlurShader( lodMax, width, height ) { - this.curves.push(curve); - const lastPoint = curve.getPoint(1); - this.currentPoint.copy(lastPoint); - return this; - } + const weights = new Float32Array( MAX_SAMPLES ); + const poleAxis = new Vector3( 0, 1, 0 ); + const shaderMaterial = new ShaderMaterial( { - copy(source) { - super.copy(source); - this.currentPoint.copy(source.currentPoint); - return this; - } + name: 'SphericalGaussianBlur', - toJSON() { - const data = super.toJSON(); - data.currentPoint = this.currentPoint.toArray(); - return data; - } + defines: { + 'n': MAX_SAMPLES, + 'CUBEUV_TEXEL_WIDTH': 1.0 / width, + 'CUBEUV_TEXEL_HEIGHT': 1.0 / height, + 'CUBEUV_MAX_MIP': `${lodMax}.0`, + }, - fromJSON(json) { - super.fromJSON(json); - this.currentPoint.fromArray(json.currentPoint); - return this; - } + uniforms: { + 'envMap': { value: null }, + 'samples': { value: 1 }, + 'weights': { value: weights }, + 'latitudinal': { value: false }, + 'dTheta': { value: 0 }, + 'mipInt': { value: 0 }, + 'poleAxis': { value: poleAxis } + }, - } + vertexShader: _getCommonVertexShader(), - class LatheGeometry extends BufferGeometry { - constructor(points = [new Vector2(0, 0.5), new Vector2(0.5, 0), new Vector2(0, -0.5)], segments = 12, phiStart = 0, phiLength = Math.PI * 2) { - super(); - this.type = 'LatheGeometry'; - this.parameters = { - points: points, - segments: segments, - phiStart: phiStart, - phiLength: phiLength - }; - segments = Math.floor(segments); // clamp phiLength so it's in range of [ 0, 2PI ] + fragmentShader: /* glsl */` - phiLength = clamp(phiLength, 0, Math.PI * 2); // buffers + precision mediump float; + precision mediump int; - const indices = []; - const vertices = []; - const uvs = []; - const initNormals = []; - const normals = []; // helper variables + varying vec3 vOutputDirection; - const inverseSegments = 1.0 / segments; - const vertex = new Vector3(); - const uv = new Vector2(); - const normal = new Vector3(); - const curNormal = new Vector3(); - const prevNormal = new Vector3(); - let dx = 0; - 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; - normal.y = -dx; - normal.z = dy * 0.0; - prevNormal.copy(normal); - normal.normalize(); - initNormals.push(normal.x, normal.y, normal.z); - break; + uniform sampler2D envMap; + uniform int samples; + uniform float weights[ n ]; + uniform bool latitudinal; + uniform float dTheta; + uniform float mipInt; + uniform vec3 poleAxis; - case points.length - 1: - // special handling for last Vertex on path - initNormals.push(prevNormal.x, prevNormal.y, prevNormal.z); - break; + #define ENVMAP_TYPE_CUBE_UV + #include - 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; - normal.y = -dx; - normal.z = dy * 0.0; - curNormal.copy(normal); - normal.x += prevNormal.x; - normal.y += prevNormal.y; - normal.z += prevNormal.z; - normal.normalize(); - initNormals.push(normal.x, normal.y, normal.z); - prevNormal.copy(curNormal); - } - } // generate vertices, uvs and normals + vec3 getSample( float theta, vec3 axis ) { + float cosTheta = cos( theta ); + // Rodrigues' axis-angle rotation + vec3 sampleDirection = vOutputDirection * cosTheta + + cross( axis, vOutputDirection ) * sin( theta ) + + axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta ); - for (let i = 0; i <= segments; i++) { - const phi = phiStart + i * inverseSegments * phiLength; - const sin = Math.sin(phi); - const cos = Math.cos(phi); + return bilinearCubeUV( envMap, sampleDirection, mipInt ); - 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 + } - uv.x = i / segments; - uv.y = j / (points.length - 1); - uvs.push(uv.x, uv.y); // normal + void main() { - 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 + vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection ); + if ( all( equal( axis, vec3( 0.0 ) ) ) ) { - for (let i = 0; i < segments; i++) { - for (let j = 0; j < points.length - 1; j++) { - const base = j + i * points.length; - const a = base; - const b = base + points.length; - const c = base + points.length + 1; - const d = base + 1; // faces + axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x ); - indices.push(a, b, d); - indices.push(c, d, b); } - } // 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); - } - - } + axis = normalize( axis ); - class CapsuleGeometry extends LatheGeometry { - constructor(radius = 1, length = 1, capSegments = 4, radialSegments = 8) { - const path = new Path(); - path.absarc(0, -length / 2, radius, Math.PI * 1.5, 0); - path.absarc(0, length / 2, radius, 0, Math.PI * 0.5); - super(path.getPoints(capSegments), radialSegments); - this.type = 'CapsuleGeometry'; - this.parameters = { - radius: radius, - height: length, - capSegments: capSegments, - radialSegments: radialSegments - }; - } + gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); + gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis ); - static fromJSON(data) { - return new CapsuleGeometry(data.radius, data.length, data.capSegments, data.radialSegments); - } + for ( int i = 1; i < n; i++ ) { - } + if ( i >= samples ) { - class CircleGeometry extends BufferGeometry { - constructor(radius = 1, segments = 8, thetaStart = 0, thetaLength = Math.PI * 2) { - super(); - this.type = 'CircleGeometry'; - this.parameters = { - radius: radius, - segments: segments, - thetaStart: thetaStart, - thetaLength: thetaLength - }; - segments = Math.max(3, segments); // buffers + break; - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // helper variables + } - const vertex = new Vector3(); - const uv = new Vector2(); // center point + float theta = dTheta * float( i ); + gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis ); + gl_FragColor.rgb += weights[ i ] * getSample( theta, axis ); - 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 + } + `, - vertex.x = radius * Math.cos(segment); - vertex.y = radius * Math.sin(segment); - vertices.push(vertex.x, vertex.y, vertex.z); // normal + blending: NoBlending, + depthTest: false, + depthWrite: false - normals.push(0, 0, 1); // uvs + } ); - uv.x = (vertices[i] / radius + 1) / 2; - uv.y = (vertices[i + 1] / radius + 1) / 2; - uvs.push(uv.x, uv.y); - } // indices + return shaderMaterial; + } - for (let i = 1; i <= segments; i++) { - indices.push(i, i + 1, 0); - } // build geometry + function _getEquirectMaterial() { + return new ShaderMaterial( { - this.setIndex(indices); - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - } + name: 'EquirectangularToCubeUV', - static fromJSON(data) { - return new CircleGeometry(data.radius, data.segments, data.thetaStart, data.thetaLength); - } + uniforms: { + 'envMap': { value: null } + }, - } + vertexShader: _getCommonVertexShader(), - class CylinderGeometry extends BufferGeometry { - constructor(radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) { - super(); - this.type = 'CylinderGeometry'; - this.parameters = { - radiusTop: radiusTop, - radiusBottom: radiusBottom, - height: height, - radialSegments: radialSegments, - heightSegments: heightSegments, - openEnded: openEnded, - thetaStart: thetaStart, - thetaLength: thetaLength - }; - const scope = this; - radialSegments = Math.floor(radialSegments); - heightSegments = Math.floor(heightSegments); // buffers + fragmentShader: /* glsl */` - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // helper variables + precision mediump float; + precision mediump int; - let index = 0; - const indexArray = []; - const halfHeight = height / 2; - let groupStart = 0; // generate geometry + varying vec3 vOutputDirection; - generateTorso(); + uniform sampler2D envMap; - if (openEnded === false) { - if (radiusTop > 0) generateCap(true); - if (radiusBottom > 0) generateCap(false); - } // build geometry + #include + void main() { - this.setIndex(indices); - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); + vec3 outputDirection = normalize( vOutputDirection ); + vec2 uv = equirectUv( outputDirection ); - function generateTorso() { - const normal = new Vector3(); - const vertex = new Vector3(); - let groupCount = 0; // this will be used to calculate the normal + gl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 ); - 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 + blending: NoBlending, + depthTest: false, + depthWrite: false - 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 + } - vertex.x = radius * sinTheta; - vertex.y = -v * height + halfHeight; - vertex.z = radius * cosTheta; - vertices.push(vertex.x, vertex.y, vertex.z); // normal + function _getCubemapMaterial() { - normal.set(sinTheta, slope, cosTheta).normalize(); - normals.push(normal.x, normal.y, normal.z); // uv + return new ShaderMaterial( { - uvs.push(u, 1 - v); // save index of vertex in respective row + name: 'CubemapToCubeUV', - indexRow.push(index++); - } // now save vertices of the row in our index array + uniforms: { + 'envMap': { value: null }, + 'flipEnvMap': { value: - 1 } + }, + vertexShader: _getCommonVertexShader(), - indexArray.push(indexRow); - } // generate indices + fragmentShader: /* glsl */` + precision mediump float; + precision mediump int; - 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 + uniform float flipEnvMap; - indices.push(a, b, d); - indices.push(b, c, d); // update group counter + varying vec3 vOutputDirection; - groupCount += 6; - } - } // add a group to the geometry. this will ensure multi material support + uniform samplerCube envMap; + void main() { - scope.addGroup(groupStart, groupCount, 0); // calculate new start value for groups + gl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) ); - groupStart += groupCount; } + `, - function generateCap(top) { - // save the index of the first center vertex - const centerIndexStart = index; - const uv = new Vector2(); - 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. - // because the geometry needs one set of uvs per face, - // we must generate a center vertex per face/segment + blending: NoBlending, + depthTest: false, + depthWrite: false - for (let x = 1; x <= radialSegments; x++) { - // vertex - vertices.push(0, halfHeight * sign, 0); // normal + } ); - normals.push(0, sign, 0); // uv + } - uvs.push(0.5, 0.5); // increase index + function _getCommonVertexShader() { - index++; - } // save the index of the last center vertex + return /* glsl */` + precision mediump float; + precision mediump int; - const centerIndexEnd = index; // now we generate the surrounding vertices, normals and uvs + attribute float faceIndex; - 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 + varying vec3 vOutputDirection; - vertex.x = radius * sinTheta; - vertex.y = halfHeight * sign; - vertex.z = radius * cosTheta; - vertices.push(vertex.x, vertex.y, vertex.z); // normal + // RH coordinate system; PMREM face-indexing convention + vec3 getDirection( vec2 uv, float face ) { - normals.push(0, sign, 0); // uv + uv = 2.0 * uv - 1.0; - uv.x = cosTheta * 0.5 + 0.5; - uv.y = sinTheta * 0.5 * sign + 0.5; - uvs.push(uv.x, uv.y); // increase index + vec3 direction = vec3( uv, 1.0 ); - index++; - } // generate indices + if ( face == 0.0 ) { + direction = direction.zyx; // ( 1, v, u ) pos x - for (let x = 0; x < radialSegments; x++) { - const c = centerIndexStart + x; - const i = centerIndexEnd + x; + } else if ( face == 1.0 ) { - if (top === true) { - // face top - indices.push(i, i + 1, c); - } else { - // face bottom - indices.push(i + 1, i, c); - } + direction = direction.xzy; + direction.xz *= -1.0; // ( -u, 1, -v ) pos y - groupCount += 3; - } // add a group to the geometry. this will ensure multi material support + } else if ( face == 2.0 ) { + direction.x *= -1.0; // ( -u, v, 1 ) pos z - scope.addGroup(groupStart, groupCount, top === true ? 1 : 2); // calculate new start value for groups + } else if ( face == 3.0 ) { + + direction = direction.zyx; + direction.xz *= -1.0; // ( -1, v, -u ) neg x + + } else if ( face == 4.0 ) { + + direction = direction.xzy; + direction.xy *= -1.0; // ( -u, -1, v ) neg y + + } else if ( face == 5.0 ) { + + direction.z *= -1.0; // ( u, v, -1 ) neg z - groupStart += groupCount; } - } - static fromJSON(data) { - return new CylinderGeometry(data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); + return direction; + } - } + void main() { - class ConeGeometry extends CylinderGeometry { - constructor(radius = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) { - super(0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength); - this.type = 'ConeGeometry'; - this.parameters = { - radius: radius, - height: height, - radialSegments: radialSegments, - heightSegments: heightSegments, - openEnded: openEnded, - thetaStart: thetaStart, - thetaLength: thetaLength - }; - } + vOutputDirection = getDirection( uv, faceIndex ); + gl_Position = vec4( position, 1.0 ); - static fromJSON(data) { - return new ConeGeometry(data.radius, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); } + `; } - class PolyhedronGeometry extends BufferGeometry { - constructor(vertices = [], indices = [], radius = 1, detail = 0) { - super(); - this.type = 'PolyhedronGeometry'; - this.parameters = { - vertices: vertices, - indices: indices, - radius: radius, - detail: detail - }; // default buffer data + function WebGLCubeUVMaps( renderer ) { - const vertexBuffer = []; - const uvBuffer = []; // the subdivision creates the vertex buffer data + let cubeUVmaps = new WeakMap(); - subdivide(detail); // all vertices should lie on a conceptual sphere with a given radius + let pmremGenerator = null; - applyRadius(radius); // finally, create the uv data + function get( texture ) { - generateUVs(); // build non-indexed geometry + if ( texture && texture.isTexture ) { - this.setAttribute('position', new Float32BufferAttribute(vertexBuffer, 3)); - this.setAttribute('normal', new Float32BufferAttribute(vertexBuffer.slice(), 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvBuffer, 2)); + const mapping = texture.mapping; - if (detail === 0) { - this.computeVertexNormals(); // flat normals - } else { - this.normalizeNormals(); // smooth normals - } // helper functions + const isEquirectMap = ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping ); + const isCubeMap = ( mapping === CubeReflectionMapping || mapping === CubeRefractionMapping ); + // equirect/cube map to cubeUV conversion - 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 + if ( isEquirectMap || isCubeMap ) { - 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 + if ( texture.isRenderTargetTexture && texture.needsPMREMUpdate === true ) { - subdivideFace(a, b, c, detail); - } - } + texture.needsPMREMUpdate = false; - function subdivideFace(a, b, c, detail) { - const cols = detail + 1; // we use this multidimensional array as a data structure for creating the subdivision + let renderTarget = cubeUVmaps.get( texture ); - const v = []; // construct all of the vertices for this subdivision + if ( pmremGenerator === null ) pmremGenerator = new PMREMGenerator( renderer ); - 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; + renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular( texture, renderTarget ) : pmremGenerator.fromCubemap( texture, renderTarget ); + cubeUVmaps.set( texture, renderTarget ); - for (let j = 0; j <= rows; j++) { - if (j === 0 && i === cols) { - v[i][j] = aj; - } else { - v[i][j] = aj.clone().lerp(bj, j / rows); - } - } - } // construct all of the faces + return renderTarget.texture; + + } else { + if ( cubeUVmaps.has( texture ) ) { - for (let i = 0; i < cols; i++) { - for (let j = 0; j < 2 * (cols - i) - 1; j++) { - const k = Math.floor(j / 2); + return cubeUVmaps.get( texture ).texture; - if (j % 2 === 0) { - pushVertex(v[i][k + 1]); - pushVertex(v[i + 1][k]); - pushVertex(v[i][k]); } else { - pushVertex(v[i][k + 1]); - pushVertex(v[i + 1][k + 1]); - pushVertex(v[i + 1][k]); + + 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 ); + cubeUVmaps.set( texture, renderTarget ); + + texture.addEventListener( 'dispose', onTextureDispose ); + + return renderTarget.texture; + + } else { + + // image not yet ready. try the conversion next frame + + return null; + + } + } + } + } + } - function applyRadius(radius) { - const vertex = new Vector3(); // iterate over the entire buffer and apply the radius to each vertex + return texture; - for (let i = 0; i < vertexBuffer.length; i += 3) { - vertex.x = vertexBuffer[i + 0]; - vertex.y = vertexBuffer[i + 1]; - vertex.z = vertexBuffer[i + 2]; - vertex.normalize().multiplyScalar(radius); - vertexBuffer[i + 0] = vertex.x; - vertexBuffer[i + 1] = vertex.y; - vertexBuffer[i + 2] = vertex.z; - } - } + } - function generateUVs() { - const vertex = new Vector3(); + function isCubeTextureComplete( image ) { - for (let i = 0; i < vertexBuffer.length; i += 3) { - vertex.x = vertexBuffer[i + 0]; - vertex.y = vertexBuffer[i + 1]; - vertex.z = vertexBuffer[i + 2]; - const u = azimuth(vertex) / 2 / Math.PI + 0.5; - const v = inclination(vertex) / Math.PI + 0.5; - uvBuffer.push(u, 1 - v); - } + let count = 0; + const length = 6; - correctUVs(); - correctSeam(); - } + for ( let i = 0; i < length; i ++ ) { - 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 + if ( image[ i ] !== undefined ) count ++; - if (max > 0.9 && min < 0.1) { - if (x0 < 0.2) uvBuffer[i + 0] += 1; - if (x1 < 0.2) uvBuffer[i + 2] += 1; - if (x2 < 0.2) uvBuffer[i + 4] += 1; - } - } } - function pushVertex(vertex) { - vertexBuffer.push(vertex.x, vertex.y, vertex.z); - } + return count === length; - 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(); - const c = new Vector3(); - const centroid = new Vector3(); - 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]); - c.set(vertexBuffer[i + 6], vertexBuffer[i + 7], vertexBuffer[i + 8]); - uvA.set(uvBuffer[j + 0], uvBuffer[j + 1]); - uvB.set(uvBuffer[j + 2], uvBuffer[j + 3]); - uvC.set(uvBuffer[j + 4], uvBuffer[j + 5]); - centroid.copy(a).add(b).add(c).divideScalar(3); - const azi = azimuth(centroid); - correctUV(uvA, j + 0, a, azi); - correctUV(uvB, j + 2, b, azi); - correctUV(uvC, j + 4, c, azi); - } - } + function onTextureDispose( event ) { - function correctUV(uv, stride, vector, azimuth) { - if (azimuth < 0 && uv.x === 1) { - uvBuffer[stride] = uv.x - 1; - } + const texture = event.target; - 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. + texture.removeEventListener( 'dispose', onTextureDispose ); + const cubemapUV = cubeUVmaps.get( texture ); - function azimuth(vector) { - return Math.atan2(vector.z, -vector.x); - } // Angle above the XZ plane. + if ( cubemapUV !== undefined ) { + cubeUVmaps.delete( texture ); + cubemapUV.dispose(); - 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); } - } + function dispose() { - 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/φ) - -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); - this.type = 'DodecahedronGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; - } + cubeUVmaps = new WeakMap(); + + if ( pmremGenerator !== null ) { + + pmremGenerator.dispose(); + pmremGenerator = null; + + } - static fromJSON(data) { - return new DodecahedronGeometry(data.radius, data.detail); } + return { + get: get, + dispose: dispose + }; + } - const _v0 = new Vector3(); + function WebGLExtensions( gl ) { - const _v1$1 = new Vector3(); + const extensions = {}; - const _normal = new Vector3(); + function getExtension( name ) { - const _triangle = new Triangle(); + if ( extensions[ name ] !== undefined ) { - class EdgesGeometry extends BufferGeometry { - constructor(geometry = null, thresholdAngle = 1) { - super(); - this.type = 'EdgesGeometry'; - this.parameters = { - geometry: geometry, - thresholdAngle: thresholdAngle - }; + return extensions[ name ]; - if (geometry !== null) { - const precisionPoints = 4; - const precision = Math.pow(10, precisionPoints); - const thresholdDot = Math.cos(DEG2RAD * thresholdAngle); - const indexAttr = geometry.getIndex(); - const positionAttr = geometry.getAttribute('position'); - const indexCount = indexAttr ? indexAttr.count : positionAttr.count; - const indexArr = [0, 0, 0]; - const vertKeys = ['a', 'b', 'c']; - const hashes = new Array(3); - const edgeData = {}; - const vertices = []; + } - for (let i = 0; i < indexCount; i += 3) { - if (indexAttr) { - indexArr[0] = indexAttr.getX(i); - indexArr[1] = indexAttr.getX(i + 1); - indexArr[2] = indexAttr.getX(i + 2); - } else { - indexArr[0] = i; - indexArr[1] = i + 1; - indexArr[2] = i + 2; - } + let extension; - const { - a, - b, - c - } = _triangle; - a.fromBufferAttribute(positionAttr, indexArr[0]); - b.fromBufferAttribute(positionAttr, indexArr[1]); - c.fromBufferAttribute(positionAttr, indexArr[2]); + switch ( name ) { - _triangle.getNormal(_normal); // create hashes for the edge from the vertices + 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; - 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 + 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; - if (hashes[0] === hashes[1] || hashes[1] === hashes[2] || hashes[2] === hashes[0]) { - continue; - } // iterate over every edge + 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 ); - for (let j = 0; j < 3; j++) { - // get the first and next vertex making up the edge - const jNext = (j + 1) % 3; - const vecHash0 = hashes[j]; - const vecHash1 = hashes[jNext]; - const v0 = _triangle[vertKeys[j]]; - 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. - if (_normal.dot(edgeData[reverseHash].normal) <= thresholdDot) { - vertices.push(v0.x, v0.y, v0.z); - vertices.push(v1.x, v1.y, v1.z); - } + } - edgeData[reverseHash] = null; - } else if (!(hash in edgeData)) { - // if we've already got an edge here then skip adding a new one - edgeData[hash] = { - index0: indexArr[j], - index1: indexArr[jNext], - normal: _normal.clone() - }; - } - } - } // iterate over all remaining, unmatched edges and add them to the vertex array + extensions[ name ] = extension; + return extension; - for (const key in edgeData) { - if (edgeData[key]) { - const { - index0, - index1 - } = edgeData[key]; + } - _v0.fromBufferAttribute(positionAttr, index0); + return { - _v1$1.fromBufferAttribute(positionAttr, index1); + has: function ( name ) { - vertices.push(_v0.x, _v0.y, _v0.z); - vertices.push(_v1$1.x, _v1$1.y, _v1$1.z); - } - } + return getExtension( name ) !== null; - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - } - } + }, - } + init: function ( capabilities ) { - class Shape extends Path { - constructor(points) { - super(points); - this.uuid = generateUUID(); - this.type = 'Shape'; - this.holes = []; - } + if ( capabilities.isWebGL2 ) { - getPointsHoles(divisions) { - const holesPts = []; + getExtension( 'EXT_color_buffer_float' ); - for (let i = 0, l = this.holes.length; i < l; i++) { - holesPts[i] = this.holes[i].getPoints(divisions); - } + } else { - return holesPts; - } // get points of shape and holes (keypoints based on segments parameter) + getExtension( 'WEBGL_depth_texture' ); + getExtension( 'OES_texture_float' ); + getExtension( 'OES_texture_half_float' ); + getExtension( 'OES_texture_half_float_linear' ); + getExtension( 'OES_standard_derivatives' ); + getExtension( 'OES_element_index_uint' ); + getExtension( 'OES_vertex_array_object' ); + getExtension( 'ANGLE_instanced_arrays' ); + } - extractPoints(divisions) { - return { - shape: this.getPoints(divisions), - holes: this.getPointsHoles(divisions) - }; - } + getExtension( 'OES_texture_float_linear' ); + getExtension( 'EXT_color_buffer_half_float' ); + getExtension( 'WEBGL_multisampled_render_to_texture' ); - 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()); - } + get: function ( name ) { - return this; - } + const extension = getExtension( name ); - toJSON() { - const data = super.toJSON(); - data.uuid = this.uuid; - data.holes = []; + if ( extension === null ) { - for (let i = 0, l = this.holes.length; i < l; i++) { - const hole = this.holes[i]; - data.holes.push(hole.toJSON()); - } + console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); - return data; - } + } - fromJSON(json) { - super.fromJSON(json); - this.uuid = json.uuid; - this.holes = []; + return extension; - 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) - */ - const Earcut = { - triangulate: function (data, holeIndices, dim = 2) { - const hasHoles = holeIndices && holeIndices.length; - const outerLen = hasHoles ? holeIndices[0] * dim : data.length; - let outerNode = linkedList(data, 0, outerLen, dim, true); - 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 + function WebGLGeometries( gl, attributes, info, bindingStates ) { + + const geometries = {}; + const wireframeAttributes = new WeakMap(); - if (data.length > 80 * dim) { - minX = maxX = data[0]; - minY = maxY = data[1]; + function onGeometryDispose( event ) { - for (let i = dim; i < outerLen; i += dim) { - x = data[i]; - y = data[i + 1]; - if (x < minX) minX = x; - if (y < minY) minY = y; - if (x > maxX) maxX = x; - if (y > maxY) maxY = y; - } // minX, minY and invSize are later used to transform coords into integers for z-order calculation + const geometry = event.target; + + if ( geometry.index !== null ) { + attributes.remove( geometry.index ); - invSize = Math.max(maxX - minX, maxY - minY); - invSize = invSize !== 0 ? 1 / invSize : 0; } - earcutLinked(outerNode, triangles, dim, minX, minY, invSize); - return triangles; - } - }; // create a circular doubly linked list from polygon points in the specified winding order + for ( const name in geometry.attributes ) { - function linkedList(data, start, end, dim, clockwise) { - let i, last; + attributes.remove( geometry.attributes[ name ] ); - 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; - } + geometry.removeEventListener( 'dispose', onGeometryDispose ); - return last; - } // eliminate colinear or duplicate points + delete geometries[ geometry.id ]; + const attribute = wireframeAttributes.get( geometry ); - function filterPoints(start, end) { - if (!start) return start; - if (!end) end = start; - let p = start, - again; + if ( attribute ) { - do { - again = false; + attributes.remove( attribute ); + wireframeAttributes.delete( geometry ); - if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { - removeNode(p); - p = end = p.prev; - if (p === p.next) break; - again = true; - } else { - p = p.next; } - } while (again || p !== end); - return end; - } // main ear slicing loop which triangulates a polygon (given as a linked list) + bindingStates.releaseStatesOfGeometry( geometry ); + if ( geometry.isInstancedBufferGeometry === true ) { - function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { - if (!ear) return; // interlink polygon nodes in z-order + delete geometry._maxInstanceCount; - if (!pass && invSize) indexCurve(ear, minX, minY, invSize); - let stop = ear, - 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 + info.memory.geometries --; - ear = next.next; - stop = next.next; - continue; - } + } - ear = next; // if we looped through the whole remaining polygon and can't find any more ears + function get( object, geometry ) { - if (ear === stop) { - // try filtering points and slicing again - if (!pass) { - earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); // if this didn't work, try curing all small self-intersections locally - } else if (pass === 1) { - ear = cureLocalIntersections(filterPoints(ear), triangles, dim); - earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); // as a last resort, try splitting the remaining polygon into two - } else if (pass === 2) { - splitEarcut(ear, triangles, dim, minX, minY, invSize); - } + if ( geometries[ geometry.id ] === true ) return geometry; - break; - } - } - } // check whether a polygon node forms a valid ear with adjacent nodes + geometry.addEventListener( 'dispose', onGeometryDispose ); + geometries[ geometry.id ] = true; - function isEar(ear) { - const a = ear.prev, - b = ear, - c = ear.next; - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear - // now make sure we don't have other points inside the potential ear + info.memory.geometries ++; - let p = ear.next.next; + return geometry; - while (p !== ear.prev) { - if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; - p = p.next; } - return true; - } - - function isEarHashed(ear, minX, minY, invSize) { - const a = ear.prev, - b = ear, - c = ear.next; - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear - // triangle bbox; min & max are calculated like this for speed + function update( geometry ) { - 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 geometryAttributes = geometry.attributes; - const minZ = zOrder(minTX, minTY, minX, minY, invSize), - maxZ = zOrder(maxTX, maxTY, minX, minY, invSize); - let p = ear.prevZ, - n = ear.nextZ; // look for points inside the triangle in both directions + // Updating index buffer in VAO now. See WebGLBindingStates. - while (p && p.z >= minZ && n && n.z <= maxZ) { - if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; - p = p.prevZ; - if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; - n = n.nextZ; - } // look for remaining points in decreasing z-order + for ( const name in geometryAttributes ) { + attributes.update( geometryAttributes[ name ], gl.ARRAY_BUFFER ); - while (p && p.z >= minZ) { - if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; - p = p.prevZ; - } // look for remaining points in increasing z-order + } + // morph targets - while (n && n.z <= maxZ) { - if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; - n = n.nextZ; - } + const morphAttributes = geometry.morphAttributes; - return true; - } // go through all polygon nodes and cure small local self-intersections + for ( const name in morphAttributes ) { + const array = morphAttributes[ name ]; - function cureLocalIntersections(start, triangles, dim) { - let p = start; + for ( let i = 0, l = array.length; i < l; i ++ ) { - do { - const a = p.prev, - b = p.next.next; + attributes.update( array[ i ], gl.ARRAY_BUFFER ); - 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 + } - 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 + function updateWireframeAttribute( geometry ) { + const indices = []; - function splitEarcut(start, triangles, dim, minX, minY, invSize) { - // look for a valid diagonal that divides the polygon into two - let a = start; + const geometryIndex = geometry.index; + const geometryPosition = geometry.attributes.position; + let version = 0; - do { - let b = a.next.next; + if ( geometryIndex !== null ) { - 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 + const array = geometryIndex.array; + version = geometryIndex.version; - a = filterPoints(a, a.next); - c = filterPoints(c, c.next); // run earcut on each half + for ( let i = 0, l = array.length; i < l; i += 3 ) { + + const a = array[ i + 0 ]; + const b = array[ i + 1 ]; + const c = array[ i + 2 ]; + + indices.push( a, b, b, c, c, a ); - earcutLinked(a, triangles, dim, minX, minY, invSize); - earcutLinked(c, triangles, dim, minX, minY, invSize); - return; } - b = b.next; - } + } else { - a = a.next; - } while (a !== start); - } // link every hole into the outer loop, producing a single-ring polygon without holes + const array = geometryPosition.array; + version = geometryPosition.version; + for ( let i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) { - function eliminateHoles(data, holeIndices, outerNode, dim) { - const queue = []; - let i, len, start, end, list; + const a = i + 0; + const b = i + 1; + const c = i + 2; - for (i = 0, len = holeIndices.length; i < len; i++) { - start = holeIndices[i] * dim; - end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; - list = linkedList(data, start, end, dim, false); - if (list === list.next) list.steiner = true; - queue.push(getLeftmost(list)); - } + indices.push( a, b, b, c, c, a ); - queue.sort(compareX); // process holes from left to right + } - for (i = 0; i < queue.length; i++) { - eliminateHole(queue[i], outerNode); - outerNode = filterPoints(outerNode, outerNode.next); - } + } - return outerNode; - } + const attribute = new ( arrayNeedsUint32( indices ) ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 ); + attribute.version = version; - function compareX(a, b) { - return a.x - b.x; - } // find a bridge between vertices that connects hole with an outer ring and link it + // Updating index buffer in VAO now. See WebGLBindingStates + // - function eliminateHole(hole, outerNode) { - outerNode = findHoleBridge(hole, outerNode); + const previousAttribute = wireframeAttributes.get( geometry ); - if (outerNode) { - const b = splitPolygon(outerNode, hole); // filter collinear points around the cuts + if ( previousAttribute ) attributes.remove( previousAttribute ); - filterPoints(outerNode, outerNode.next); - filterPoints(b, b.next); - } - } // David Eberly's algorithm for finding a bridge between hole and outer polygon + // + wireframeAttributes.set( geometry, attribute ); - 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 + } - 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); + function getWireframeAttribute( geometry ) { - if (x <= hx && x > qx) { - qx = x; + const currentAttribute = wireframeAttributes.get( geometry ); - if (x === hx) { - if (hy === p.y) return p; - if (hy === p.next.y) return p.next; - } + if ( currentAttribute ) { - m = p.x < p.next.x ? p : p.next; - } - } + const geometryIndex = geometry.index; - p = p.next; - } while (p !== outerNode); + if ( geometryIndex !== null ) { - 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 + // if the attribute is obsolete, create a new one - const stop = m, - mx = m.x, - my = m.y; - let tanMin = Infinity, - tan; - p = m; + if ( currentAttribute.version < geometryIndex.version ) { - 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 + updateWireframeAttribute( geometry ); + + } - if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) { - m = p; - tanMin = tan; } - } - p = p.next; - } while (p !== stop); + } else { - return m; - } // whether sector in vertex m contains sector in vertex p in the same coordinates + updateWireframeAttribute( geometry ); + } - 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 + return wireframeAttributes.get( geometry ); + } - function indexCurve(start, minX, minY, invSize) { - let p = start; + return { - do { - if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize); - p.prevZ = p.prev; - p.nextZ = p.next; - p = p.next; - } while (p !== start); + get: get, + update: update, - 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 + getWireframeAttribute: getWireframeAttribute + }; - function sortLinked(list) { - let i, - p, - q, - e, - tail, - numMerges, - pSize, - qSize, - inSize = 1; + } - do { - p = list; - list = null; - tail = null; - numMerges = 0; + function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) { - while (p) { - numMerges++; - q = p; - pSize = 0; + const isWebGL2 = capabilities.isWebGL2; - for (i = 0; i < inSize; i++) { - pSize++; - q = q.nextZ; - if (!q) break; - } + let mode; - qSize = inSize; + function setMode( value ) { - while (pSize > 0 || qSize > 0 && q) { - if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { - e = p; - p = p.nextZ; - pSize--; - } else { - e = q; - q = q.nextZ; - qSize--; - } + mode = value; - if (tail) tail.nextZ = e;else list = e; - e.prevZ = tail; - tail = e; - } + } - p = q; - } + let type, bytesPerElement; - tail.nextZ = null; - inSize *= 2; - } while (numMerges > 1); + function setIndex( value ) { - return list; - } // z-order of a point given coords and inverse of the longer side of data bbox + type = value.type; + bytesPerElement = value.bytesPerElement; + } - function zOrder(x, y, minX, minY, invSize) { - // coords are transformed into non-negative 15-bit integer range - x = 32767 * (x - minX) * invSize; - y = 32767 * (y - minY) * invSize; - x = (x | x << 8) & 0x00FF00FF; - x = (x | x << 4) & 0x0F0F0F0F; - x = (x | x << 2) & 0x33333333; - x = (x | x << 1) & 0x55555555; - y = (y | y << 8) & 0x00FF00FF; - y = (y | y << 4) & 0x0F0F0F0F; - y = (y | y << 2) & 0x33333333; - y = (y | y << 1) & 0x55555555; - return x | y << 1; - } // find the leftmost node of a polygon ring - - - function getLeftmost(start) { - let p = start, - leftmost = start; + function render( start, count ) { - do { - if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p; - p = p.next; - } while (p !== start); + gl.drawElements( mode, count, type, start * bytesPerElement ); - return leftmost; - } // check if a point lies within a convex triangle + info.update( count, mode, 1 ); + + } + function renderInstances( start, count, primcount ) { - 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) + if ( primcount === 0 ) return; + let extension, methodName; - 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 - } // signed area of a triangle + if ( isWebGL2 ) { + extension = gl; + methodName = 'drawElementsInstanced'; - 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 + } else { + extension = extensions.get( 'ANGLE_instanced_arrays' ); + methodName = 'drawElementsInstancedANGLE'; - function equals(p1, p2) { - return p1.x === p2.x && p1.y === p2.y; - } // check if two segments intersect + if ( extension === null ) { + console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); + return; - function intersects(p1, q1, p2, q2) { - const o1 = sign(area(p1, q1, p2)); - const o2 = sign(area(p1, q1, q2)); - const o3 = sign(area(p2, q2, p1)); - const o4 = sign(area(p2, q2, q1)); - 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 + extension[ methodName ]( mode, count, type, start * bytesPerElement, primcount ); - if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 + info.update( count, mode, primcount ); - 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 + // + this.setMode = setMode; + this.setIndex = setIndex; + this.render = render; + this.renderInstances = renderInstances; - 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 + function WebGLInfo( gl ) { + const memory = { + geometries: 0, + textures: 0 + }; - function intersectsPolygon(a, b) { - let p = a; + const render = { + frame: 0, + calls: 0, + triangles: 0, + points: 0, + lines: 0 + }; - 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); + function update( count, mode, instanceCount ) { - return false; - } // check if a polygon diagonal is locally inside the polygon + render.calls ++; + + switch ( mode ) { + case gl.TRIANGLES: + render.triangles += instanceCount * ( count / 3 ); + break; - 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 + case gl.LINES: + render.lines += instanceCount * ( count / 2 ); + break; + case gl.LINE_STRIP: + render.lines += instanceCount * ( count - 1 ); + break; - function middleInside(a, b) { - let p = a, - inside = false; - const px = (a.x + b.x) / 2, - py = (a.y + b.y) / 2; + case gl.LINE_LOOP: + render.lines += instanceCount * count; + break; - 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); + case gl.POINTS: + render.points += instanceCount * count; + break; - 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 + default: + console.error( 'THREE.WebGLInfo: Unknown draw mode:', mode ); + break; + } - 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; - a.next = b; - b.prev = a; - a2.next = an; - an.prev = a2; - b2.next = a2; - a2.prev = b2; - bp.next = b2; - b2.prev = bp; - return b2; - } // create a node and optionally link it with previous one (in a circular doubly linked list) + } + function reset() { - function insertNode(i, x, y, last) { - const p = new Node(i, x, y); + render.frame ++; + render.calls = 0; + render.triangles = 0; + render.points = 0; + render.lines = 0; - if (!last) { - p.prev = p; - p.next = p; - } else { - p.next = last.next; - p.prev = last; - last.next.prev = p; - last.next = p; } - return p; - } + return { + memory: memory, + render: render, + programs: null, + autoReset: true, + reset: reset, + update: update + }; - 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 + function numericalSort( a, b ) { - this.x = x; - this.y = y; // previous and next vertex nodes in a polygon ring + return a[ 0 ] - b[ 0 ]; - this.prev = null; - this.next = null; // z-order curve value + } - this.z = null; // previous and next nodes in z-order + function absNumericalSort( a, b ) { - this.prevZ = null; - this.nextZ = null; // indicates whether this is a steiner point + return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] ); - 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; - } + function WebGLMorphtargets( gl, capabilities, textures ) { - return sum; - } + const influencesList = {}; + const morphInfluences = new Float32Array( 8 ); + const morphTextures = new WeakMap(); + const morph = new Vector4(); - class ShapeUtils { - // calculate area of the contour polygon - static area(contour) { - const n = contour.length; - let a = 0.0; + const workInfluences = []; - for (let p = n - 1, q = 0; q < n; p = q++) { - a += contour[p].x * contour[q].y - contour[q].x * contour[p].y; - } + for ( let i = 0; i < 8; i ++ ) { - return a * 0.5; - } + workInfluences[ i ] = [ i, 0 ]; - 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, ... ] + function update( object, geometry, material, program ) { - const holeIndices = []; // array of hole indices + const objectInfluences = object.morphTargetInfluences; - const faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ] + if ( capabilities.isWebGL2 === true ) { - removeDupEndPts(contour); - addContour(vertices, contour); // + // 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. - let holeIndex = contour.length; - holes.forEach(removeDupEndPts); + const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; + const morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0; - for (let i = 0; i < holes.length; i++) { - holeIndices.push(holeIndex); - holeIndex += holes[i].length; - addContour(vertices, holes[i]); - } // + let entry = morphTextures.get( geometry ); + if ( entry === undefined || entry.count !== morphTargetsCount ) { - const triangles = Earcut.triangulate(vertices, holeIndices); // + if ( entry !== undefined ) entry.texture.dispose(); - for (let i = 0; i < triangles.length; i += 3) { - faces.push(triangles.slice(i, i + 3)); - } + const hasMorphPosition = geometry.morphAttributes.position !== undefined; + const hasMorphNormals = geometry.morphAttributes.normal !== undefined; + const hasMorphColors = geometry.morphAttributes.color !== undefined; - return faces; - } + const morphTargets = geometry.morphAttributes.position || []; + const morphNormals = geometry.morphAttributes.normal || []; + const morphColors = geometry.morphAttributes.color || []; - } + let vertexDataCount = 0; - function removeDupEndPts(points) { - const l = points.length; + if ( hasMorphPosition === true ) vertexDataCount = 1; + if ( hasMorphNormals === true ) vertexDataCount = 2; + if ( hasMorphColors === true ) vertexDataCount = 3; - if (l > 2 && points[l - 1].equals(points[0])) { - points.pop(); - } - } + let width = geometry.attributes.position.count * vertexDataCount; + let height = 1; - function addContour(vertices, contour) { - for (let i = 0; i < contour.length; i++) { - vertices.push(contour[i].x); - vertices.push(contour[i].y); - } - } + if ( width > capabilities.maxTextureSize ) { - /** - * Creates extruded geometry from a path shape. - * - * parameters = { - * - * curveSegments: , // number of points on the curves - * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too - * depth: , // Depth to extrude the shape - * - * bevelEnabled: , // turn on bevel - * bevelThickness: , // how deep into the original shape bevel goes - * bevelSize: , // how far from shape outline (including bevelOffset) is bevel - * bevelOffset: , // how far from shape outline does bevel start - * bevelSegments: , // number of bevel layers - * - * extrudePath: // curve to extrude shape along - * - * UVGenerator: // object that provides UV generator functions - * - * } - */ + height = Math.ceil( width / capabilities.maxTextureSize ); + width = capabilities.maxTextureSize; - 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(); - this.type = 'ExtrudeGeometry'; - this.parameters = { - shapes: shapes, - options: options - }; - shapes = Array.isArray(shapes) ? shapes : [shapes]; - 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 + const buffer = new Float32Array( width * height * 4 * morphTargetsCount ); + const texture = new DataArrayTexture( buffer, width, height, morphTargetsCount ); + texture.type = FloatType; + texture.needsUpdate = true; - this.setAttribute('position', new Float32BufferAttribute(verticesArray, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvArray, 2)); - this.computeVertexNormals(); // functions + // fill buffer - function addShape(shape) { - const placeholder = []; // options + const vertexDataStride = vertexDataCount * 4; - const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; - const steps = options.steps !== undefined ? options.steps : 1; - let depth = options.depth !== undefined ? options.depth : 1; - let bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; - let bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 0.2; - let bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 0.1; - 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; // deprecated options + for ( let i = 0; i < morphTargetsCount; i ++ ) { - if (options.amount !== undefined) { - console.warn('THREE.ExtrudeBufferGeometry: amount has been renamed to depth.'); - depth = options.amount; - } // + const morphTarget = morphTargets[ i ]; + const morphNormal = morphNormals[ i ]; + const morphColor = morphColors[ i ]; + const offset = width * height * 4 * i; - let extrudePts, - extrudeByPath = false; - let splineTube, binormal, normal, position2; + for ( let j = 0; j < morphTarget.count; j ++ ) { - 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? + const stride = j * vertexDataStride; - splineTube = extrudePath.computeFrenetFrames(steps, false); // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); + if ( hasMorphPosition === true ) { - binormal = new Vector3(); - normal = new Vector3(); - position2 = new Vector3(); - } // Safeguards if bevels are not enabled + morph.fromBufferAttribute( morphTarget, j ); + buffer[ offset + stride + 0 ] = morph.x; + buffer[ offset + stride + 1 ] = morph.y; + buffer[ offset + stride + 2 ] = morph.z; + buffer[ offset + stride + 3 ] = 0; - if (!bevelEnabled) { - bevelSegments = 0; - bevelThickness = 0; - bevelSize = 0; - bevelOffset = 0; - } // Variables initialization + } + if ( hasMorphNormals === true ) { - const shapePoints = shape.extractPoints(curveSegments); - let vertices = shapePoints.shape; - const holes = shapePoints.holes; - const reverse = !ShapeUtils.isClockWise(vertices); + morph.fromBufferAttribute( morphNormal, j ); - if (reverse) { - vertices = vertices.reverse(); // Maybe we should also check if holes are in the opposite direction, just to be safe ... + buffer[ offset + stride + 4 ] = morph.x; + buffer[ offset + stride + 5 ] = morph.y; + buffer[ offset + stride + 6 ] = morph.z; + buffer[ offset + stride + 7 ] = 0; - for (let h = 0, hl = holes.length; h < hl; h++) { - const ahole = holes[h]; + } - if (ShapeUtils.isClockWise(ahole)) { - holes[h] = ahole.reverse(); - } - } - } + if ( hasMorphColors === true ) { - const faces = ShapeUtils.triangulateShape(vertices, holes); - /* Vertices */ + morph.fromBufferAttribute( morphColor, j ); - const contour = vertices; // vertices has all points but contour has only points of circumference + buffer[ offset + stride + 8 ] = morph.x; + buffer[ offset + stride + 9 ] = morph.y; + buffer[ offset + stride + 10 ] = morph.z; + buffer[ offset + stride + 11 ] = ( morphColor.itemSize === 4 ) ? morph.w : 1; - for (let h = 0, hl = holes.length; h < hl; h++) { - 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 + } - function getBevelVec(inPt, inPrev, inNext) { - // computes for inPt the corresponding point inPt' on a new contour - // shifted by 1 unit (length of normalized vector) to the left - // if we walk along contour clockwise, this new contour is outside the old one - // - // inPt' is the intersection of the two lines parallel to the two - // adjacent edges of inPt at a distance of 1 unit on the left side. - 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 + entry = { + count: morphTargetsCount, + texture: texture, + size: new Vector2( width, height ) + }; - const v_prev_x = inPt.x - inPrev.x, - 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 + morphTextures.set( geometry, entry ); - const collinear0 = v_prev_x * v_next_y - v_prev_y * v_next_x; + function disposeTexture() { - 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 + texture.dispose(); - 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 + morphTextures.delete( geometry ); - 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 + geometry.removeEventListener( 'dispose', disposeTexture ); - 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 + } - const v_trans_lensq = v_trans_x * v_trans_x + v_trans_y * v_trans_y; + geometry.addEventListener( 'dispose', disposeTexture ); - if (v_trans_lensq <= 2) { - return new Vector2(v_trans_x, v_trans_y); - } else { - shrink_by = Math.sqrt(v_trans_lensq / 2); - } - } else { - // handle special case of collinear edges - let direction_eq = false; // assumes: opposite + } - if (v_prev_x > Number.EPSILON) { - if (v_next_x > Number.EPSILON) { - direction_eq = true; - } - } else { - if (v_prev_x < -Number.EPSILON) { - if (v_next_x < -Number.EPSILON) { - direction_eq = true; - } - } else { - if (Math.sign(v_prev_y) === Math.sign(v_next_y)) { - direction_eq = true; - } - } - } + // - if (direction_eq) { - // console.log("Warning: lines are a straight sequence"); - v_trans_x = -v_prev_y; - v_trans_y = v_prev_x; - shrink_by = Math.sqrt(v_prev_lensq); - } else { - // console.log("Warning: lines are a straight spike"); - v_trans_x = v_prev_x; - v_trans_y = v_prev_y; - shrink_by = Math.sqrt(v_prev_lensq / 2); - } - } + let morphInfluencesSum = 0; + + for ( let i = 0; i < objectInfluences.length; i ++ ) { + + morphInfluencesSum += objectInfluences[ i ]; - return new Vector2(v_trans_x / shrink_by, v_trans_y / shrink_by); } - const contourMovements = []; + const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; - 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) - // console.log('i,j,k', i, j , k) + program.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence ); + program.getUniforms().setValue( gl, 'morphTargetInfluences', objectInfluences ); - contourMovements[i] = getBevelVec(contour[i], contour[j], contour[k]); - } + program.getUniforms().setValue( gl, 'morphTargetsTexture', entry.texture, textures ); + program.getUniforms().setValue( gl, 'morphTargetsTextureSize', entry.size ); - const holesMovements = []; - let oneHoleMovements, - verticesMovements = contourMovements.concat(); - for (let h = 0, hl = holes.length; h < hl; h++) { - const ahole = holes[h]; - oneHoleMovements = []; + } else { - 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) + // 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 - oneHoleMovements[i] = getBevelVec(ahole[i], ahole[j], ahole[k]); - } + const length = objectInfluences === undefined ? 0 : objectInfluences.length; - holesMovements.push(oneHoleMovements); - verticesMovements = verticesMovements.concat(oneHoleMovements); - } // Loop bevelSegments, 1 for the front, 1 for the back + let influences = influencesList[ geometry.id ]; + if ( influences === undefined || influences.length !== length ) { - 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 + // initialise list - 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 + influences = []; + for ( let i = 0; i < length; i ++ ) { - for (let h = 0, hl = holes.length; h < hl; h++) { - const ahole = holes[h]; - oneHoleMovements = holesMovements[h]; + influences[ i ] = [ i, 0 ]; - 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; // Back facing vertices + influencesList[ geometry.id ] = influences; - 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 + // Collect influences + for ( let i = 0; i < length; i ++ ) { - 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]; + const influence = influences[ 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 ++ ) { + influence[ 0 ] = i; + influence[ 1 ] = objectInfluences[ i ]; + } - 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 + influences.sort( absNumericalSort ); - 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 + for ( let i = 0; i < 8; i ++ ) { + if ( i < length && influences[ i ][ 1 ] ) { - for (let h = 0, hl = holes.length; h < hl; h++) { - const ahole = holes[h]; - oneHoleMovements = holesMovements[h]; + workInfluences[ i ][ 0 ] = influences[ i ][ 0 ]; + workInfluences[ i ][ 1 ] = influences[ i ][ 1 ]; - for (let i = 0, il = ahole.length; i < il; i++) { - const vert = scalePt2(ahole[i], oneHoleMovements[i], bs); + } else { + + workInfluences[ i ][ 0 ] = Number.MAX_SAFE_INTEGER; + workInfluences[ i ][ 1 ] = 0; - if (!extrudeByPath) { - v(vert.x, vert.y, depth + z); - } else { - v(vert.x, vert.y + extrudePts[steps - 1].y, extrudePts[steps - 1].x + z); - } - } } + } - /* Faces */ - // Top and bottom faces + workInfluences.sort( numericalSort ); - buildLidFaces(); // Sides faces + const morphTargets = geometry.morphAttributes.position; + const morphNormals = geometry.morphAttributes.normal; - buildSideFaces(); ///// Internal functions + let morphInfluencesSum = 0; - function buildLidFaces() { - const start = verticesArray.length / 3; + for ( let i = 0; i < 8; i ++ ) { - if (bevelEnabled) { - let layer = 0; // steps + 1 + const influence = workInfluences[ i ]; + const index = influence[ 0 ]; + const value = influence[ 1 ]; - let offset = vlen * layer; // Bottom faces + if ( index !== Number.MAX_SAFE_INTEGER && value ) { - for (let i = 0; i < flen; i++) { - const face = faces[i]; - f3(face[2] + offset, face[1] + offset, face[0] + offset); - } + if ( morphTargets && geometry.getAttribute( 'morphTarget' + i ) !== morphTargets[ index ] ) { - layer = steps + bevelSegments * 2; - offset = vlen * layer; // Top faces + geometry.setAttribute( 'morphTarget' + i, morphTargets[ index ] ); - for (let i = 0; i < flen; i++) { - const face = faces[i]; - f3(face[0] + offset, face[1] + offset, face[2] + offset); } - } else { - // Bottom faces - for (let i = 0; i < flen; i++) { - const face = faces[i]; - f3(face[2], face[1], face[0]); - } // Top faces + if ( morphNormals && geometry.getAttribute( 'morphNormal' + i ) !== morphNormals[ index ] ) { - for (let i = 0; i < flen; i++) { - const face = faces[i]; - f3(face[0] + vlen * steps, face[1] + vlen * steps, face[2] + vlen * steps); - } - } + geometry.setAttribute( 'morphNormal' + i, morphNormals[ index ] ); - scope.addGroup(start, verticesArray.length / 3 - start, 0); - } // Create faces for the z-sides of the shape + } + morphInfluences[ i ] = value; + morphInfluencesSum += value; - function buildSideFaces() { - const start = verticesArray.length / 3; - let layeroffset = 0; - sidewalls(contour, layeroffset); - layeroffset += contour.length; + } else { - for (let h = 0, hl = holes.length; h < hl; h++) { - const ahole = holes[h]; - sidewalls(ahole, layeroffset); //, true + if ( morphTargets && geometry.hasAttribute( 'morphTarget' + i ) === true ) { - layeroffset += ahole.length; - } + geometry.deleteAttribute( 'morphTarget' + i ); - scope.addGroup(start, verticesArray.length / 3 - start, 1); - } + } - function sidewalls(contour, layeroffset) { - let i = contour.length; + if ( morphNormals && geometry.hasAttribute( 'morphNormal' + i ) === true ) { - 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); + geometry.deleteAttribute( 'morphNormal' + i ); - 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; - f4(a, b, c, d); } + + morphInfluences[ i ] = 0; + } - } - function v(x, y, z) { - placeholder.push(x); - placeholder.push(y); - placeholder.push(z); } - function f3(a, b, c) { - addVertex(a); - addVertex(b); - addVertex(c); - const nextIndex = verticesArray.length / 3; - const uvs = uvgen.generateTopUV(scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1); - addUV(uvs[0]); - addUV(uvs[1]); - addUV(uvs[2]); - } - - function f4(a, b, c, d) { - addVertex(a); - addVertex(b); - addVertex(d); - addVertex(b); - addVertex(c); - addVertex(d); - const nextIndex = verticesArray.length / 3; - const uvs = uvgen.generateSideWallUV(scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1); - addUV(uvs[0]); - addUV(uvs[1]); - addUV(uvs[3]); - addUV(uvs[1]); - addUV(uvs[2]); - addUV(uvs[3]); - } + // 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; - function addVertex(index) { - verticesArray.push(placeholder[index * 3 + 0]); - verticesArray.push(placeholder[index * 3 + 1]); - verticesArray.push(placeholder[index * 3 + 2]); - } + program.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence ); + program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences ); - 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 = []; + return { - for (let j = 0, jl = data.shapes.length; j < jl; j++) { - const shape = shapes[data.shapes[j]]; - geometryShapes.push(shape); - } + update: update - const extrudePath = data.options.extrudePath; + }; - if (extrudePath !== undefined) { - data.options.extrudePath = new Curves[extrudePath.type]().fromJSON(extrudePath); - } + } - return new ExtrudeGeometry(geometryShapes, data.options); - } + function WebGLObjects( gl, geometries, attributes, info ) { - } + let updateMap = new WeakMap(); - const WorldUVGenerator = { - generateTopUV: function (geometry, vertices, indexA, indexB, indexC) { - const a_x = vertices[indexA * 3]; - const a_y = vertices[indexA * 3 + 1]; - const b_x = vertices[indexB * 3]; - const b_y = vertices[indexB * 3 + 1]; - const c_x = vertices[indexC * 3]; - const c_y = vertices[indexC * 3 + 1]; - return [new Vector2(a_x, a_y), new Vector2(b_x, b_y), new Vector2(c_x, c_y)]; - }, - generateSideWallUV: function (geometry, vertices, indexA, indexB, indexC, indexD) { - const a_x = vertices[indexA * 3]; - const a_y = vertices[indexA * 3 + 1]; - const a_z = vertices[indexA * 3 + 2]; - const b_x = vertices[indexB * 3]; - const b_y = vertices[indexB * 3 + 1]; - const b_z = vertices[indexB * 3 + 2]; - const c_x = vertices[indexC * 3]; - const c_y = vertices[indexC * 3 + 1]; - const c_z = vertices[indexC * 3 + 2]; - 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 { - return [new Vector2(a_y, 1 - a_z), new Vector2(b_y, 1 - b_z), new Vector2(c_y, 1 - c_z), new Vector2(d_y, 1 - d_z)]; - } - } - }; + function update( object ) { - function toJSON$1(shapes, options, data) { - data.shapes = []; + const frame = info.render.frame; - if (Array.isArray(shapes)) { - for (let i = 0, l = shapes.length; i < l; i++) { - const shape = shapes[i]; - data.shapes.push(shape.uuid); - } - } else { - data.shapes.push(shapes.uuid); - } + const geometry = object.geometry; + const buffergeometry = geometries.get( object, geometry ); - data.options = Object.assign({}, options); - if (options.extrudePath !== undefined) data.options.extrudePath = options.extrudePath.toJSON(); - return data; - } + // Update once per frame - class IcosahedronGeometry extends PolyhedronGeometry { - constructor(radius = 1, detail = 0) { - const t = (1 + Math.sqrt(5)) / 2; - const vertices = [-1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, 0, -1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, t, 0, -1, t, 0, 1, -t, 0, -1, -t, 0, 1]; - const indices = [0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1]; - super(vertices, indices, radius, detail); - this.type = 'IcosahedronGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; - } + if ( updateMap.get( buffergeometry ) !== frame ) { - static fromJSON(data) { - return new IcosahedronGeometry(data.radius, data.detail); - } + geometries.update( buffergeometry ); - } + updateMap.set( buffergeometry, frame ); - class OctahedronGeometry extends PolyhedronGeometry { - constructor(radius = 1, detail = 0) { - const vertices = [1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1]; - const indices = [0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2]; - super(vertices, indices, radius, detail); - this.type = 'OctahedronGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; - } + } - static fromJSON(data) { - return new OctahedronGeometry(data.radius, data.detail); - } + if ( object.isInstancedMesh ) { - } + if ( object.hasEventListener( 'dispose', onInstancedMeshDispose ) === false ) { - class RingGeometry extends BufferGeometry { - constructor(innerRadius = 0.5, outerRadius = 1, thetaSegments = 8, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2) { - super(); - this.type = 'RingGeometry'; - this.parameters = { - innerRadius: innerRadius, - outerRadius: outerRadius, - thetaSegments: thetaSegments, - phiSegments: phiSegments, - thetaStart: thetaStart, - thetaLength: thetaLength - }; - thetaSegments = Math.max(3, thetaSegments); - phiSegments = Math.max(1, phiSegments); // buffers + object.addEventListener( 'dispose', onInstancedMeshDispose ); - const indices = []; - const vertices = []; - const normals = []; - 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 + attributes.update( object.instanceMatrix, gl.ARRAY_BUFFER ); - 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 + if ( object.instanceColor !== null ) { - vertex.x = radius * Math.cos(segment); - vertex.y = radius * Math.sin(segment); - vertices.push(vertex.x, vertex.y, vertex.z); // normal + attributes.update( object.instanceColor, gl.ARRAY_BUFFER ); - normals.push(0, 0, 1); // 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 + } + return buffergeometry; - radius += radiusStep; - } // indices + } + function dispose() { - for (let j = 0; j < phiSegments; j++) { - const thetaSegmentLevel = j * (thetaSegments + 1); + updateMap = new WeakMap(); - 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 + } - indices.push(a, b, d); - indices.push(b, c, d); - } - } // build geometry + function onInstancedMeshDispose( event ) { + + const instancedMesh = event.target; + instancedMesh.removeEventListener( 'dispose', onInstancedMeshDispose ); - this.setIndex(indices); - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - } + attributes.remove( instancedMesh.instanceMatrix ); + + if ( instancedMesh.instanceColor !== null ) attributes.remove( instancedMesh.instanceColor ); - static fromJSON(data) { - return new RingGeometry(data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength); } - } + return { - class ShapeGeometry extends BufferGeometry { - constructor(shapes = new Shape([new Vector2(0, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)]), curveSegments = 12) { - super(); - this.type = 'ShapeGeometry'; - this.parameters = { - shapes: shapes, - curveSegments: curveSegments - }; // buffers + update: update, + dispose: dispose - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // helper variables + }; - let groupStart = 0; - let groupCount = 0; // allow single and array values for "shapes" parameter + } - if (Array.isArray(shapes) === false) { - addShape(shapes); - } else { - for (let i = 0; i < shapes.length; i++) { - addShape(shapes[i]); - this.addGroup(groupStart, groupCount, i); // enables MultiMaterial support + /** + * Uniforms of a program. + * Those form a tree structure with a special top-level container for the root, + * which you get by calling 'new WebGLUniforms( gl, program )'. + * + * + * Properties of inner nodes including the top-level container: + * + * .seq - array of nested uniforms + * .map - nested uniforms by name + * + * + * Methods of all nodes except the top-level container: + * + * .setValue( gl, value, [textures] ) + * + * uploads a uniform value(s) + * the 'textures' parameter is needed for sampler uniforms + * + * + * Static methods of the top-level container (textures factorizations): + * + * .upload( gl, seq, values, textures ) + * + * sets uniforms in 'seq' to 'values[id].value' + * + * .seqWithValue( seq, values ) : filteredSeq + * + * filters 'seq' entries with corresponding entry in values + * + * + * Methods of the top-level container (textures factorizations): + * + * .setValue( gl, name, value, textures ) + * + * sets uniform with name 'name' to 'value' + * + * .setOptional( gl, obj, prop ) + * + * like .set for an optional property of the object + * + */ - groupStart += groupCount; - groupCount = 0; - } - } // build geometry + const emptyTexture = /*@__PURE__*/ new Texture(); + const emptyArrayTexture = /*@__PURE__*/ new DataArrayTexture(); + const empty3dTexture = /*@__PURE__*/ new Data3DTexture(); + const emptyCubeTexture = /*@__PURE__*/ new CubeTexture(); + // --- Utilities --- - 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 + // Array Caches (provide typed arrays for temporary by size) - 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 arrayCacheF32 = []; + const arrayCacheI32 = []; - if (ShapeUtils.isClockWise(shapeVertices) === false) { - shapeVertices = shapeVertices.reverse(); - } + // Float32Array caches used for uploading Matrix uniforms - for (let i = 0, l = shapeHoles.length; i < l; i++) { - const shapeHole = shapeHoles[i]; + const mat4array = new Float32Array( 16 ); + const mat3array = new Float32Array( 9 ); + const mat2array = new Float32Array( 4 ); - if (ShapeUtils.isClockWise(shapeHole) === true) { - shapeHoles[i] = shapeHole.reverse(); - } - } + // Flattening for arrays of vectors and matrices - const faces = ShapeUtils.triangulateShape(shapeVertices, shapeHoles); // join vertices of inner and outer paths to a single array + function flatten( array, nBlocks, blockSize ) { - for (let i = 0, l = shapeHoles.length; i < l; i++) { - const shapeHole = shapeHoles[i]; - shapeVertices = shapeVertices.concat(shapeHole); - } // vertices, normals, uvs + const firstElem = array[ 0 ]; + if ( firstElem <= 0 || firstElem > 0 ) return array; + // unoptimized: ! isNaN( firstElem ) + // see http://jacksondunstan.com/articles/983 - 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 + const n = nBlocks * blockSize; + let r = arrayCacheF32[ n ]; + if ( r === undefined ) { - for (let i = 0, l = faces.length; i < l; i++) { - const face = faces[i]; - const a = face[0] + indexOffset; - const b = face[1] + indexOffset; - const c = face[2] + indexOffset; - indices.push(a, b, c); - groupCount += 3; - } - } - } + r = new Float32Array( n ); + arrayCacheF32[ n ] = r; - toJSON() { - const data = super.toJSON(); - const shapes = this.parameters.shapes; - return toJSON(shapes, data); } - static fromJSON(data, shapes) { - const geometryShapes = []; + if ( nBlocks !== 0 ) { + + firstElem.toArray( r, 0 ); + + for ( let i = 1, offset = 0; i !== nBlocks; ++ i ) { + + offset += blockSize; + array[ i ].toArray( r, offset ); - 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); } + return r; + } - function toJSON(shapes, data) { - data.shapes = []; + 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; - if (Array.isArray(shapes)) { - for (let i = 0, l = shapes.length; i < l; i++) { - const shape = shapes[i]; - data.shapes.push(shape.uuid); - } - } else { - data.shapes.push(shapes.uuid); } - return data; + return true; + } - class SphereGeometry extends BufferGeometry { - constructor(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI) { - super(); - this.type = 'SphereGeometry'; - this.parameters = { - radius: radius, - widthSegments: widthSegments, - heightSegments: heightSegments, - phiStart: phiStart, - phiLength: phiLength, - thetaStart: thetaStart, - thetaLength: thetaLength - }; - widthSegments = Math.max(3, Math.floor(widthSegments)); - heightSegments = Math.max(2, Math.floor(heightSegments)); - const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI); - let index = 0; - const grid = []; - const vertex = new Vector3(); - const normal = new Vector3(); // buffers + function copyArray( a, b ) { - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // generate vertices, normals and uvs + for ( let i = 0, l = b.length; i < l; i ++ ) { - for (let iy = 0; iy <= heightSegments; iy++) { - const verticesRow = []; - const v = iy / heightSegments; // special case for the poles + a[ i ] = b[ i ]; - 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 + // Texture unit allocation - 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 + function allocTexUnits( textures, n ) { - normal.copy(vertex).normalize(); - normals.push(normal.x, normal.y, normal.z); // uv + let r = arrayCacheI32[ n ]; - uvs.push(u + uOffset, 1 - v); - verticesRow.push(index++); - } + if ( r === undefined ) { - grid.push(verticesRow); - } // indices + r = new Int32Array( n ); + arrayCacheI32[ n ] = r; + } - for (let iy = 0; iy < heightSegments; iy++) { - for (let ix = 0; ix < widthSegments; ix++) { - const a = grid[iy][ix + 1]; - const b = grid[iy][ix]; - const c = grid[iy + 1][ix]; - const d = grid[iy + 1][ix + 1]; - if (iy !== 0 || thetaStart > 0) indices.push(a, b, d); - if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d); - } - } // build geometry + for ( let i = 0; i !== n; ++ i ) { + r[ i ] = textures.allocateTextureUnit(); - 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); - } + return r; } - class TetrahedronGeometry extends PolyhedronGeometry { - constructor(radius = 1, detail = 0) { - const vertices = [1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1]; - const indices = [2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1]; - super(vertices, indices, radius, detail); - this.type = 'TetrahedronGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; - } + // --- Setters --- - static fromJSON(data) { - return new TetrahedronGeometry(data.radius, data.detail); - } + // Note: Defining these methods externally, because they come in a bunch + // and this way their names minify. + + // Single scalar + + function setValueV1f( gl, v ) { + + const cache = this.cache; + + if ( cache[ 0 ] === v ) return; + + gl.uniform1f( this.addr, v ); + + cache[ 0 ] = v; } - class TorusGeometry extends BufferGeometry { - constructor(radius = 1, tube = 0.4, radialSegments = 8, tubularSegments = 6, arc = Math.PI * 2) { - super(); - this.type = 'TorusGeometry'; - this.parameters = { - radius: radius, - tube: tube, - radialSegments: radialSegments, - tubularSegments: tubularSegments, - arc: arc - }; - radialSegments = Math.floor(radialSegments); - tubularSegments = Math.floor(tubularSegments); // buffers + // Single float vector (from flat array or THREE.VectorN) - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // helper variables + function setValueV2f( gl, v ) { - const center = new Vector3(); - const vertex = new Vector3(); - const normal = new Vector3(); // generate vertices, normals and uvs + const cache = this.cache; - 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 + if ( v.x !== undefined ) { - 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 + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { - 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 + gl.uniform2f( this.addr, v.x, v.y ); - uvs.push(i / tubularSegments); - uvs.push(j / radialSegments); - } - } // generate indices + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + } - 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 + } else { - indices.push(a, b, d); - indices.push(b, c, d); - } - } // build geometry + if ( arraysEqual( cache, v ) ) return; + gl.uniform2fv( this.addr, v ); - this.setIndex(indices); - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - } + copyArray( cache, v ); - static fromJSON(data) { - return new TorusGeometry(data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc); } } - class TorusKnotGeometry extends BufferGeometry { - constructor(radius = 1, tube = 0.4, tubularSegments = 64, radialSegments = 8, p = 2, q = 3) { - super(); - this.type = 'TorusKnotGeometry'; - this.parameters = { - radius: radius, - tube: tube, - tubularSegments: tubularSegments, - radialSegments: radialSegments, - p: p, - q: q - }; - tubularSegments = Math.floor(tubularSegments); - radialSegments = Math.floor(radialSegments); // buffers - - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; // helper variables + function setValueV3f( gl, v ) { - const vertex = new Vector3(); - const normal = new Vector3(); - const P1 = new Vector3(); - const P2 = new Vector3(); - const B = new Vector3(); - const T = new Vector3(); - const N = new Vector3(); // generate vertices, normals and uvs + const cache = this.cache; - 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. - // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions + if ( v.x !== undefined ) { - calculatePositionOnCurve(u, p, q, radius, P1); - calculatePositionOnCurve(u + 0.01, p, q, radius, P2); // calculate orthonormal basis + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) { - 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 + gl.uniform3f( this.addr, v.x, v.y, v.z ); - B.normalize(); - N.normalize(); + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + cache[ 2 ] = v.z; - 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. - // 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) + } else if ( v.r !== undefined ) { - normal.subVectors(vertex, P1).normalize(); - normals.push(normal.x, normal.y, normal.z); // uv + if ( cache[ 0 ] !== v.r || cache[ 1 ] !== v.g || cache[ 2 ] !== v.b ) { - uvs.push(i / tubularSegments); - uvs.push(j / radialSegments); - } - } // generate indices + gl.uniform3f( this.addr, v.r, v.g, v.b ); + cache[ 0 ] = v.r; + cache[ 1 ] = v.g; + cache[ 2 ] = v.b; - 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 + } - indices.push(a, b, d); - indices.push(b, c, d); - } - } // build geometry + } else { + if ( arraysEqual( cache, v ) ) return; - 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 + gl.uniform3fv( this.addr, v ); - function calculatePositionOnCurve(u, p, q, radius, position) { - const cu = Math.cos(u); - const su = Math.sin(u); - const quOverP = q / p * u; - const cs = Math.cos(quOverP); - position.x = radius * (2 + cs) * 0.5 * cu; - position.y = radius * (2 + cs) * su * 0.5; - position.z = radius * Math.sin(quOverP) * 0.5; - } - } + copyArray( cache, v ); - static fromJSON(data) { - return new TorusKnotGeometry(data.radius, data.tube, data.tubularSegments, data.radialSegments, data.p, data.q); } } - class TubeGeometry extends BufferGeometry { - constructor(path = new QuadraticBezierCurve3(new Vector3(-1, -1, 0), new Vector3(-1, 1, 0), new Vector3(1, 1, 0)), tubularSegments = 64, radius = 1, radialSegments = 8, closed = false) { - super(); - this.type = 'TubeGeometry'; - this.parameters = { - path: path, - tubularSegments: tubularSegments, - radius: radius, - radialSegments: radialSegments, - closed: closed - }; - const frames = path.computeFrenetFrames(tubularSegments, closed); // expose internals + function setValueV4f( gl, v ) { - this.tangents = frames.tangents; - this.normals = frames.normals; - this.binormals = frames.binormals; // helper variables + const cache = this.cache; - const vertex = new Vector3(); - const normal = new Vector3(); - const uv = new Vector2(); - let P = new Vector3(); // buffer + if ( v.x !== undefined ) { - const vertices = []; - const normals = []; - const uvs = []; - const indices = []; // create buffer data + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) { - generateBufferData(); // build geometry + gl.uniform4f( this.addr, v.x, v.y, v.z, v.w ); - 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 + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + cache[ 2 ] = v.z; + cache[ 3 ] = v.w; - 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 - // at the regular position on the given path - // - // if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ) + } + } else { - generateSegment(closed === false ? tubularSegments : 0); // uvs are generated in a separate function. - // this makes it easy compute correct values for closed geometries + if ( arraysEqual( cache, v ) ) return; - generateUVs(); // finally create faces + gl.uniform4fv( this.addr, v ); - generateIndices(); - } + copyArray( cache, v ); - 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 + } - const N = frames.normals[i]; - 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 + // Single matrix (from flat array or THREE.MatrixN) - 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 + function setValueM2( gl, v ) { - vertex.x = P.x + radius * normal.x; - vertex.y = P.y + radius * normal.y; - vertex.z = P.z + radius * normal.z; - vertices.push(vertex.x, vertex.y, vertex.z); - } - } + const cache = this.cache; + const elements = v.elements; - 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 + if ( elements === undefined ) { - indices.push(a, b, d); - indices.push(b, c, d); - } - } - } + if ( arraysEqual( cache, v ) ) return; + + gl.uniformMatrix2fv( this.addr, false, v ); + + copyArray( cache, v ); + + } else { + + if ( arraysEqual( cache, elements ) ) return; + + mat2array.set( elements ); + + gl.uniformMatrix2fv( this.addr, false, mat2array ); + + copyArray( cache, elements ); - function generateUVs() { - for (let i = 0; i <= tubularSegments; i++) { - for (let j = 0; j <= radialSegments; j++) { - uv.x = i / tubularSegments; - uv.y = j / radialSegments; - uvs.push(uv.x, uv.y); - } - } - } } - toJSON() { - const data = super.toJSON(); - data.path = this.parameters.path.toJSON(); - return data; + } + + 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 ); + + copyArray( cache, v ); + + } else { + + if ( arraysEqual( cache, elements ) ) return; + + mat3array.set( elements ); + + gl.uniformMatrix3fv( this.addr, false, mat3array ); + + copyArray( cache, elements ); + } - 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); + } + + 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 ); + + copyArray( cache, v ); + + } else { + + if ( arraysEqual( cache, elements ) ) return; + + mat4array.set( elements ); + + gl.uniformMatrix4fv( this.addr, false, mat4array ); + + copyArray( cache, elements ); + } } - class WireframeGeometry extends BufferGeometry { - constructor(geometry = null) { - super(); - this.type = 'WireframeGeometry'; - this.parameters = { - geometry: geometry - }; + // Single integer / boolean - if (geometry !== null) { - // buffer - const vertices = []; - const edges = new Set(); // helper variables + function setValueV1i( gl, v ) { - const start = new Vector3(); - const end = new Vector3(); + const cache = this.cache; - if (geometry.index !== null) { - // indexed BufferGeometry - const position = geometry.attributes.position; - const indices = geometry.index; - let groups = geometry.groups; + if ( cache[ 0 ] === v ) return; - if (groups.length === 0) { - groups = [{ - start: 0, - count: indices.count, - materialIndex: 0 - }]; - } // create a data structure that contains all edges without duplicates + gl.uniform1i( this.addr, v ); + cache[ 0 ] = v; - 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); + // Single integer / boolean vector (from flat array or THREE.VectorN) - if (isUniqueEdge(start, end, edges) === true) { - vertices.push(start.x, start.y, start.z); - vertices.push(end.x, end.y, end.z); - } - } - } - } - } else { - // non-indexed BufferGeometry - const position = geometry.attributes.position; + function setValueV2i( gl, v ) { - 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); + const cache = this.cache; - if (isUniqueEdge(start, end, edges) === true) { - vertices.push(start.x, start.y, start.z); - vertices.push(end.x, end.y, end.z); - } - } - } - } // build geometry + 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; - this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); } + + } else { + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform2iv( this.addr, v ); + + copyArray( cache, v ); + } } - 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 + function setValueV3i( gl, v ) { + + const cache = this.cache; + + 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; + + } - if (edges.has(hash1) === true || edges.has(hash2) === true) { - return false; } else { - edges.add(hash1); - edges.add(hash2); - return true; + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform3iv( this.addr, v ); + + copyArray( cache, v ); + } + } - 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 - }); + function setValueV4i( gl, v ) { - class ShadowMaterial extends Material { - constructor(parameters) { - super(); - this.isShadowMaterial = true; - this.type = 'ShadowMaterial'; - this.color = new Color(0x000000); - this.transparent = true; - this.fog = true; - this.setValues(parameters); - } + 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.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 ); - copy(source) { - super.copy(source); - this.color.copy(source.color); - this.fog = source.fog; - return this; } } - class RawShaderMaterial extends ShaderMaterial { - constructor(parameters) { - super(parameters); - this.isRawShaderMaterial = true; - this.type = 'RawShaderMaterial'; - } + // Single unsigned integer + + function setValueV1ui( gl, v ) { + + const cache = this.cache; + + if ( cache[ 0 ] === v ) return; + + gl.uniform1ui( this.addr, v ); + + cache[ 0 ] = v; } - class MeshStandardMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshStandardMaterial = true; - this.defines = { - 'STANDARD': '' - }; - this.type = 'MeshStandardMaterial'; - this.color = new Color(0xffffff); // diffuse + // Single unsigned integer vector (from flat array or THREE.VectorN) + + function setValueV2ui( gl, v ) { + + const cache = this.cache; + + 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 ); - this.roughness = 1.0; - this.metalness = 0.0; - this.map = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; - this.emissive = new Color(0x000000); - this.emissiveIntensity = 1.0; - this.emissiveMap = null; - this.bumpMap = null; - this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2(1, 1); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.roughnessMap = null; - this.metalnessMap = null; - this.alphaMap = null; - this.envMap = null; - this.envMapIntensity = 1.0; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; - this.flatShading = false; - this.fog = true; - this.setValues(parameters); - } - - copy(source) { - super.copy(source); - this.defines = { - 'STANDARD': '' - }; - this.color.copy(source.color); - this.roughness = source.roughness; - this.metalness = source.metalness; - this.map = source.map; - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; - this.emissive.copy(source.emissive); - this.emissiveMap = source.emissiveMap; - this.emissiveIntensity = source.emissiveIntensity; - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy(source.normalScale); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.roughnessMap = source.roughnessMap; - this.metalnessMap = source.metalnessMap; - this.alphaMap = source.alphaMap; - this.envMap = source.envMap; - this.envMapIntensity = source.envMapIntensity; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; - this.flatShading = source.flatShading; - this.fog = source.fog; - return this; } } - class MeshPhysicalMaterial extends MeshStandardMaterial { - constructor(parameters) { - super(); - this.isMeshPhysicalMaterial = true; - this.defines = { - 'STANDARD': '', - 'PHYSICAL': '' - }; - this.type = 'MeshPhysicalMaterial'; - this.clearcoatMap = null; - this.clearcoatRoughness = 0.0; - this.clearcoatRoughnessMap = null; - this.clearcoatNormalScale = new Vector2(1, 1); - this.clearcoatNormalMap = null; - this.ior = 1.5; - Object.defineProperty(this, 'reflectivity', { - get: function () { - return clamp(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1); - }, - set: function (reflectivity) { - this.ior = (1 + 0.4 * reflectivity) / (1 - 0.4 * reflectivity); - } - }); - this.iridescenceMap = null; - this.iridescenceIOR = 1.3; - this.iridescenceThicknessRange = [100, 400]; - this.iridescenceThicknessMap = null; - this.sheenColor = new Color(0x000000); - this.sheenColorMap = null; - this.sheenRoughness = 1.0; - this.sheenRoughnessMap = null; - this.transmissionMap = null; - this.thickness = 0; - this.thicknessMap = null; - this.attenuationDistance = 0.0; - this.attenuationColor = new Color(1, 1, 1); - this.specularIntensity = 1.0; - this.specularIntensityMap = null; - this.specularColor = new Color(1, 1, 1); - this.specularColorMap = null; - this._sheen = 0.0; - this._clearcoat = 0; - this._iridescence = 0; - this._transmission = 0; - this.setValues(parameters); - } + function setValueV3ui( gl, v ) { - get sheen() { - return this._sheen; - } + const cache = this.cache; - set sheen(value) { - if (this._sheen > 0 !== value > 0) { - this.version++; - } + if ( v.x !== undefined ) { - this._sheen = value; - } + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) { - get clearcoat() { - return this._clearcoat; - } + gl.uniform3ui( this.addr, v.x, v.y, v.z ); + + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + cache[ 2 ] = v.z; - set clearcoat(value) { - if (this._clearcoat > 0 !== value > 0) { - this.version++; } - this._clearcoat = value; - } + } else { - get iridescence() { - return this._iridescence; - } + if ( arraysEqual( cache, v ) ) return; - set iridescence(value) { - if (this._iridescence > 0 !== value > 0) { - this.version++; - } + gl.uniform3uiv( this.addr, v ); - this._iridescence = value; - } + copyArray( cache, v ); - get transmission() { - return this._transmission; } - set transmission(value) { - if (this._transmission > 0 !== value > 0) { - this.version++; + } + + function setValueV4ui( 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.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; + } - this._transmission = value; - } + } else { + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform4uiv( this.addr, v ); + + copyArray( cache, v ); - copy(source) { - super.copy(source); - this.defines = { - 'STANDARD': '', - 'PHYSICAL': '' - }; - this.clearcoat = source.clearcoat; - this.clearcoatMap = source.clearcoatMap; - this.clearcoatRoughness = source.clearcoatRoughness; - this.clearcoatRoughnessMap = source.clearcoatRoughnessMap; - this.clearcoatNormalMap = source.clearcoatNormalMap; - this.clearcoatNormalScale.copy(source.clearcoatNormalScale); - this.ior = source.ior; - this.iridescence = source.iridescence; - this.iridescenceMap = source.iridescenceMap; - this.iridescenceIOR = source.iridescenceIOR; - this.iridescenceThicknessRange = [...source.iridescenceThicknessRange]; - this.iridescenceThicknessMap = source.iridescenceThicknessMap; - this.sheen = source.sheen; - this.sheenColor.copy(source.sheenColor); - this.sheenColorMap = source.sheenColorMap; - this.sheenRoughness = source.sheenRoughness; - this.sheenRoughnessMap = source.sheenRoughnessMap; - this.transmission = source.transmission; - this.transmissionMap = source.transmissionMap; - this.thickness = source.thickness; - this.thicknessMap = source.thicknessMap; - this.attenuationDistance = source.attenuationDistance; - this.attenuationColor.copy(source.attenuationColor); - this.specularIntensity = source.specularIntensity; - this.specularIntensityMap = source.specularIntensityMap; - this.specularColor.copy(source.specularColor); - this.specularColorMap = source.specularColorMap; - return this; } } - class MeshPhongMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshPhongMaterial = true; - this.type = 'MeshPhongMaterial'; - this.color = new Color(0xffffff); // diffuse - this.specular = new Color(0x111111); - this.shininess = 30; - this.map = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; - this.emissive = new Color(0x000000); - this.emissiveIntensity = 1.0; - this.emissiveMap = null; - this.bumpMap = null; - this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2(1, 1); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.specularMap = null; - this.alphaMap = null; - this.envMap = null; - this.combine = MultiplyOperation; - this.reflectivity = 1; - this.refractionRatio = 0.98; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; - this.flatShading = false; - this.fog = true; - this.setValues(parameters); - } + // 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; - copy(source) { - super.copy(source); - this.color.copy(source.color); - this.specular.copy(source.specular); - this.shininess = source.shininess; - this.map = source.map; - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; - this.emissive.copy(source.emissive); - this.emissiveMap = source.emissiveMap; - this.emissiveIntensity = source.emissiveIntensity; - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy(source.normalScale); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.specularMap = source.specularMap; - this.alphaMap = source.alphaMap; - this.envMap = source.envMap; - this.combine = source.combine; - this.reflectivity = source.reflectivity; - this.refractionRatio = source.refractionRatio; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; - this.flatShading = source.flatShading; - this.fog = source.fog; - return this; } + textures.setTexture2D( v || emptyTexture, unit ); + } - class MeshToonMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshToonMaterial = true; - this.defines = { - 'TOON': '' - }; - this.type = 'MeshToonMaterial'; - this.color = new Color(0xffffff); - this.map = null; - this.gradientMap = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; - this.emissive = new Color(0x000000); - this.emissiveIntensity = 1.0; - this.emissiveMap = null; - this.bumpMap = null; - this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2(1, 1); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.alphaMap = null; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; - this.fog = true; - this.setValues(parameters); - } + 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; - copy(source) { - super.copy(source); - this.color.copy(source.color); - this.map = source.map; - this.gradientMap = source.gradientMap; - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; - this.emissive.copy(source.emissive); - this.emissiveMap = source.emissiveMap; - this.emissiveIntensity = source.emissiveIntensity; - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy(source.normalScale); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.alphaMap = source.alphaMap; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; - this.fog = source.fog; - return this; } + textures.setTexture3D( v || empty3dTexture, unit ); + } - class MeshNormalMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshNormalMaterial = true; - this.type = 'MeshNormalMaterial'; - this.bumpMap = null; - this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2(1, 1); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.flatShading = false; - this.setValues(parameters); + 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; + } - copy(source) { - super.copy(source); - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy(source.normalScale); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.flatShading = source.flatShading; - return this; + 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 ); + } - class MeshLambertMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshLambertMaterial = true; - this.type = 'MeshLambertMaterial'; - this.color = new Color(0xffffff); // diffuse + // 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 + + case 0x8b5a: return setValueM2; // _MAT2 + case 0x8b5b: return setValueM3; // _MAT3 + case 0x8b5c: return setValueM4; // _MAT4 + + case 0x1404: 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; // _VEC4 + + 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; - this.map = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; - this.emissive = new Color(0x000000); - this.emissiveIntensity = 1.0; - this.emissiveMap = null; - this.specularMap = null; - this.alphaMap = null; - this.envMap = null; - this.combine = MultiplyOperation; - this.reflectivity = 1; - this.refractionRatio = 0.98; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; - this.fog = true; - 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; + } + + + // Array of scalars + + function setValueV1fArray( gl, v ) { + + gl.uniform1fv( this.addr, v ); + + } + + // 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) + + 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 + + function setValueV1iArray( gl, v ) { + + gl.uniform1iv( this.addr, v ); + + } + + // 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 + + function setValueV1uiArray( gl, v ) { + + gl.uniform1uiv( this.addr, v ); + + } + + // 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) + + function setValueT1Array( gl, v, textures ) { + + const cache = this.cache; + + const n = v.length; + + const units = allocTexUnits( textures, n ); + + 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 ] ); + } } - class MeshMatcapMaterial extends Material { - constructor(parameters) { - super(); - this.isMeshMatcapMaterial = true; - this.defines = { - 'MATCAP': '' - }; - this.type = 'MeshMatcapMaterial'; - this.color = new Color(0xffffff); // diffuse + function setValueT3DArray( gl, v, textures ) { + + const cache = this.cache; + + const n = v.length; + + const units = allocTexUnits( textures, n ); + + if ( ! arraysEqual( cache, units ) ) { + + gl.uniform1iv( this.addr, units ); + + copyArray( cache, units ); - this.matcap = null; - this.map = null; - this.bumpMap = null; - this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2(1, 1); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - this.alphaMap = null; - this.flatShading = false; - this.fog = true; - this.setValues(parameters); } - copy(source) { - super.copy(source); - this.defines = { - 'MATCAP': '' - }; - this.color.copy(source.color); - this.matcap = source.matcap; - this.map = source.map; - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy(source.normalScale); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.alphaMap = source.alphaMap; - this.flatShading = source.flatShading; - this.fog = source.fog; - return this; + 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 ); + + 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 ); + + 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 + + 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 + + case 0x8b5a: return setValueM2Array; // _MAT2 + case 0x8b5b: return setValueM3Array; // _MAT3 + case 0x8b5c: return setValueM4Array; // _MAT4 + + case 0x1404: 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; // _VEC4 + + 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 --- + + class SingleUniform { + + constructor( id, activeInfo, addr ) { + + this.id = id; + this.addr = addr; + this.cache = []; + this.setValue = getSingularSetter( activeInfo.type ); + + // this.path = activeInfo.name; // DEBUG + + } + + } + + class PureArrayUniform { + + constructor( id, activeInfo, addr ) { + + this.id = id; + this.addr = addr; + this.cache = []; + this.size = activeInfo.size; + this.setValue = getPureArraySetter( activeInfo.type ); + + // this.path = activeInfo.name; // DEBUG + + } + + } + + class StructuredUniform { + + constructor( id ) { + + this.id = id; + + 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 --- + + // Parser - builds up the property tree from the path strings + + const RePathPart = /(\w+)(\])?(\[|\.)?/g; + + // extracts + // - the identifier (member name or array index) + // - followed by an optional right bracket (found when array index) + // - followed by an optional left bracket or dot (type of subscript) + // + // Note: These portions can be read in a non-overlapping fashion and + // allow straightforward parsing of the hierarchy that WebGL encodes + // in the uniform names. + + 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 + RePathPart.lastIndex = 0; + + while ( true ) { + + const match = RePathPart.exec( path ), + matchEnd = RePathPart.lastIndex; + + let id = match[ 1 ]; + const idIsIndex = match[ 2 ] === ']', + 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 + + 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 ); + + 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 ]; + + 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 ) { + + const shader = gl.createShader( type ); + + gl.shaderSource( shader, string ); + gl.compileShader( shader ); + + return shader; + + } + + 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 ); + + attributes[ name ] = { + type: info.type, + location: gl.getAttribLocation( program, name ), + locationSize: locationSize + }; + + } + + return attributes; + + } + + function filterEmptyLine( string ) { + + return 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 ); + + } + + function replaceClippingPlaneNums( string, parameters ) { + + return string + .replace( /NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes ) + .replace( /UNION_CLIPPING_PLANES/g, ( parameters.numClippingPlanes - parameters.numClipIntersection ) ); + + } + + // 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 + + 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 ); + + } + + 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' ) { + + precisionstring += '\n#define MEDIUM_PRECISION'; + + } 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 ) { + + shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; + + } 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: + + envMapModeDefine = 'ENVMAP_MODE_REFRACTION'; + 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; + + const maxMip = Math.log2( imageHeight ) - 2; + + const texelHeight = 1.0 / imageHeight; + + const texelWidth = 1.0 / ( 3 * Math.max( Math.pow( 2, maxMip ), 7 * 16 ) ); + + return { texelWidth, texelHeight, 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; + let fragmentShader = parameters.fragmentShader; + + const shadowMapTypeDefine = generateShadowMapTypeDefine( parameters ); + const envMapTypeDefine = generateEnvMapTypeDefine( parameters ); + const envMapModeDefine = generateEnvMapModeDefine( parameters ); + const envMapBlendingDefine = generateEnvMapBlendingDefine( parameters ); + const envMapCubeUVSize = generateCubeUVSize( parameters ); + + const customExtensions = parameters.isWebGL2 ? '' : generateExtensions( parameters ); + + const customDefines = generateDefines( defines ); + + 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 + 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 ); + + fragmentShader = resolveIncludes( fragmentShader ); + fragmentShader = replaceLightNums( fragmentShader, parameters ); + fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters ); + + vertexShader = unrollLoops( vertexShader ); + fragmentShader = unrollLoops( fragmentShader ); + + if ( parameters.isWebGL2 && parameters.isRawShaderMaterial !== true ) { + + // GLSL 3.0 conversion for built-in materials and ShaderMaterial + + versionString = '#version 300 es\n'; + + prefixVertex = [ + '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 ); + // 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. + + if ( parameters.index0AttributeName !== undefined ) { + + gl.bindAttribLocation( program, 0, parameters.index0AttributeName ); + + } else if ( parameters.morphTargets === true ) { + + // programs with morphTargets displace position out of attribute 0 + gl.bindAttribLocation( program, 0, 'position' ); + + } + + gl.linkProgram( program ); + + // check for link errors + if ( renderer.debug.checkShaderErrors ) { + + 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' ); + const fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' ); + + console.error( + 'THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' + + 'VALIDATE_STATUS ' + gl.getProgramParameter( program, gl.VALIDATE_STATUS ) + '\n\n' + + 'Program Info Log: ' + programLog + '\n' + + vertexErrors + '\n' + + fragmentErrors + ); + + } else if ( programLog !== '' ) { + + console.warn( 'THREE.WebGLProgram: Program Info Log:', programLog ); + + } else if ( vertexLog === '' || fragmentLog === '' ) { + + haveDiagnostics = false; + + } + + if ( haveDiagnostics ) { + + this.diagnostics = { + + runnable: runnable, + + programLog: programLog, + + vertexShader: { + + log: vertexLog, + prefix: prefixVertex + + }, + + fragmentShader: { + + log: fragmentLog, + prefix: prefixFragment + + } + + }; + + } + + } + + // Clean up + + // Crashes in iOS9 and iOS10. #18402 + // gl.detachShader( program, glVertexShader ); + // gl.detachShader( program, glFragmentShader ); + + gl.deleteShader( glVertexShader ); + gl.deleteShader( glFragmentShader ); + + // 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 + + let cachedAttributes; + + this.getAttributes = function () { + + if ( cachedAttributes === undefined ) { + + cachedAttributes = fetchAttributeLocations( gl, program ); + + } + + return cachedAttributes; + + }; + + // free resource + + this.destroy = function () { + + bindingStates.releaseStatesOfProgram( this ); + + gl.deleteProgram( program ); + this.program = undefined; + + }; + + // + + this.name = parameters.shaderName; + this.id = programIdCount ++; + this.cacheKey = cacheKey; + this.usedTimes = 1; + this.program = program; + this.vertexShader = glVertexShader; + this.fragmentShader = glFragmentShader; + + return this; + + } + + 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; + let set = cache.get( material ); + + if ( set === undefined ) { + + set = new Set(); + cache.set( material, set ); + + } + + return set; + + } + + _getShaderStage( code ) { + + const cache = this.shaderCache; + let stage = cache.get( code ); + + if ( stage === undefined ) { + + stage = new WebGLShaderStage( code ); + cache.set( code, stage ); + + } + + 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; + const vertexTextures = capabilities.vertexTextures; + let precision = capabilities.precision; + + const shaderIDs = { + MeshDepthMaterial: 'depth', + MeshDistanceMaterial: 'distanceRGBA', + MeshNormalMaterial: 'normal', + MeshBasicMaterial: 'basic', + MeshLambertMaterial: 'lambert', + MeshPhongMaterial: 'phong', + MeshToonMaterial: 'toon', + MeshStandardMaterial: 'physical', + MeshPhysicalMaterial: 'physical', + MeshMatcapMaterial: 'matcap', + LineBasicMaterial: 'basic', + LineDashedMaterial: 'dashed', + PointsMaterial: 'points', + ShadowMaterial: 'shadow', + SpriteMaterial: 'sprite' + }; + + 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 + // (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; + + // + + let vertexShader, fragmentShader; + let customVertexShaderID, customFragmentShaderID; + + if ( shaderID ) { + + const shader = ShaderLib[ shaderID ]; + + vertexShader = shader.vertexShader; + fragmentShader = shader.fragmentShader; + + } 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; + const useIridescence = material.iridescence > 0; + + const parameters = { + + isWebGL2: isWebGL2, + + shaderID: shaderID, + shaderName: material.type, + + vertexShader: vertexShader, + fragmentShader: fragmentShader, + defines: material.defines, + + customVertexShaderID: customVertexShaderID, + customFragmentShaderID: customFragmentShaderID, + + isRawShaderMaterial: material.isRawShaderMaterial === true, + glslVersion: material.glslVersion, + + precision: precision, + + instancing: object.isInstancedMesh === true, + instancingColor: object.isInstancedMesh === true && object.instanceColor !== null, + + supportsVertexTextures: vertexTextures, + outputEncoding: ( currentRenderTarget === null ) ? renderer.outputEncoding : ( currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.encoding : LinearEncoding ), + map: !! material.map, + matcap: !! material.matcap, + envMap: !! envMap, + envMapMode: envMap && envMap.mapping, + envMapCubeUVHeight: envMapCubeUVHeight, + lightMap: !! material.lightMap, + aoMap: !! material.aoMap, + emissiveMap: !! material.emissiveMap, + bumpMap: !! material.bumpMap, + normalMap: !! material.normalMap, + objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap, + tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap, + + decodeVideoTexture: !! material.map && ( material.map.isVideoTexture === true ) && ( material.map.encoding === sRGBEncoding ), + + clearcoat: useClearcoat, + clearcoatMap: useClearcoat && !! material.clearcoatMap, + clearcoatRoughnessMap: useClearcoat && !! material.clearcoatRoughnessMap, + clearcoatNormalMap: useClearcoat && !! material.clearcoatNormalMap, + + iridescence: useIridescence, + iridescenceMap: useIridescence && !! material.iridescenceMap, + iridescenceThicknessMap: useIridescence && !! material.iridescenceThicknessMap, + + displacementMap: !! material.displacementMap, + roughnessMap: !! material.roughnessMap, + metalnessMap: !! material.metalnessMap, + specularMap: !! material.specularMap, + specularIntensityMap: !! material.specularIntensityMap, + specularColorMap: !! material.specularColorMap, + + opaque: material.transparent === false && material.blending === NormalBlending, + + alphaMap: !! material.alphaMap, + alphaTest: useAlphaTest, + + gradientMap: !! material.gradientMap, + + sheen: material.sheen > 0, + sheenColorMap: !! material.sheenColorMap, + sheenRoughnessMap: !! material.sheenRoughnessMap, + + transmission: material.transmission > 0, + transmissionMap: !! material.transmissionMap, + thicknessMap: !! material.thicknessMap, + + combine: material.combine, + + vertexTangents: ( !! material.normalMap && !! geometry.attributes.tangent ), + vertexColors: material.vertexColors, + vertexAlphas: material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4, + vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatMap || !! material.clearcoatRoughnessMap || !! material.clearcoatNormalMap || !! material.iridescenceMap || !! material.iridescenceThicknessMap || !! material.displacementMap || !! material.transmissionMap || !! material.thicknessMap || !! material.specularIntensityMap || !! material.specularColorMap || !! material.sheenColorMap || !! material.sheenRoughnessMap, + uvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap || !! material.iridescenceMap || !! material.iridescenceThicknessMap || material.transmission > 0 || !! material.transmissionMap || !! material.thicknessMap || !! material.specularIntensityMap || !! material.specularColorMap || material.sheen > 0 || !! material.sheenColorMap || !! material.sheenRoughnessMap ) && !! material.displacementMap, + + fog: !! fog, + useFog: material.fog === true, + fogExp2: ( fog && fog.isFogExp2 ), + + flatShading: !! material.flatShading, + + sizeAttenuation: material.sizeAttenuation, + logarithmicDepthBuffer: logarithmicDepthBuffer, + + skinning: object.isSkinnedMesh === true, + + morphTargets: geometry.morphAttributes.position !== undefined, + morphNormals: geometry.morphAttributes.normal !== undefined, + morphColors: geometry.morphAttributes.color !== undefined, + morphTargetsCount: morphTargetsCount, + morphTextureStride: morphTextureStride, + + 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, + + shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0, + shadowMapType: renderer.shadowMap.type, + + toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping, + physicallyCorrectLights: renderer.physicallyCorrectLights, + + premultipliedAlpha: material.premultipliedAlpha, + + doubleSided: material.side === DoubleSide, + flipSided: material.side === BackSide, + + useDepthPacking: !! material.depthPacking, + depthPacking: material.depthPacking || 0, + + index0AttributeName: material.index0AttributeName, + + extensionDerivatives: material.extensions && material.extensions.derivatives, + extensionFragDepth: material.extensions && material.extensions.fragDepth, + extensionDrawBuffers: material.extensions && material.extensions.drawBuffers, + extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD, + + rendererExtensionFragDepth: isWebGL2 || extensions.has( 'EXT_frag_depth' ), + rendererExtensionDrawBuffers: isWebGL2 || extensions.has( 'WEBGL_draw_buffers' ), + rendererExtensionShaderTextureLod: isWebGL2 || extensions.has( 'EXT_shader_texture_lod' ), + + customProgramCacheKey: material.customProgramCacheKey() + + }; + + return parameters; + + } + + 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 ); + array.push( parameters.envMapMode ); + array.push( parameters.envMapCubeUVHeight ); + array.push( parameters.combine ); + array.push( parameters.vertexUvs ); + array.push( parameters.fogExp2 ); + array.push( parameters.sizeAttenuation ); + array.push( parameters.morphTargetsCount ); + array.push( parameters.morphAttributeCount ); + 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 ); + if ( parameters.instancingColor ) + _programLayers.enable( 3 ); + if ( parameters.map ) + _programLayers.enable( 4 ); + if ( parameters.matcap ) + _programLayers.enable( 5 ); + if ( parameters.envMap ) + _programLayers.enable( 6 ); + if ( parameters.lightMap ) + _programLayers.enable( 7 ); + if ( parameters.aoMap ) + _programLayers.enable( 8 ); + if ( parameters.emissiveMap ) + _programLayers.enable( 9 ); + if ( parameters.bumpMap ) + _programLayers.enable( 10 ); + if ( parameters.normalMap ) + _programLayers.enable( 11 ); + if ( parameters.objectSpaceNormalMap ) + _programLayers.enable( 12 ); + if ( parameters.tangentSpaceNormalMap ) + _programLayers.enable( 13 ); + if ( parameters.clearcoat ) + _programLayers.enable( 14 ); + if ( parameters.clearcoatMap ) + _programLayers.enable( 15 ); + if ( parameters.clearcoatRoughnessMap ) + _programLayers.enable( 16 ); + if ( parameters.clearcoatNormalMap ) + _programLayers.enable( 17 ); + if ( parameters.iridescence ) + _programLayers.enable( 18 ); + if ( parameters.iridescenceMap ) + _programLayers.enable( 19 ); + if ( parameters.iridescenceThicknessMap ) + _programLayers.enable( 20 ); + if ( parameters.displacementMap ) + _programLayers.enable( 21 ); + if ( parameters.specularMap ) + _programLayers.enable( 22 ); + if ( parameters.roughnessMap ) + _programLayers.enable( 23 ); + if ( parameters.metalnessMap ) + _programLayers.enable( 24 ); + if ( parameters.gradientMap ) + _programLayers.enable( 25 ); + if ( parameters.alphaMap ) + _programLayers.enable( 26 ); + if ( parameters.alphaTest ) + _programLayers.enable( 27 ); + if ( parameters.vertexColors ) + _programLayers.enable( 28 ); + if ( parameters.vertexAlphas ) + _programLayers.enable( 29 ); + if ( parameters.vertexUvs ) + _programLayers.enable( 30 ); + if ( parameters.vertexTangents ) + _programLayers.enable( 31 ); + if ( parameters.uvsVertexOnly ) + _programLayers.enable( 32 ); + + array.push( _programLayers.mask ); + _programLayers.disableAll(); + + 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 + 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 + program.destroy(); + + } + + } + + function releaseShaderCache( material ) { + + _customShaders.remove( material ); + + } + + function dispose() { + + _customShaders.dispose(); + + } + + return { + getParameters: getParameters, + getProgramCacheKey: getProgramCacheKey, + getUniforms: getUniforms, + acquireProgram: acquireProgram, + releaseProgram: releaseProgram, + releaseShaderCache: releaseShaderCache, + // Exposed for resource monitoring & error feedback via renderer.info: + programs: programs, + dispose: dispose + }; + + } + + 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, + update: update, + dispose: dispose + }; + + } + + function painterSortStable( a, b ) { + + if ( a.groupOrder !== b.groupOrder ) { + + return a.groupOrder - b.groupOrder; + + } else if ( a.renderOrder !== b.renderOrder ) { + + return a.renderOrder - b.renderOrder; + + } else if ( a.material.id !== b.material.id ) { + + return a.material.id - b.material.id; + + } else if ( a.z !== b.z ) { + + return a.z - b.z; + + } else { + + return a.id - b.id; + + } + + } + + function reversePainterSortStable( a, b ) { + + if ( a.groupOrder !== b.groupOrder ) { + + return a.groupOrder - b.groupOrder; + + } else if ( a.renderOrder !== b.renderOrder ) { + + return a.renderOrder - b.renderOrder; + + } else if ( a.z !== b.z ) { + + return b.z - a.z; + + } else { + + return a.id - b.id; + + } + + } + + + 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, + object: object, + geometry: geometry, + material: material, + groupOrder: groupOrder, + renderOrder: object.renderOrder, + z: z, + group: group + }; + + renderItems[ renderItemsIndex ] = renderItem; + + } else { + + renderItem.id = object.id; + renderItem.object = object; + renderItem.geometry = geometry; + renderItem.material = material; + renderItem.groupOrder = groupOrder; + renderItem.renderOrder = object.renderOrder; + 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 ) { + + transparent.push( renderItem ); + + } else { + + 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 ) { + + transparent.unshift( renderItem ); + + } else { + + 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; + + renderItem.id = null; + renderItem.object = null; + renderItem.geometry = null; + renderItem.material = null; + renderItem.group = null; + + } + + } + + return { + + opaque: opaque, + transmissive: transmissive, + transparent: transparent, + + init: init, + push: push, + unshift: unshift, + finish: finish, + + sort: sort + }; + + } + + function WebGLRenderLists() { + + let lists = new WeakMap(); + + function get( scene, renderCallDepth ) { + + const listArray = lists.get( scene ); + let list; + + if ( listArray === undefined ) { + + list = new WebGLRenderList(); + lists.set( scene, [ list ] ); + + } else { + + if ( renderCallDepth >= listArray.length ) { + + list = new WebGLRenderList(); + listArray.push( list ); + + } else { + + list = listArray[ renderCallDepth ]; + + } + + } + + return list; + + } + + function dispose() { + + lists = new WeakMap(); + + } + + return { + get: get, + dispose: dispose + }; + + } + + function UniformsCache() { + + const lights = {}; + + return { + + get: function ( light ) { + + if ( lights[ light.id ] !== undefined ) { + + return lights[ light.id ]; + + } + + let uniforms; + + switch ( light.type ) { + + case 'DirectionalLight': + uniforms = { + direction: new Vector3(), + color: new Color() + }; + break; + + case 'SpotLight': + uniforms = { + position: new Vector3(), + direction: new Vector3(), + color: new Color(), + distance: 0, + coneCos: 0, + penumbraCos: 0, + decay: 0 + }; + break; + + case 'PointLight': + uniforms = { + position: new Vector3(), + color: new Color(), + distance: 0, + decay: 0 + }; + break; + + case 'HemisphereLight': + uniforms = { + direction: new Vector3(), + skyColor: new Color(), + groundColor: new Color() + }; + break; + + case 'RectAreaLight': + uniforms = { + color: new Color(), + position: new Vector3(), + halfWidth: new Vector3(), + halfHeight: new Vector3() + }; + break; + + } + + lights[ light.id ] = uniforms; + + return uniforms; + + } + + }; + + } + + function ShadowUniformsCache() { + + const lights = {}; + + return { + + get: function ( light ) { + + if ( lights[ light.id ] !== undefined ) { + + return lights[ light.id ]; + + } + + let uniforms; + + switch ( light.type ) { + + case 'DirectionalLight': + uniforms = { + shadowBias: 0, + shadowNormalBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2() + }; + break; + + case 'SpotLight': + uniforms = { + shadowBias: 0, + shadowNormalBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2() + }; + break; + + case 'PointLight': + uniforms = { + shadowBias: 0, + shadowNormalBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2(), + shadowCameraNear: 1, + shadowCameraFar: 1000 + }; + break; + + // TODO (abelnation): set RectAreaLight shadow uniforms + + } + + lights[ light.id ] = uniforms; + + return uniforms; + + } + + }; + + } + + + + let nextVersion = 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(); + + const state = { + + 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 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; + + for ( let i = 0; i < 9; i ++ ) state.probe[ i ].set( 0, 0, 0 ); + + let directionalLength = 0; + let pointLength = 0; + let spotLength = 0; + let rectAreaLength = 0; + let hemiLength = 0; + + let numDirectionalShadows = 0; + let numPointShadows = 0; + let numSpotShadows = 0; + let numSpotMaps = 0; + let numSpotShadowsWithMaps = 0; + + // 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; + b += color.b * intensity * scaleFactor; + + } else if ( light.isLightProbe ) { + + for ( let j = 0; j < 9; j ++ ) { + + state.probe[ j ].addScaledVector( light.sh.coefficients[ j ], intensity ); + + } + + } 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 ); + + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowNormalBias = shadow.normalBias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; + + state.directionalShadow[ directionalLength ] = shadowUniforms; + state.directionalShadowMap[ directionalLength ] = shadowMap; + state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; + + numDirectionalShadows ++; + + } + + state.directional[ directionalLength ] = uniforms; + + directionalLength ++; + + } else if ( light.isSpotLight ) { + + const uniforms = cache.get( light ); + + uniforms.position.setFromMatrixPosition( light.matrixWorld ); + + uniforms.color.copy( color ).multiplyScalar( intensity * scaleFactor ); + uniforms.distance = distance; + + 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 shadowUniforms = shadowCache.get( light ); + + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowNormalBias = shadow.normalBias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; + + state.spotShadow[ spotLength ] = shadowUniforms; + state.spotShadowMap[ spotLength ] = shadowMap; + + numSpotShadows ++; + + } + + spotLength ++; + + } else if ( light.isRectAreaLight ) { + + 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 ); + + state.rectArea[ rectAreaLength ] = uniforms; + + rectAreaLength ++; + + } else if ( light.isPointLight ) { + + const uniforms = cache.get( light ); + + 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 ); + + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowNormalBias = shadow.normalBias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; + shadowUniforms.shadowCameraNear = shadow.camera.near; + shadowUniforms.shadowCameraFar = shadow.camera.far; + + state.pointShadow[ pointLength ] = shadowUniforms; + state.pointShadowMap[ pointLength ] = shadowMap; + state.pointShadowMatrix[ pointLength ] = light.shadow.matrix; + + numPointShadows ++; + + } + + state.point[ pointLength ] = uniforms; + + pointLength ++; + + } else if ( light.isHemisphereLight ) { + + const uniforms = cache.get( light ); + + uniforms.skyColor.copy( light.color ).multiplyScalar( intensity * scaleFactor ); + uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity * scaleFactor ); + + state.hemi[ hemiLength ] = uniforms; + + 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; + + } else if ( extensions.has( 'OES_texture_half_float_linear' ) === true ) { + + state.rectAreaLTC1 = UniformsLib.LTC_HALF_1; + state.rectAreaLTC2 = UniformsLib.LTC_HALF_2; + + } else { + + console.error( 'THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.' ); + + } + + } + + } + + 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 || + hash.numSpotMaps !== numSpotMaps ) { + + state.directional.length = directionalLength; + state.spot.length = spotLength; + state.rectArea.length = rectAreaLength; + state.point.length = pointLength; + state.hemi.length = hemiLength; + + state.directionalShadow.length = numDirectionalShadows; + state.directionalShadowMap.length = numDirectionalShadows; + state.pointShadow.length = numPointShadows; + state.pointShadowMap.length = numPointShadows; + state.spotShadow.length = numSpotShadows; + state.spotShadowMap.length = numSpotShadows; + state.directionalShadowMatrix.length = numDirectionalShadows; + state.pointShadowMatrix.length = numPointShadows; + state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps; + state.spotLightMap.length = numSpotMaps; + state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps; + + 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.version = nextVersion ++; + + } + + } + + function setupView( lights, camera ) { + + let directionalLength = 0; + let pointLength = 0; + let spotLength = 0; + 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 ); + vector3.setFromMatrixPosition( light.target.matrixWorld ); + uniforms.direction.sub( vector3 ); + uniforms.direction.transformDirection( viewMatrix ); + + directionalLength ++; + + } else if ( light.isSpotLight ) { + + const uniforms = state.spot[ spotLength ]; + + uniforms.position.setFromMatrixPosition( light.matrixWorld ); + uniforms.position.applyMatrix4( viewMatrix ); + + uniforms.direction.setFromMatrixPosition( light.matrixWorld ); + vector3.setFromMatrixPosition( light.target.matrixWorld ); + uniforms.direction.sub( vector3 ); + uniforms.direction.transformDirection( viewMatrix ); + + spotLength ++; + + } 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 + matrix42.identity(); + matrix4.copy( light.matrixWorld ); + matrix4.premultiply( viewMatrix ); + matrix42.extractRotation( matrix4 ); + + uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 ); + uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 ); + + uniforms.halfWidth.applyMatrix4( matrix42 ); + uniforms.halfHeight.applyMatrix4( matrix42 ); + + rectAreaLength ++; + + } else if ( light.isPointLight ) { + + const uniforms = state.point[ pointLength ]; + + uniforms.position.setFromMatrixPosition( light.matrixWorld ); + uniforms.position.applyMatrix4( viewMatrix ); + + pointLength ++; + + } else if ( light.isHemisphereLight ) { + + const uniforms = state.hemi[ hemiLength ]; + + uniforms.direction.setFromMatrixPosition( light.matrixWorld ); + uniforms.direction.transformDirection( viewMatrix ); + + hemiLength ++; + + } + + } + + } + + return { + setup: setup, + setupView: setupView, + state: state + }; + + } + + 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, + + lights: lights + }; + + return { + init: init, + state: state, + setupLights: setupLights, + setupLightsView: setupLightsView, + + pushLight: pushLight, + pushShadow: pushShadow + }; + + } + + function WebGLRenderStates( extensions, capabilities ) { + + let renderStates = new WeakMap(); + + function get( scene, renderCallDepth = 0 ) { + + const renderStateArray = renderStates.get( scene ); + let renderState; + + if ( renderStateArray === undefined ) { + + renderState = new WebGLRenderState( extensions, capabilities ); + renderStates.set( scene, [ renderState ] ); + + } else { + + if ( renderCallDepth >= renderStateArray.length ) { + + renderState = new WebGLRenderState( extensions, capabilities ); + renderStateArray.push( renderState ); + + } else { + + renderState = renderStateArray[ renderCallDepth ]; + + } + + } + + return renderState; + + } + + function dispose() { + + renderStates = new WeakMap(); + + } + + return { + get: get, + dispose: dispose + }; + + } + + class MeshDepthMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshDepthMaterial = true; + + this.type = 'MeshDepthMaterial'; + + this.depthPacking = BasicDepthPacking; + + this.map = null; + + this.alphaMap = null; + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.wireframe = false; + this.wireframeLinewidth = 1; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.depthPacking = source.depthPacking; + + this.map = source.map; + + this.alphaMap = source.alphaMap; + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + + return this; + + } + + } + + class MeshDistanceMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshDistanceMaterial = true; + + this.type = 'MeshDistanceMaterial'; + + this.referencePosition = new Vector3(); + this.nearDistance = 1; + this.farDistance = 1000; + + this.map = null; + + this.alphaMap = null; + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.referencePosition.copy( source.referencePosition ); + this.nearDistance = source.nearDistance; + this.farDistance = source.farDistance; + + this.map = source.map; + + this.alphaMap = source.alphaMap; + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + return this; + + } + + } + + const vertex = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; + + const fragment = "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}"; + + 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; + + const shadowSide = { [ FrontSide ]: BackSide, [ BackSide ]: FrontSide, [ DoubleSide ]: DoubleSide }; + + const shadowMaterialVertical = new ShaderMaterial( { + defines: { + VSM_SAMPLES: 8 + }, + uniforms: { + shadow_pass: { value: null }, + resolution: { value: new Vector2() }, + radius: { value: 4.0 } + }, + + vertexShader: vertex, + fragmentShader: fragment + + } ); + + const shadowMaterialHorizontal = shadowMaterialVertical.clone(); + shadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1; + + const fullScreenTri = new BufferGeometry(); + fullScreenTri.setAttribute( + 'position', + new BufferAttribute( + new Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ), + 3 + ) + ); + + const fullScreenMesh = new Mesh( fullScreenTri, shadowMaterialVertical ); + + const scope = this; + + this.enabled = false; + + 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; + + // 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 ); + + // 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, magFilter: NearestFilter } : {}; + + shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); + 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 + + 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 + + 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 ); + + // 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 ) || + ( 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; + + 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; + + result.displacementMap = material.displacementMap; + result.displacementScale = material.displacementScale; + 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 ); + + } + + } + + } + + function WebGLState( gl, extensions, capabilities ) { + + const isWebGL2 = capabilities.isWebGL2; + + function ColorBuffer() { + + let locked = false; + + const color = new Vector4(); + let currentColorMask = null; + const currentColorClear = new Vector4( 0, 0, 0, 0 ); + + return { + + setMask: function ( colorMask ) { + + if ( currentColorMask !== colorMask && ! locked ) { + + gl.colorMask( colorMask, colorMask, colorMask, colorMask ); + currentColorMask = colorMask; + + } + + }, + + setLocked: function ( lock ) { + + locked = lock; + + }, + + setClear: function ( r, g, b, a, premultipliedAlpha ) { + + if ( premultipliedAlpha === true ) { + + r *= a; g *= a; b *= a; + + } + + color.set( r, g, b, a ); + + if ( currentColorClear.equals( color ) === false ) { + + gl.clearColor( r, g, b, a ); + currentColorClear.copy( color ); + + } + + }, + + reset: function () { + + locked = false; + + currentColorMask = null; + currentColorClear.set( - 1, 0, 0, 0 ); // set to invalid state + + } + + }; + + } + + function DepthBuffer() { + + let locked = false; + + let currentDepthMask = null; + let currentDepthFunc = null; + let currentDepthClear = null; + + return { + + setTest: function ( depthTest ) { + + if ( depthTest ) { + + enable( gl.DEPTH_TEST ); + + } else { + + disable( gl.DEPTH_TEST ); + + } + + }, + + setMask: function ( depthMask ) { + + if ( currentDepthMask !== depthMask && ! locked ) { + + gl.depthMask( depthMask ); + currentDepthMask = depthMask; + + } + + }, + + setFunc: function ( depthFunc ) { + + if ( currentDepthFunc !== 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 ); + + } + + currentDepthFunc = depthFunc; + + } + + }, + + setLocked: function ( lock ) { + + locked = lock; + + }, + + setClear: function ( depth ) { + + if ( currentDepthClear !== depth ) { + + gl.clearDepth( depth ); + currentDepthClear = depth; + + } + + }, + + reset: function () { + + locked = false; + + currentDepthMask = null; + currentDepthFunc = null; + currentDepthClear = null; + + } + + }; + + } + + function StencilBuffer() { + + let locked = false; + + let currentStencilMask = null; + let currentStencilFunc = null; + let currentStencilRef = null; + let currentStencilFuncMask = null; + let currentStencilFail = null; + let currentStencilZFail = null; + let currentStencilZPass = null; + let currentStencilClear = null; + + return { + + setTest: function ( stencilTest ) { + + if ( ! locked ) { + + if ( stencilTest ) { + + enable( gl.STENCIL_TEST ); + + } else { + + disable( gl.STENCIL_TEST ); + + } + + } + + }, + + setMask: function ( stencilMask ) { + + if ( currentStencilMask !== stencilMask && ! locked ) { + + gl.stencilMask( stencilMask ); + currentStencilMask = stencilMask; + + } + + }, + + setFunc: function ( stencilFunc, stencilRef, stencilMask ) { + + if ( currentStencilFunc !== stencilFunc || + currentStencilRef !== stencilRef || + currentStencilFuncMask !== stencilMask ) { + + gl.stencilFunc( stencilFunc, stencilRef, stencilMask ); + + currentStencilFunc = stencilFunc; + currentStencilRef = stencilRef; + currentStencilFuncMask = stencilMask; + + } + + }, + + setOp: function ( stencilFail, stencilZFail, stencilZPass ) { + + if ( currentStencilFail !== stencilFail || + currentStencilZFail !== stencilZFail || + currentStencilZPass !== stencilZPass ) { + + gl.stencilOp( stencilFail, stencilZFail, stencilZPass ); + + currentStencilFail = stencilFail; + currentStencilZFail = stencilZFail; + currentStencilZPass = stencilZPass; + + } + + }, + + setLocked: function ( lock ) { + + locked = lock; + + }, + + setClear: function ( stencil ) { + + if ( currentStencilClear !== stencil ) { + + gl.clearStencil( stencil ); + currentStencilClear = stencil; + + } + + }, + + reset: function () { + + locked = false; + + currentStencilMask = null; + currentStencilFunc = null; + currentStencilRef = null; + currentStencilFuncMask = null; + currentStencilFail = null; + currentStencilZFail = null; + currentStencilZPass = null; + currentStencilClear = null; + + } + + }; + + } + + // + + const colorBuffer = new ColorBuffer(); + const depthBuffer = new DepthBuffer(); + const stencilBuffer = new StencilBuffer(); + + const uboBindings = new WeakMap(); + const uboProgramMap = new WeakMap(); + + let enabledCapabilities = {}; + + let currentBoundFramebuffers = {}; + let currentDrawbuffers = new WeakMap(); + let defaultDrawbuffers = []; + + let currentProgram = null; + + let currentBlendingEnabled = false; + let currentBlending = null; + let currentBlendEquation = null; + let currentBlendSrc = null; + let currentBlendDst = null; + let currentBlendEquationAlpha = null; + let currentBlendSrcAlpha = null; + let currentBlendDstAlpha = null; + let currentPremultipledAlpha = false; + + let currentFlipSided = null; + let currentCullFace = null; + + let currentLineWidth = null; + + let currentPolygonOffsetFactor = null; + let currentPolygonOffsetUnits = null; + + const maxTextures = gl.getParameter( gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS ); + + 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 ); + + } else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) { + + 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 + + colorBuffer.setClear( 0, 0, 0, 1 ); + depthBuffer.setClear( 1 ); + stencilBuffer.setClear( 0 ); + + enable( gl.DEPTH_TEST ); + depthBuffer.setFunc( LessEqualDepth ); + + setFlipSided( false ); + setCullFace( CullFaceBack ); + enable( gl.CULL_FACE ); + + setBlending( NoBlending ); + + // + + function enable( id ) { + + if ( enabledCapabilities[ id ] !== true ) { + + gl.enable( id ); + enabledCapabilities[ id ] = true; + + } + + } + + function disable( id ) { + + if ( enabledCapabilities[ id ] !== false ) { + + gl.disable( id ); + enabledCapabilities[ id ] = false; + + } + + } + + function 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; + + } + + } else { + + if ( drawBuffers[ 0 ] !== gl.COLOR_ATTACHMENT0 ) { + + drawBuffers[ 0 ] = gl.COLOR_ATTACHMENT0; + + needsUpdate = true; + + } + + } + + } else { + + if ( drawBuffers[ 0 ] !== gl.BACK ) { + + drawBuffers[ 0 ] = gl.BACK; + + needsUpdate = true; + + } + + } + + if ( needsUpdate ) { + + if ( capabilities.isWebGL2 ) { + + gl.drawBuffers( drawBuffers ); + + } else { + + extensions.get( 'WEBGL_draw_buffers' ).drawBuffersWEBGL( drawBuffers ); + + } + + } + + + } + + 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, + [ SrcColorFactor ]: gl.SRC_COLOR, + [ SrcAlphaFactor ]: gl.SRC_ALPHA, + [ SrcAlphaSaturateFactor ]: gl.SRC_ALPHA_SATURATE, + [ DstColorFactor ]: gl.DST_COLOR, + [ DstAlphaFactor ]: gl.DST_ALPHA, + [ OneMinusSrcColorFactor ]: gl.ONE_MINUS_SRC_COLOR, + [ OneMinusSrcAlphaFactor ]: gl.ONE_MINUS_SRC_ALPHA, + [ 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 ) { + + gl.blendEquation( gl.FUNC_ADD ); + + 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; + + } + + } else { + + switch ( blending ) { + + 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; + currentBlendDstAlpha = null; + + currentBlending = blending; + currentPremultipledAlpha = premultipliedAlpha; + + } + + return; + + } + + // 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; + currentBlendDst = blendDst; + currentBlendSrcAlpha = blendSrcAlpha; + currentBlendDstAlpha = blendDstAlpha; + + } + + currentBlending = blending; + currentPremultipledAlpha = false; + + } + + function setMaterial( material, frontFaceCW ) { + + material.side === DoubleSide + ? disable( gl.CULL_FACE ) + : enable( gl.CULL_FACE ); + + let flipSided = ( material.side === BackSide ); + if ( frontFaceCW ) flipSided = ! flipSided; + + setFlipSided( flipSided ); + + ( material.blending === NormalBlending && material.transparent === false ) + ? setBlending( NoBlending ) + : setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha ); + + depthBuffer.setFunc( material.depthFunc ); + depthBuffer.setTest( material.depthTest ); + depthBuffer.setMask( material.depthWrite ); + colorBuffer.setMask( material.colorWrite ); + + 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 ) { + + if ( flipSided ) { + + gl.frontFace( gl.CW ); + + } 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 ); + + } else if ( cullFace === CullFaceFront ) { + + gl.cullFace( gl.FRONT ); + + } else { + + gl.cullFace( gl.FRONT_AND_BACK ); + + } + + } + + } 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; + currentPolygonOffsetUnits = units; + + } + + } else { + + disable( gl.POLYGON_OFFSET_FILL ); + + } + + } + + function setScissorTest( scissorTest ) { + + if ( scissorTest ) { + + enable( gl.SCISSOR_TEST ); + + } else { + + disable( gl.SCISSOR_TEST ); + + } + + } + + // texture + + function activeTexture( webglSlot ) { + + if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1; + + if ( currentTextureSlot !== webglSlot ) { + + gl.activeTexture( webglSlot ); + currentTextureSlot = webglSlot; + + } + + } + + function bindTexture( webglType, webglTexture, webglSlot ) { + + if ( webglSlot === undefined ) { + + if ( currentTextureSlot === null ) { + + webglSlot = gl.TEXTURE0 + maxTextures - 1; + + } else { + + webglSlot = currentTextureSlot; + + } + + } + + let boundTexture = currentBoundTextures[ webglSlot ]; + + if ( boundTexture === undefined ) { + + boundTexture = { type: undefined, texture: undefined }; + 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 ); + + } catch ( error ) { + + 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 ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } + + } + + function texSubImage3D() { + + try { + + gl.texSubImage3D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } + + } + + function compressedTexSubImage2D() { + + try { + + gl.compressedTexSubImage2D.apply( gl, arguments ); + + } catch ( error ) { + + 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 ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } + + } + + function texStorage3D() { + + try { + + gl.texStorage3D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } + + } + + function texImage2D() { + + try { + + gl.texImage2D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } + + } + + function texImage3D() { + + try { + + gl.texImage3D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } + + } + + // + + function scissor( scissor ) { + + if ( currentScissor.equals( scissor ) === false ) { + + gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w ); + 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 = uboProgramMap.get( program ); + + if ( mapping === undefined ) { + + mapping = new WeakMap(); + + uboProgramMap.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 = uboProgramMap.get( program ); + const blockIndex = mapping.get( uniformsGroup ); + + if ( uboBindings.get( program ) !== blockIndex ) { + + // bind shader specific block index to global block point + gl.uniformBlockBinding( program, blockIndex, uniformsGroup.__bindingPointIndex ); + + uboBindings.set( program, blockIndex ); + + } + + } + + // + + function reset() { + + // reset state + + gl.disable( gl.BLEND ); + gl.disable( gl.CULL_FACE ); + gl.disable( gl.DEPTH_TEST ); + gl.disable( gl.POLYGON_OFFSET_FILL ); + gl.disable( gl.SCISSOR_TEST ); + gl.disable( gl.STENCIL_TEST ); + gl.disable( gl.SAMPLE_ALPHA_TO_COVERAGE ); + + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.ONE, gl.ZERO ); + gl.blendFuncSeparate( gl.ONE, gl.ZERO, gl.ONE, gl.ZERO ); + + gl.colorMask( true, true, true, true ); + gl.clearColor( 0, 0, 0, 0 ); + + gl.depthMask( true ); + gl.depthFunc( gl.LESS ); + gl.clearDepth( 1 ); + + gl.stencilMask( 0xffffffff ); + gl.stencilFunc( gl.ALWAYS, 0, 0xffffffff ); + gl.stencilOp( gl.KEEP, gl.KEEP, gl.KEEP ); + gl.clearStencil( 0 ); + + gl.cullFace( gl.BACK ); + gl.frontFace( gl.CCW ); + + 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 + + enabledCapabilities = {}; + + currentTextureSlot = null; + currentBoundTextures = {}; + + currentBoundFramebuffers = {}; + currentDrawbuffers = new WeakMap(); + defaultDrawbuffers = []; + + currentProgram = null; + + currentBlendingEnabled = false; + currentBlending = null; + currentBlendEquation = null; + currentBlendSrc = null; + currentBlendDst = null; + currentBlendEquationAlpha = null; + currentBlendSrcAlpha = null; + currentBlendDstAlpha = null; + currentPremultipledAlpha = false; + + currentFlipSided = null; + currentCullFace = null; + + currentLineWidth = null; + + currentPolygonOffsetFactor = null; + currentPolygonOffsetUnits = null; + + currentScissor.set( 0, 0, gl.canvas.width, gl.canvas.height ); + currentViewport.set( 0, 0, gl.canvas.width, gl.canvas.height ); + + colorBuffer.reset(); + depthBuffer.reset(); + stencilBuffer.reset(); + + } + + return { + + buffers: { + color: colorBuffer, + depth: depthBuffer, + stencil: stencilBuffer + }, + + enable: enable, + disable: disable, + + bindFramebuffer: bindFramebuffer, + drawBuffers: drawBuffers, + + useProgram: useProgram, + + setBlending: setBlending, + setMaterial: setMaterial, + + setFlipSided: setFlipSided, + setCullFace: setCullFace, + + setLineWidth: setLineWidth, + setPolygonOffset: setPolygonOffset, + + setScissorTest: setScissorTest, + + activeTexture: activeTexture, + bindTexture: bindTexture, + unbindTexture: unbindTexture, + compressedTexImage2D: compressedTexImage2D, + compressedTexImage3D: compressedTexImage3D, + texImage2D: texImage2D, + texImage3D: texImage3D, + + updateUBOMapping: updateUBOMapping, + uniformBlockBinding: uniformBlockBinding, + + texStorage2D: texStorage2D, + texStorage3D: texStorage3D, + texSubImage2D: texSubImage2D, + texSubImage3D: texSubImage3D, + compressedTexSubImage2D: compressedTexSubImage2D, + compressedTexSubImage3D: compressedTexSubImage3D, + + scissor: scissor, + viewport: viewport, + + reset: reset + + }; + + } + + function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) { + + const isWebGL2 = capabilities.isWebGL2; + const maxTextures = capabilities.maxTextures; + const maxCubemapSize = capabilities.maxCubemapSize; + 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 = 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 + && ( new OffscreenCanvas( 1, 1 ).getContext( '2d' ) ) !== null; + + } 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 + new OffscreenCanvas( width, height ) : createElementNS( 'canvas' ); + + } + + function resizeImage( image, needsPowerOfTwo, needsNewCanvas, maxSize ) { + + 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 + + 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 + + const canvas = needsNewCanvas ? createCanvas( width, height ) : _canvas; + + canvas.width = width; + canvas.height = height; + + const context = canvas.getContext( '2d' ); + context.drawImage( image, 0, 0, width, height ); + + console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' ); + + return canvas; + + } else { + + if ( '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, 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 && 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 + + 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 + + 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 + + if ( webglTexture.usedTimes === 0 ) { + + deleteTexture( texture ); + + } + + // 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 ); + array.push( texture.internalFormat ); + array.push( texture.format ); + array.push( texture.type ); + array.push( texture.generateMipmaps ); + array.push( texture.premultiplyAlpha ); + array.push( texture.flipY ); + 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 ) { + + console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete' ); + + } else { + + uploadTexture( textureProperties, texture, slot ); + return; + + } + + } + + 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.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.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.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot ); + + } + + const wrappingToGL = { + [ RepeatWrapping ]: _gl.REPEAT, + [ ClampToEdgeWrapping ]: _gl.CLAMP_TO_EDGE, + [ MirroredRepeatWrapping ]: _gl.MIRRORED_REPEAT + }; + + const filterToGL = { + [ NearestFilter ]: _gl.NEAREST, + [ NearestMipmapNearestFilter ]: _gl.NEAREST_MIPMAP_NEAREST, + [ NearestMipmapLinearFilter ]: _gl.NEAREST_MIPMAP_LINEAR, + + [ LinearFilter ]: _gl.LINEAR, + [ 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.magFilter === NearestFilter ) return; + if ( texture.minFilter !== NearestMipmapLinearFilter && texture.minFilter !== LinearMipmapLinearFilter ) return; + 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 + + 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 + + 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 + // even if the image contents are identical + + forceUpload = true; + + } + + webglTextures[ textureCacheKey ].usedTimes ++; + + // 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 + + textureProperties.__cacheKey = textureCacheKey; + textureProperties.__webglTexture = webglTextures[ textureCacheKey ].texture; + + } + + return forceUpload; + + } + + function uploadTexture( textureProperties, texture, slot ) { + + let textureType = _gl.TEXTURE_2D; + + 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.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 ); + + let glType = utils.convert( texture.type ), + 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 = ( sourceProperties.__version === undefined ) || ( forceUpload === true ); + const levels = getMipLevels( texture, image, supportsMips ); + + if ( texture.isDepthTexture ) { + + // populate depth texture with dummy data + + glInternalFormat = _gl.DEPTH_COMPONENT; + + if ( isWebGL2 ) { + + if ( texture.type === FloatType ) { + + glInternalFormat = _gl.DEPTH_COMPONENT32F; + + } else if ( texture.type === UnsignedIntType ) { + + glInternalFormat = _gl.DEPTH_COMPONENT24; + + } else if ( texture.type === UnsignedInt248Type ) { + + glInternalFormat = _gl.DEPTH24_STENCIL8; + + } else { + + glInternalFormat = _gl.DEPTH_COMPONENT16; // WebGL2 requires sized internalformat for glTexImage2D + + } + + } else { + + if ( texture.type === FloatType ) { + + console.error( 'WebGLRenderer: Floating point depth texture requires WebGL2.' ); + + } + + } + + // validation checks for WebGL 1 + + if ( texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT ) { + + // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are + // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT + // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) + if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) { + + console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' ); + + texture.type = UnsignedIntType; + 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 + // 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 ) { + + state.texStorage2D( _gl.TEXTURE_2D, 1, glInternalFormat, image.width, image.height ); + + } else { + + state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null ); + + } + + } + + } else if ( texture.isDataTexture ) { + + // use manually created mipmaps if available + // if there are no manual mipmaps + // set 0 level mipmap and then use GL to generate other mipmap levels + + if ( mipmaps.length > 0 && supportsMips ) { + + 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 ( 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 { + + console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); + + } + + } else { + + 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 && 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 { + + 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 ); + + } + + } + + } + + } + + } else if ( texture.isDataArrayTexture ) { + + if ( useTexStorage ) { + + 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 ); + + } + + } else if ( texture.isData3DTexture ) { + + if ( useTexStorage ) { + + 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 ); + + } + + } else if ( texture.isFramebufferTexture ) { + + if ( allocateMemory ) { + + if ( useTexStorage ) { + + state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height ); + + } else { + + let width = image.width, 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; + height >>= 1; + + } + + } + + } + + } 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 ); + + } + + 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.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 ); + + const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== 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 ) { + + state.compressedTexSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data ); + + } else { + + state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); + + } + + } else { + + console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' ); + + } + + } else { + + if ( useTexStorage ) { + + state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); + + } else { + + state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); + + } + + } + + } + + } + + } 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 ) { + + state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[ i ].width, cubeImage[ i ].height, glFormat, glType, cubeImage[ i ].data ); + + } 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 { + + state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data ); + + } + + } + + } else { + + if ( useTexStorage ) { + + state.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[ i ] ); + + } 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 { + + state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] ); + + } + + } + + } + + } + + } + + if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { + + // We assume images for cube map have the same size. + generateMipmap( _gl.TEXTURE_CUBE_MAP ); + + } + + 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 + 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 ); + + } else { + + 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 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 + 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; + + } else if ( depthTexture.type === UnsignedIntType ) { + + glInternalFormat = _gl.DEPTH_COMPONENT24; + + } + + } + + const samples = getRenderTargetSamples( renderTarget ); + + if ( useMultisampledRTT( renderTarget ) ) { + + multisampledRTTExt.renderbufferStorageMultisampleEXT( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + + } else { + + _gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + + } + + } 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 ) ) { + + multisampledRTTExt.renderbufferStorageMultisampleEXT( _gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height ); + + } 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 ) ) { + + multisampledRTTExt.renderbufferStorageMultisampleEXT( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + + } else { + + _gl.renderbufferStorage( _gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height ); + + } + + } + + } + + _gl.bindRenderbuffer( _gl.RENDERBUFFER, null ); + + } + + // 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 + 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 ); + + } else { + + _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 ); + + } + + } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) { + + if ( useMultisampledRTT( renderTarget ) ) { + + multisampledRTTExt.framebufferTexture2DMultisampleEXT( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples ); + + } else { + + _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 ); + + } + + } else { + + throw new Error( 'Unknown depthTexture format' ); + + } + + } + + // 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(); + setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget, false ); + + } + + } else { + + state.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer ); + renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget, false ); + + } + + } + + state.bindFramebuffer( _gl.FRAMEBUFFER, null ); + + } + + // 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 + 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 + + 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 ++; + + } + + } + + } else { + + 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, 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 + + 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; + + } else { + + 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 + + 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 ]; + const width = renderTarget.width; + const height = renderTarget.height; + let mask = _gl.COLOR_BUFFER_BIT; + 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 + 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 + 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 + + 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.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.' ); + + } + + } + + } else { + + console.error( 'THREE.WebGLTextures: Unsupported texture encoding:', encoding ); + + } + + } + + return image; + + } + + // + + this.allocateTextureUnit = allocateTextureUnit; + this.resetTextureUnits = resetTextureUnits; + + this.setTexture2D = setTexture2D; + this.setTexture2DArray = setTexture2DArray; + this.setTexture3D = setTexture3D; + this.setTextureCube = setTextureCube; + this.rebindTextures = rebindTextures; + this.setupRenderTarget = setupRenderTarget; + this.updateRenderTargetMipmap = updateRenderTargetMipmap; + this.updateMultisampleRenderTarget = updateMultisampleRenderTarget; + this.setupDepthRenderbuffer = setupDepthRenderbuffer; + this.setupFrameBufferTexture = setupFrameBufferTexture; + this.useMultisampledRTT = useMultisampledRTT; + + } + + function WebGLUtils( gl, extensions, capabilities ) { + + const isWebGL2 = capabilities.isWebGL2; + + function convert( p, encoding = null ) { + + let extension; + + if ( p === UnsignedByteType ) return gl.UNSIGNED_BYTE; + if ( p === UnsignedShort4444Type ) return gl.UNSIGNED_SHORT_4_4_4_4; + if ( p === UnsignedShort5551Type ) return gl.UNSIGNED_SHORT_5_5_5_1; + + if ( p === ByteType ) return gl.BYTE; + if ( p === ShortType ) return gl.SHORT; + if ( p === UnsignedShortType ) return gl.UNSIGNED_SHORT; + 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; + + // 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. + + 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 === 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; + if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + + } else { + + return null; + + } + + } 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; + if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; + if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; + + } else { + + return null; + + } + + } + + } + + // 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; + if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + + } else { + + return null; + + } + + } + + // 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 + + 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 + + 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; + if ( p === RGBA_ASTC_5x5_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR; + if ( p === RGBA_ASTC_6x5_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR; + if ( p === RGBA_ASTC_6x6_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR; + if ( p === RGBA_ASTC_8x5_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR; + if ( p === RGBA_ASTC_8x6_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR; + if ( p === RGBA_ASTC_8x8_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR; + if ( p === RGBA_ASTC_10x5_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR; + if ( p === RGBA_ASTC_10x6_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR; + if ( p === RGBA_ASTC_10x8_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR; + if ( p === RGBA_ASTC_10x10_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR; + if ( p === RGBA_ASTC_12x10_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR; + if ( p === RGBA_ASTC_12x12_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR; + + } else { + + return null; + + } + + } + + // 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; + + } + + } + + // RGTC + + if ( p === RED_RGTC1_Format || p === SIGNED_RED_RGTC1_Format || p === RED_GREEN_RGTC2_Format || p === SIGNED_RED_GREEN_RGTC2_Format ) { + + extension = extensions.get( 'EXT_texture_compression_rgtc' ); + + if ( extension !== null ) { + + if ( p === RGBA_BPTC_Format ) return extension.COMPRESSED_RED_RGTC1_EXT; + if ( p === SIGNED_RED_RGTC1_Format ) return extension.COMPRESSED_SIGNED_RED_RGTC1_EXT; + if ( p === RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_RED_GREEN_RGTC2_EXT; + if ( p === SIGNED_RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_SIGNED_RED_GREEN_RGTC2_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) + + return ( gl[ p ] !== undefined ) ? gl[ p ] : null; + + } + + return { convert: convert }; + + } + + class ArrayCamera extends PerspectiveCamera { + + constructor( array = [] ) { + + super(); + + this.isArrayCamera = true; + + this.cameras = array; + + } + + } + + class Group extends Object3D { + + constructor() { + + super(); + + 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(); + this._hand.matrixAutoUpdate = false; + this._hand.visible = false; + + this._hand.joints = {}; + this._hand.inputState = { pinching: false }; + + } + + return this._hand; + + } + + getTargetRaySpace() { + + if ( this._targetRay === null ) { + + this._targetRay = new Group(); + this._targetRay.matrixAutoUpdate = false; + this._targetRay.visible = false; + this._targetRay.hasLinearVelocity = false; + this._targetRay.linearVelocity = new Vector3(); + this._targetRay.hasAngularVelocity = false; + this._targetRay.angularVelocity = new Vector3(); + + } + + return this._targetRay; + + } + + getGripSpace() { + + if ( this._grip === null ) { + + this._grip = new Group(); + this._grip.matrixAutoUpdate = false; + this._grip.visible = false; + this._grip.hasLinearVelocity = false; + this._grip.linearVelocity = new Vector3(); + 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; + let handPose = null; + + 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 ); + + // 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 + 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( { + type: 'pinchend', + handedness: inputSource.handedness, + target: this + } ); + + } else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) { + + hand.inputState.pinching = true; + this.dispatchEvent( { + type: 'pinchstart', + handedness: inputSource.handedness, + target: this + } ); + + } + + } else { + + if ( 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 ); + + } else { + + grip.hasAngularVelocity = false; + + } + + } + + } + + } + + 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 + 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 ); + + this.isDepthTexture = true; + + this.image = { width: width, height: height }; + + this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; + this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; + + this.flipY = false; + this.generateMipmaps = false; + + } + + + } + + class WebXRManager extends EventDispatcher { + + constructor( renderer, gl ) { + + super(); + + const scope = this; + + let session = null; + let framebufferScaleFactor = 1.0; + + let referenceSpace = null; + let referenceSpaceType = 'local-floor'; + // Set default foveation to maximum. + let foveation = 1.0; + let customReferenceSpace = null; + + let pose = null; + let glBinding = null; + let glProjLayer = null; + let glBaseLayer = null; + let xrFrame = null; + const attributes = gl.getContextAttributes(); + let initialRenderTarget = null; + let newRenderTarget = null; + + const controllers = []; + const controllerInputSources = []; + + const planes = new Set(); + const planesLastChangedTimes = new Map(); + + // + + const cameraL = new PerspectiveCamera(); + cameraL.layers.enable( 1 ); + cameraL.viewport = new Vector4(); + + const cameraR = new PerspectiveCamera(); + cameraR.layers.enable( 2 ); + cameraR.viewport = new Vector4(); + + const cameras = [ cameraL, cameraR ]; + + const cameraVR = new ArrayCamera(); + cameraVR.layers.enable( 1 ); + cameraVR.layers.enable( 2 ); + + let _currentDepthNear = 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, data: event.inputSource } ); + + } + + } + + function onSessionEnd() { + + session.removeEventListener( 'select', onSessionEvent ); + session.removeEventListener( 'selectstart', onSessionEvent ); + session.removeEventListener( 'selectend', onSessionEvent ); + session.removeEventListener( 'squeeze', onSessionEvent ); + session.removeEventListener( 'squeezestart', onSessionEvent ); + 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 + + renderer.setRenderTarget( initialRenderTarget ); + + glBaseLayer = null; + glProjLayer = null; + glBinding = null; + session = null; + newRenderTarget = null; + + // + + animation.stop(); + + scope.isPresenting = false; + + scope.dispatchEvent( { 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 ); + session.addEventListener( 'selectstart', onSessionEvent ); + session.addEventListener( 'selectend', onSessionEvent ); + session.addEventListener( 'squeeze', onSessionEvent ); + session.addEventListener( 'squeezestart', onSessionEvent ); + 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, + alpha: attributes.alpha, + depth: attributes.depth, + stencil: attributes.stencil, + framebufferScaleFactor: framebufferScaleFactor + }; + + glBaseLayer = new XRWebGLLayer( session, gl, layerInit ); + + session.updateRenderState( { baseLayer: glBaseLayer } ); + + newRenderTarget = new WebGLRenderTarget( + glBaseLayer.framebufferWidth, + glBaseLayer.framebufferHeight, + { + format: RGBAFormat, + type: UnsignedByteType, + 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, + scaleFactor: framebufferScaleFactor + }; + + glBinding = new XRWebGLBinding( session, gl ); + + glProjLayer = glBinding.createProjectionLayer( projectionlayerInit ); + + session.updateRenderState( { layers: [ glProjLayer ] } ); + + newRenderTarget = new WebGLRenderTarget( + glProjLayer.textureWidth, + glProjLayer.textureHeight, + { + format: RGBAFormat, + type: UnsignedByteType, + depthTexture: new DepthTexture( glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat ), + stencilBuffer: attributes.stencil, + encoding: renderer.outputEncoding, + samples: attributes.antialias ? 4 : 0 + } ); + + const renderTargetProperties = renderer.properties.get( newRenderTarget ); + renderTargetProperties.__ignoreDepthValues = glProjLayer.ignoreDepthValues; + + } + + newRenderTarget.isXRRenderTarget = true; // TODO Remove this when possible, see #23278 + + this.setFoveation( foveation ); + + customReferenceSpace = null; + referenceSpace = await session.requestReferenceSpace( referenceSpaceType ); + + animation.setContext( session ); + animation.start(); + + scope.isPresenting = true; + + scope.dispatchEvent( { type: 'sessionstart' } ); + + } + + }; + + 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 ].disconnect( inputSource ); + + } + + } + + // 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 ); + controllerIndex = i; + break; + + } else if ( controllerInputSources[ i ] === null ) { + + controllerInputSources[ i ] = inputSource; + controllerIndex = i; + break; + + } + + } + + // If all controllers do currently receive input we ignore new ones + + if ( controllerIndex === - 1 ) break; + + } + + const controller = controllers[ controllerIndex ]; + + if ( controller ) { + + 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 + // 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 ]; + const bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ]; + + 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 zOffset = ipd / ( - leftFov + rightFov ); + 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 + // 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; + const right2 = right + ( ipd - xOffset ); + const top2 = topFov * far / far2 * near2; + 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 + } ); + + _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 ); + + // update user camera and its children + + camera.matrix.copy( cameraVR.matrix ); + 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 + + 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 && glBaseLayer === null ) { + + return undefined; + + } + + return foveation; + + }; + + this.setFoveation = function ( value ) { + + // 0 = no foveation = full resolution + // 1 = maximum foveation = the edges render at lower resolution + + foveation = value; + + if ( glProjLayer !== null ) { + + glProjLayer.fixedFoveation = value; + + } + + if ( glBaseLayer !== null && glBaseLayer.fixedFoveation !== undefined ) { + + glBaseLayer.fixedFoveation = value; + + } + + }; + + 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; + + // 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. + 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 ) { + + fog.color.getRGB( uniforms.fogColor.value, getUnlitUniformColorSpace( renderer ) ); + + if ( fog.isFog ) { + + uniforms.fogNear.value = fog.near; + uniforms.fogFar.value = fog.far; + + } else if ( fog.isFogExp2 ) { + + uniforms.fogDensity.value = fog.density; + + } + + } + + function refreshMaterialUniforms( uniforms, material, pixelRatio, height, transmissionRenderTarget ) { + + if ( material.isMeshBasicMaterial ) { + + refreshUniformsCommon( uniforms, material ); + + } else if ( material.isMeshLambertMaterial ) { + + refreshUniformsCommon( uniforms, material ); + + } else if ( material.isMeshToonMaterial ) { + + refreshUniformsCommon( uniforms, material ); + refreshUniformsToon( uniforms, material ); + + } else if ( material.isMeshPhongMaterial ) { + + refreshUniformsCommon( uniforms, material ); + refreshUniformsPhong( uniforms, material ); + + } else if ( material.isMeshStandardMaterial ) { + + refreshUniformsCommon( uniforms, material ); + refreshUniformsStandard( uniforms, material ); + + if ( material.isMeshPhysicalMaterial ) { + + refreshUniformsPhysical( uniforms, material, transmissionRenderTarget ); + + } + + } else if ( material.isMeshMatcapMaterial ) { + + refreshUniformsCommon( uniforms, material ); + refreshUniformsMatcap( uniforms, material ); + + } else if ( material.isMeshDepthMaterial ) { + + refreshUniformsCommon( uniforms, material ); + + } else if ( material.isMeshDistanceMaterial ) { + + refreshUniformsCommon( uniforms, material ); + refreshUniformsDistance( uniforms, material ); + + } else if ( material.isMeshNormalMaterial ) { + + refreshUniformsCommon( uniforms, material ); + + } else if ( material.isLineBasicMaterial ) { + + refreshUniformsLine( uniforms, material ); + + if ( material.isLineDashedMaterial ) { + + refreshUniformsDash( uniforms, material ); + + } + + } else if ( material.isPointsMaterial ) { + + refreshUniformsPoints( uniforms, material, pixelRatio, height ); + + } else if ( material.isSpriteMaterial ) { + + refreshUniformsSprites( uniforms, material ); + + } else if ( material.isShadowMaterial ) { + + uniforms.color.value.copy( material.color ); + uniforms.opacity.value = material.opacity; + + } else if ( material.isShaderMaterial ) { + + material.uniformsNeedUpdate = false; // #15581 + + } + + } + + 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; + + uniforms.reflectivity.value = material.reflectivity; + uniforms.ior.value = material.ior; + uniforms.refractionRatio.value = material.refractionRatio; + + } + + if ( material.lightMap ) { + + 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 + // 1. color map + // 2. specular map + // 3. displacementMap map + // 4. normal map + // 5. bump map + // 6. roughnessMap map + // 7. metalnessMap map + // 8. alphaMap map + // 9. emissiveMap map + // 10. clearcoat map + // 11. clearcoat normal map + // 12. clearcoat roughnessMap map + // 13. iridescence map + // 14. iridescence thickness map + // 15. specular intensity map + // 16. specular tint map + // 17. transmission map + // 18. thickness map + + let uvScaleMap; + + if ( material.map ) { + + uvScaleMap = material.map; + + } else if ( material.specularMap ) { + + uvScaleMap = material.specularMap; + + } else if ( material.displacementMap ) { + + uvScaleMap = material.displacementMap; + + } else if ( material.normalMap ) { + + uvScaleMap = material.normalMap; + + } else if ( material.bumpMap ) { + + uvScaleMap = material.bumpMap; + + } else if ( material.roughnessMap ) { + + uvScaleMap = material.roughnessMap; + + } else if ( material.metalnessMap ) { + + uvScaleMap = material.metalnessMap; + + } else if ( material.alphaMap ) { + + uvScaleMap = material.alphaMap; + + } else if ( material.emissiveMap ) { + + uvScaleMap = material.emissiveMap; + + } else if ( material.clearcoatMap ) { + + uvScaleMap = material.clearcoatMap; + + } else if ( material.clearcoatNormalMap ) { + + uvScaleMap = material.clearcoatNormalMap; + + } else if ( material.clearcoatRoughnessMap ) { + + uvScaleMap = material.clearcoatRoughnessMap; + + } else if ( material.iridescenceMap ) { + + uvScaleMap = material.iridescenceMap; + + } else if ( material.iridescenceThicknessMap ) { + + uvScaleMap = material.iridescenceThicknessMap; + + } else if ( material.specularIntensityMap ) { + + uvScaleMap = material.specularIntensityMap; + + } else if ( material.specularColorMap ) { + + uvScaleMap = material.specularColorMap; + + } else if ( material.transmissionMap ) { + + uvScaleMap = material.transmissionMap; + + } else if ( material.thicknessMap ) { + + uvScaleMap = material.thicknessMap; + + } else if ( material.sheenColorMap ) { + + uvScaleMap = material.sheenColorMap; + + } 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 + // 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 + // 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 + // 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 ) + + } + + function refreshUniformsToon( uniforms, material ) { + + if ( material.gradientMap ) { + + 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 + }; + + } + + function WebGLUniformsGroups( gl, info, capabilities, state ) { + + let buffers = {}; + let updateList = {}; + let allocatedBindingPoints = []; + + const maxBindingPoints = ( capabilities.isWebGL2 ) ? gl.getParameter( gl.MAX_UNIFORM_BUFFER_BINDINGS ) : 0; // binding points are global whereas block indices are per shader program + + function bind( uniformsGroup, program ) { + + 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 + + const webglProgram = program.program; + state.updateUBOMapping( uniformsGroup, webglProgram ); + + // 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(); + const size = uniformsGroup.__size; + const usage = uniformsGroup.usage; + + gl.bindBuffer( gl.UNIFORM_BUFFER, buffer ); + gl.bufferData( gl.UNIFORM_BUFFER, size, usage ); + gl.bindBuffer( gl.UNIFORM_BUFFER, null ); + gl.bindBufferBase( gl.UNIFORM_BUFFER, bindingPointIndex, buffer ); + + return buffer; + + } + + function allocateBindingPointIndex() { + + for ( let i = 0; i < maxBindingPoints; i ++ ) { + + if ( allocatedBindingPoints.indexOf( i ) === - 1 ) { + + allocatedBindingPoints.push( i ); + 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 + + if ( hasUniformChanged( uniform, i, cache ) === true ) { + + const offset = uniform.__offset; + + const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ]; + + let arrayOffset = 0; + + for ( let i = 0; i < values.length; i ++ ) { + + const value = values[ i ]; + + const info = getUniformSize( value ); + + if ( typeof value === 'number' ) { + + uniform.__data[ 0 ] = value; + gl.bufferSubData( gl.UNIFORM_BUFFER, offset + arrayOffset, uniform.__data ); + + } else if ( value.isMatrix3 ) { + + // manually converting 3x3 to 3x4 + + uniform.__data[ 0 ] = value.elements[ 0 ]; + uniform.__data[ 1 ] = value.elements[ 1 ]; + uniform.__data[ 2 ] = value.elements[ 2 ]; + uniform.__data[ 3 ] = value.elements[ 0 ]; + uniform.__data[ 4 ] = value.elements[ 3 ]; + uniform.__data[ 5 ] = value.elements[ 4 ]; + uniform.__data[ 6 ] = value.elements[ 5 ]; + uniform.__data[ 7 ] = value.elements[ 0 ]; + uniform.__data[ 8 ] = value.elements[ 6 ]; + uniform.__data[ 9 ] = value.elements[ 7 ]; + uniform.__data[ 10 ] = value.elements[ 8 ]; + uniform.__data[ 11 ] = value.elements[ 0 ]; + + } else { + + value.toArray( uniform.__data, arrayOffset ); + + arrayOffset += info.storage / Float32Array.BYTES_PER_ELEMENT; + + } + + } + + 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 { + + const values = Array.isArray( value ) ? value : [ value ]; + + const tempValues = []; + + for ( let i = 0; i < values.length; i ++ ) { + + tempValues.push( values[ i ].clone() ); + + } + + cache[ index ] = tempValues; + + } + + return true; + + } else { + + // compare current value with cached entry + + if ( typeof value === 'number' ) { + + if ( cache[ index ] !== value ) { + + cache[ index ] = value; + return true; + + } + + } else { + + const cachedObjects = Array.isArray( cache[ index ] ) ? cache[ index ] : [ cache[ index ] ]; + const values = Array.isArray( value ) ? value : [ value ]; + + for ( let i = 0; i < cachedObjects.length; i ++ ) { + + const cachedObject = cachedObjects[ i ]; + + if ( cachedObject.equals( values[ i ] ) === false ) { + + cachedObject.copy( values[ i ] ); + 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 infos = { + boundary: 0, // bytes + storage: 0 // bytes + }; + + const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ]; + + for ( let j = 0, jl = values.length; j < jl; j ++ ) { + + const value = values[ j ]; + + const info = getUniformSize( value ); + + infos.boundary += info.boundary; + infos.storage += info.storage; + + } + + // the following two properties will be used for partial buffer updates + + uniform.__data = new Float32Array( infos.storage / Float32Array.BYTES_PER_ELEMENT ); + uniform.__offset = offset; + + // + + if ( i > 0 ) { + + chunkOffset = offset % chunkSize; + + const remainingSizeInChunk = chunkSize - chunkOffset; + + // check for chunk overflow + + if ( chunkOffset !== 0 && ( remainingSizeInChunk - infos.boundary ) < 0 ) { + + // add padding and adjust offset + + offset += ( chunkSize - chunkOffset ); + uniform.__offset = offset; + + } + + } + + offset += infos.storage; + + } + + // ensure correct final padding + + chunkOffset = offset % chunkSize; + + if ( chunkOffset > 0 ) offset += ( chunkSize - chunkOffset ); + + // + + uniformsGroup.__size = offset; + uniformsGroup.__cache = {}; + + return this; + + } + + function getUniformSize( value ) { + + const info = { + boundary: 0, // bytes + storage: 0 // bytes + }; + + // 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 ) { + + console.warn( 'THREE.WebGLRenderer: Texture samplers can not be part of an uniforms group.' ); + + } else { + + console.warn( 'THREE.WebGLRenderer: Unsupported uniform value type.', value ); + + } + + return info; + + } + + function onUniformsGroupsDispose( event ) { + + const uniformsGroup = event.target; + + uniformsGroup.removeEventListener( 'dispose', onUniformsGroupsDispose ); + + const index = allocatedBindingPoints.indexOf( uniformsGroup.__bindingPointIndex ); + allocatedBindingPoints.splice( index, 1 ); + + gl.deleteBuffer( buffers[ uniformsGroup.id ] ); + + 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, + + dispose: dispose + + }; + + } + + function createCanvasElement() { + + const canvas = createElementNS( 'canvas' ); + 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; + + 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. + // 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 + + this.domElement = _canvas; + + // Debug configuration container + this.debug = { + + /** + * Enables error checking and reporting when shader programs are being compiled + * @type {boolean} + */ + checkShaderErrors: true + }; + + // clearing + + this.autoClear = true; + this.autoClearColor = true; + this.autoClearDepth = true; + this.autoClearStencil = true; + + // scene graph + + this.sortObjects = true; + + // user-defined clipping + + this.clippingPlanes = []; + this.localClippingEnabled = false; + + // physically based shading + + this.outputEncoding = LinearEncoding; + + // physical lights + + this.physicallyCorrectLights = false; + + // tone mapping + + this.toneMapping = NoToneMapping; + this.toneMappingExposure = 1.0; + + // internal properties + + const _this = this; + + let _isContextLost = false; + + // 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 _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; + + // frustum + + const _frustum = new Frustum(); + + // clipping + + let _clippingEnabled = false; + let _localClippingEnabled = false; + + // transmission + + let _transmissionRenderTarget = null; + + // camera matrices cache + + const _projScreenMatrix = new Matrix4(); + + const _vector2 = new Vector2(); + const _vector3 = new Vector3(); + + const _emptyScene = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: true }; + + function getTargetPixelRatio() { + + return _currentRenderTarget === null ? _pixelRatio : 1; + + } + + // 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, + depth: _depth, + stencil: _stencil, + antialias: _antialias, + premultipliedAlpha: _premultipliedAlpha, + 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 + _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.' ); + + } else { + + throw new Error( 'Error creating WebGL context.' ); + + } + + } + + } + + // Some experimental-webgl implementations do not have getShaderPrecisionFormat + + if ( _gl.getShaderPrecisionFormat === undefined ) { + + _gl.getShaderPrecisionFormat = function () { + + return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 }; + + }; + + } + + } catch ( error ) { + + console.error( 'THREE.WebGLRenderer: ' + error.message ); + throw error; + + } + + 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 ); + + extensions.init( capabilities ); + + utils = new WebGLUtils( _gl, extensions, capabilities ); + + state = new WebGLState( _gl, extensions, capabilities ); + + info = new WebGLInfo( _gl ); + properties = new WebGLProperties(); + textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ); + cubemaps = new WebGLCubeMaps( _this ); + cubeuvmaps = new WebGLCubeUVMaps( _this ); + attributes = new WebGLAttributes( _gl, capabilities ); + bindingStates = new WebGLBindingStates( _gl, extensions, attributes, capabilities ); + geometries = new WebGLGeometries( _gl, attributes, info, bindingStates ); + objects = new WebGLObjects( _gl, geometries, attributes, info ); + morphtargets = new WebGLMorphtargets( _gl, capabilities, textures ); + clipping = new WebGLClipping( properties ); + programCache = new WebGLPrograms( _this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping ); + materials = new WebGLMaterials( _this, properties ); + renderLists = new WebGLRenderLists(); + renderStates = new WebGLRenderStates( extensions, capabilities ); + 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 ); + indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities ); + + info.programs = programCache.programs; + + _this.capabilities = capabilities; + _this.extensions = extensions; + _this.properties = properties; + _this.renderLists = renderLists; + _this.shadowMap = shadowMap; + _this.state = state; + _this.info = info; + + } + + initGLContext(); + + // xr + + const xr = new WebXRManager( _this, _gl ); + + 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; + + _pixelRatio = pixelRatio; + + _canvas.width = Math.floor( width * pixelRatio ); + _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 + + 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(); + cubemaps.dispose(); + cubeuvmaps.dispose(); + objects.dispose(); + bindingStates.dispose(); + uniformsGroups.dispose(); + programCache.dispose(); + + xr.dispose(); + + xr.removeEventListener( 'sessionstart', onXRSessionStart ); + xr.removeEventListener( 'sessionend', onXRSessionEnd ); + + if ( _transmissionRenderTarget ) { + + _transmissionRenderTarget.dispose(); + _transmissionRenderTarget = null; + + } + + animation.stop(); + + }; + + // Events + + function onContextLost( event ) { + + event.preventDefault(); + + console.log( 'THREE.WebGLRenderer: Context Lost.' ); + + _isContextLost = true; + + } + + function onContextRestore( /* event */ ) { + + console.log( 'THREE.WebGLRenderer: Context Restored.' ); + + _isContextLost = false; + + const infoAutoReset = info.autoReset; + const shadowMapEnabled = shadowMap.enabled; + const shadowMapAutoUpdate = shadowMap.autoUpdate; + const shadowMapNeedsUpdate = shadowMap.needsUpdate; + const shadowMapType = shadowMap.type; + + initGLContext(); + + info.autoReset = infoAutoReset; + shadowMap.enabled = shadowMapEnabled; + shadowMap.autoUpdate = shadowMapAutoUpdate; + 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 + + 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 + + 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; + 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 ); + + } + + // + + if ( object.isMesh ) { + + if ( material.wireframe === true ) { + + state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() ); + renderer.setMode( _gl.LINES ); + + } else { + + renderer.setMode( _gl.TRIANGLES ); + + } + + } else if ( object.isLine ) { + + let lineWidth = material.linewidth; + + if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material + + state.setLineWidth( lineWidth * getTargetPixelRatio() ); + + if ( object.isLineSegments ) { + + renderer.setMode( _gl.LINES ); + + } else if ( object.isLineLoop ) { + + renderer.setMode( _gl.LINE_LOOP ); + + } else { + + renderer.setMode( _gl.LINE_STRIP ); + + } + + } else if ( object.isPoints ) { + + renderer.setMode( _gl.POINTS ); + + } else if ( object.isSprite ) { + + renderer.setMode( _gl.TRIANGLES ); + + } + + if ( object.isInstancedMesh ) { + + renderer.renderInstances( drawStart, drawCount, object.count ); + + } else if ( geometry.isInstancedBufferGeometry ) { + + 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 + + this.compile = function ( scene, camera ) { + + function prepare( material, scene, object ) { + + if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) { + + 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 ); + + } + + } + + } ); + + 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 ]; + + prepare( material2, scene, object ); + + } + + } else { + + prepare( material, scene, object ); + + } + + } + + } ); + + renderStateStack.pop(); + currentRenderState = null; + + }; + + // 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 + + 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; + + // update scene graph + + if ( scene.matrixWorldAutoUpdate === true ) scene.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 ); + + currentRenderList = renderLists.get( scene, renderListStack.length ); + currentRenderList.init(); + + 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 ( this.info.autoReset === true ) this.info.reset(); + + // + + 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.updateRenderTargetMipmap( _currentRenderTarget ); + + } + + // + + if ( scene.isScene === true ) scene.onAfterRender( _this, scene, camera ); + + // _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; + + } else if ( object.isLOD ) { + + if ( object.autoUpdate === true ) object.update( camera ); + + } else if ( object.isLight ) { + + currentRenderState.pushLight( object ); + + if ( object.castShadow ) { + + currentRenderState.pushShadow( object ); + + } + + } else if ( object.isSprite ) { + + if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) { + + 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 ); + + } + + } + + } 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 ); + + } + + } + + } else if ( material.visible ) { + + currentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null ); + + } + + } + + } + + } + + 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; + const transparentObjects = currentRenderList.transparent; + + currentRenderState.setupLightsView( camera ); + + if ( _clippingEnabled === true ) clipping.setGlobalState( _this.clippingPlanes, camera ); + + if ( transmissiveObjects.length > 0 ) renderTransmissionPass( opaqueObjects, scene, camera ); + + 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 + + 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, + type: extensions.has( 'EXT_color_buffer_half_float' ) ? HalfFloatType : UnsignedByteType, + minFilter: LinearMipmapLinearFilter, + 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(); + + // 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.forceSinglePass === false ) { + + 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, ... + + const materialProperties = properties.get( material ); + + const lights = currentRenderState.state.lights; + const shadowsArray = currentRenderState.state.shadowsArray; + + 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 + + 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; + + } + + } else { + + parameters.uniforms = programCache.getUniforms( material ); + + material.onBuild( object, parameters, _this ); + + material.onBeforeCompile( parameters, _this ); + + program = programCache.acquireProgram( parameters, programCacheKey ); + 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 ); + + // store the light setup it was created for + + materialProperties.needsLights = materialNeedsLights( material ); + materialProperties.lightsStateVersion = lightsStateVersion; + + if ( materialProperties.needsLights ) { + + // wire up the material to this renderer's lighting state + + uniforms.ambientLightColor.value = lights.state.ambient; + uniforms.lightProbe.value = lights.state.probe; + uniforms.directionalLights.value = lights.state.directional; + uniforms.directionalLightShadows.value = lights.state.directionalShadow; + uniforms.spotLights.value = lights.state.spot; + uniforms.spotLightShadows.value = lights.state.spotShadow; + uniforms.rectAreaLights.value = lights.state.rectArea; + uniforms.ltc_1.value = lights.state.rectAreaLTC1; + uniforms.ltc_2.value = lights.state.rectAreaLTC2; + uniforms.pointLights.value = lights.state.point; + uniforms.pointLightShadows.value = lights.state.pointShadow; + uniforms.hemisphereLights.value = lights.state.hemi; + + uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; + uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix; + uniforms.spotShadowMap.value = lights.state.spotShadowMap; + uniforms.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 + + } + + const progUniforms = program.getUniforms(); + const uniformsList = WebGLUniforms.seqWithValue( progUniforms.seq, uniforms ); + + materialProperties.currentProgram = program; + materialProperties.uniformsList = uniformsList; + + return program; + + } + + function updateCommonMaterialProperties( material, parameters ) { + + const materialProperties = properties.get( material ); + + materialProperties.outputEncoding = parameters.outputEncoding; + materialProperties.instancing = parameters.instancing; + materialProperties.skinning = parameters.skinning; + materialProperties.morphTargets = parameters.morphTargets; + materialProperties.morphNormals = parameters.morphNormals; + materialProperties.morphColors = parameters.morphColors; + materialProperties.morphTargetsCount = parameters.morphTargetsCount; + materialProperties.numClippingPlanes = parameters.numClippingPlanes; + materialProperties.numIntersection = parameters.numClipIntersection; + materialProperties.vertexAlphas = parameters.vertexAlphas; + 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, ... + + textures.resetTextureUnits(); + + const fog = scene.fog; + const environment = material.isMeshStandardMaterial ? scene.environment : null; + const encoding = ( _currentRenderTarget === null ) ? _this.outputEncoding : ( _currentRenderTarget.isXRRenderTarget === true ? _currentRenderTarget.texture.encoding : LinearEncoding ); + const envMap = ( material.isMeshStandardMaterial ? cubeuvmaps : cubemaps ).get( material.envMap || environment ); + const vertexAlphas = material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4; + const vertexTangents = !! material.normalMap && !! geometry.attributes.tangent; + const morphTargets = !! geometry.morphAttributes.position; + const morphNormals = !! geometry.morphAttributes.normal; + const morphColors = !! geometry.morphAttributes.color; + const toneMapping = material.toneMapped ? _this.toneMapping : NoToneMapping; + + const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; + 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 + // 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; + + } else if ( materialProperties.outputEncoding !== encoding ) { + + needsProgramChange = true; + + } else if ( object.isInstancedMesh && materialProperties.instancing === false ) { + + needsProgramChange = true; + + } else if ( ! object.isInstancedMesh && materialProperties.instancing === true ) { + + needsProgramChange = true; + + } else if ( object.isSkinnedMesh && materialProperties.skinning === false ) { + + needsProgramChange = true; + + } else if ( ! object.isSkinnedMesh && materialProperties.skinning === true ) { + + needsProgramChange = true; + + } else if ( materialProperties.envMap !== envMap ) { + + needsProgramChange = true; + + } else if ( material.fog === true && materialProperties.fog !== fog ) { + + needsProgramChange = true; + + } else if ( materialProperties.numClippingPlanes !== undefined && + ( materialProperties.numClippingPlanes !== clipping.numPlanes || + materialProperties.numIntersection !== clipping.numIntersection ) ) { + + needsProgramChange = true; + + } else if ( materialProperties.vertexAlphas !== vertexAlphas ) { + + needsProgramChange = true; + + } else if ( materialProperties.vertexTangents !== vertexTangents ) { + + needsProgramChange = true; + + } else if ( materialProperties.morphTargets !== morphTargets ) { + + needsProgramChange = true; + + } else if ( materialProperties.morphNormals !== morphNormals ) { + + needsProgramChange = true; + + } else if ( materialProperties.morphColors !== morphColors ) { + + needsProgramChange = true; + + } else if ( materialProperties.toneMapping !== toneMapping ) { + + needsProgramChange = true; + + } else if ( capabilities.isWebGL2 === true && materialProperties.morphTargetsCount !== morphTargetsCount ) { + + needsProgramChange = true; + + } + + } 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; + + 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 + // 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) + + 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 + // 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(); + + p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture, textures ); + p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize ); + + } else { + + console.warn( 'THREE.WebGLRenderer: SkinnedMesh can only be used with WebGL 2. With WebGL 1 OES_texture_float and vertex textures support is required.' ); + + } + + } + + } + + 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 + + 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 + + p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix ); + p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix ); + 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 ]; + + uniformsGroups.update( group, program ); + uniformsGroups.bind( group, program ); + + } else { + + console.warn( 'THREE.WebGLRenderer: Uniform Buffer Objects can only be used with WebGL 2.' ); + + } + + } + + } + + return program; + + } + + // If uniforms are marked as clean, they don't need to be loaded to the GPU. + + function markUniformsLightsNeedsUpdate( uniforms, value ) { + + uniforms.ambientLightColor.needsUpdate = value; + uniforms.lightProbe.needsUpdate = value; + + uniforms.directionalLights.needsUpdate = value; + uniforms.directionalLightShadows.needsUpdate = value; + uniforms.pointLights.needsUpdate = value; + uniforms.pointLightShadows.needsUpdate = value; + uniforms.spotLights.needsUpdate = value; + uniforms.spotLightShadows.needsUpdate = value; + uniforms.rectAreaLights.needsUpdate = value; + uniforms.hemisphereLights.needsUpdate = value; + + } + + function materialNeedsLights( material ) { + + return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || + material.isMeshStandardMaterial || material.isShadowMaterial || + ( material.isShaderMaterial && material.lights === true ); + + } + + 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. + if ( extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true ) { + + console.warn( 'THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided' ); + renderTargetProperties.__useRenderToTexture = false; + + } + + } + + } + + }; + + 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 ); + useDefaultFramebuffer = false; + + } else if ( renderTargetProperties.__webglFramebuffer === undefined ) { + + textures.setupRenderTarget( renderTarget ); + + } else if ( renderTargetProperties.__hasExternalTextures ) { + + // 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 ); + + } + + const texture = renderTarget.texture; + + if ( texture.isData3DTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) { + + isRenderTarget3D = true; + + } + + const __webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer; + + if ( renderTarget.isWebGLCubeRenderTarget ) { + + framebuffer = __webglFramebuffer[ activeCubeFace ]; + isCube = true; + + } else if ( ( capabilities.isWebGL2 && renderTarget.samples > 0 ) && textures.useMultisampledRTT( renderTarget ) === false ) { + + framebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer; + + } 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 + + }; + + this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer, activeCubeFaceIndex ) { + + if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) { + + console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' ); + return; + + } + + 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 + ! 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) + + 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 + _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 { + + if ( srcTexture.isCompressedTexture ) { + + _gl.compressedTexSubImage2D( _gl.TEXTURE_2D, level, position.x, position.y, srcTexture.mipmaps[ 0 ].width, srcTexture.mipmaps[ 0 ].height, glFormat, srcTexture.mipmaps[ 0 ].data ); + + } else { + + _gl.texSubImage2D( _gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image ); + + } + + } + + // 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; + + } else if ( dstTexture.isDataArrayTexture ) { + + textures.setTexture2DArray( dstTexture, 0 ); + glTarget = _gl.TEXTURE_2D_ARRAY; + + } else { + + 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.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 ); + + // 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 || texture.isCompressedArrayTexture ) { + + textures.setTexture2DArray( texture, 0 ); + + } else { + + textures.setTexture2D( texture, 0 ); + + } + + state.unbindTexture(); + + }; + + this.resetState = function () { + + _currentActiveCubeFace = 0; + _currentActiveMipmapLevel = 0; + _currentRenderTarget = null; + + state.reset(); + bindingStates.reset(); + + }; + + if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { + + __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); + + } + + } + + class WebGL1Renderer extends WebGLRenderer {} + + WebGL1Renderer.prototype.isWebGL1Renderer = true; + + class FogExp2 { + + constructor( color, density = 0.00025 ) { + + this.isFogExp2 = true; + + this.name = ''; + + this.color = new Color( color ); + this.density = density; + + } + + clone() { + + return new FogExp2( this.color, this.density ); + + } + + toJSON( /* meta */ ) { + + return { + type: 'FogExp2', + color: this.color.getHex(), + density: this.density + }; + + } + + } + + class Fog { + + constructor( color, near = 1, far = 1000 ) { + + this.isFog = true; + + this.name = ''; + + this.color = new Color( color ); + + this.near = near; + this.far = far; + + } + + clone() { + + return new Fog( this.color, this.near, this.far ); + + } + + toJSON( /* meta */ ) { + + return { + type: 'Fog', + color: this.color.getHex(), + near: this.near, + far: this.far + }; + + } + + } + + class Scene extends Object3D { + + constructor() { + + super(); + + this.isScene = true; + + this.type = 'Scene'; + + this.background = null; + this.environment = null; + this.fog = null; + + this.backgroundBlurriness = 0; + this.backgroundIntensity = 1; + + this.overrideMaterial = null; + + 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.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.object.backgroundBlurriness = this.backgroundBlurriness; + if ( this.backgroundIntensity !== 1 ) data.object.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 { + + constructor( array, stride ) { + + this.isInterleavedBuffer = true; + + this.array = array; + this.stride = stride; + this.count = array !== undefined ? array.length / stride : 0; + + this.usage = StaticDrawUsage; + this.updateRange = { offset: 0, count: - 1 }; + + this.version = 0; + + this.uuid = 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; + this.stride = source.stride; + 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 + + 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, + buffer: this.array.buffer._uuid, + type: this.array.constructor.name, + stride: this.stride + }; + + } + + } + + const _vector$6 = /*@__PURE__*/ new Vector3(); + + class InterleavedBufferAttribute { + + constructor( interleavedBuffer, itemSize, offset, normalized = false ) { + + this.isInterleavedBufferAttribute = true; + + this.name = ''; + + this.data = interleavedBuffer; + this.itemSize = itemSize; + this.offset = offset; + + this.normalized = normalized; + + } + + 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 ) { + + let x = this.data.array[ index * this.data.stride + this.offset ]; + + if ( this.normalized ) x = denormalize( x, this.array ); + + return x; + + } + + getY( index ) { + + let y = this.data.array[ index * this.data.stride + this.offset + 1 ]; + + if ( this.normalized ) y = denormalize( y, this.array ); + + return y; + + } + + getZ( index ) { + + let z = this.data.array[ index * this.data.stride + this.offset + 2 ]; + + if ( this.normalized ) z = denormalize( z, this.array ); + + return z; + + } + + getW( index ) { + + 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 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 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 ] ); + + } + + } + + // de-interleave data and save it as an ordinary buffer attribute for now + + return { + itemSize: this.itemSize, + type: this.array.constructor.name, + array: array, + normalized: this.normalized + }; + + } else { + + // 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, + data: this.data.uuid, + offset: this.offset, + normalized: this.normalized + }; + + } + + } + + } + + class SpriteMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isSpriteMaterial = true; + + this.type = 'SpriteMaterial'; + + this.color = new Color( 0xffffff ); + + this.map = null; + + this.alphaMap = null; + + this.rotation = 0; + + this.sizeAttenuation = true; + + this.transparent = true; + + this.fog = true; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.color.copy( source.color ); + + this.map = source.map; + + this.alphaMap = source.alphaMap; + + this.rotation = source.rotation; + + this.sizeAttenuation = source.sizeAttenuation; + + 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 ); + + // 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( { + + distance: distance, + point: _intersectPoint.clone(), + uv: Triangle.getUV( _intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ), + face: null, + 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 + 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.applyMatrix4( _viewWorldMatrix ); + + } + + const _v1$2 = /*@__PURE__*/ new Vector3(); + const _v2$1 = /*@__PURE__*/ new Vector3(); + + class LOD extends Object3D { + + constructor() { + + super(); + + this._currentLevel = 0; + + this.type = 'LOD'; + + Object.defineProperties( this, { + levels: { + enumerable: true, + value: [] + }, + isLOD: { + value: true, + } + } ); + + 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, level.hysteresis ); + + } + + this.autoUpdate = source.autoUpdate; + + return this; + + } + + 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 ++ ) { + + 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 ++ ) { + + 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, + 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 ); + + this.isSkinnedMesh = true; + + this.type = 'SkinnedMesh'; + + this.bindMode = 'attached'; + this.bindMatrix = new Matrix4(); + this.bindMatrixInverse = new Matrix4(); + + } + + copy( source, recursive ) { + + super.copy( source, recursive ); + + this.bindMode = source.bindMode; + this.bindMatrix.copy( source.bindMatrix ); + this.bindMatrixInverse.copy( source.bindMatrixInverse ); + + 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 { + + vector.set( 1, 0, 0, 0 ); // do something reasonable + + } + + 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' ) { + + this.bindMatrixInverse.copy( this.bindMatrix ).invert(); + + } else { + + 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 { + + constructor() { + + super(); + + this.isBone = true; + + this.type = 'Bone'; + + } + + } + + class DataTexture extends Texture { + + constructor( data = null, width = 1, height = 1, format, type, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, encoding ) { + + super( null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); + + this.isDataTexture = true; + + this.image = { data: data, width: width, height: height }; + + this.generateMipmaps = false; + this.flipY = false; + this.unpackAlignment = 1; + + } + + } + + const _offsetMatrix = /*@__PURE__*/ new Matrix4(); + const _identityMatrix = /*@__PURE__*/ new Matrix4(); + + class Skeleton { + + constructor( bones = [], boneInverses = [] ) { + + this.uuid = generateUUID(); + + this.bones = bones.slice( 0 ); + this.boneInverses = boneInverses; + this.boneMatrices = null; + + this.boneTexture = null; + this.boneTextureSize = 0; + + 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 + + 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 + + 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(); + bone.matrix.multiply( bone.matrixWorld ); + + } 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 + + 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; + + _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) + // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8) + // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16) + // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32) + // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64) + + 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 ); + boneTexture.needsUpdate = true; + + this.boneMatrices = boneMatrices; + this.boneTexture = boneTexture; + 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: { + version: 4.5, + type: 'Skeleton', + generator: 'Skeleton.toJSON' + }, + bones: [], + boneInverses: [] + }; + + 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 ) { + + 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 ); + + this.isInstancedMesh = true; + + this.instanceMatrix = new InstancedBufferAttribute( new Float32Array( count * 16 ), 16 ); + 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 ); + + if ( source.instanceColor !== null ) this.instanceColor = source.instanceColor.clone(); + + 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 + + _mesh.matrixWorld = _instanceWorldMatrix; + + _mesh.raycast( raycaster, _instanceIntersects ); + + // process the result of raycast + + for ( let i = 0, l = _instanceIntersects.length; i < l; i ++ ) { + + const intersect = _instanceIntersects[ i ]; + intersect.instanceId = instanceId; + 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 { + + constructor( parameters ) { + + super(); + + this.isLineBasicMaterial = true; + + this.type = 'LineBasicMaterial'; + + this.color = new Color( 0xffffff ); + + this.linewidth = 1; + this.linecap = 'round'; + this.linejoin = 'round'; + + this.fog = true; + + this.setValues( parameters ); + + } + + + copy( source ) { + + super.copy( source ); + + this.color.copy( source.color ); + + this.linewidth = source.linewidth; + this.linecap = source.linecap; + this.linejoin = source.linejoin; + + 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(); + + this.isLine = true; + + this.type = 'Line'; + + this.geometry = geometry; + 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 + + 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 + + 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; + + // + + _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(); + const vEnd = new Vector3(); + const interSegment = new Vector3(); + const interRay = new Vector3(); + const step = this.isLineSegments ? 2 : 1; + + 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 + + const distance = raycaster.ray.origin.distanceTo( interRay ); + + if ( distance < raycaster.near || distance > raycaster.far ) continue; + + intersects.push( { + + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4( this.matrixWorld ), + index: i, + face: null, + faceIndex: null, + object: this + + } ); + + } + + } else { + + 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 + + const distance = raycaster.ray.origin.distanceTo( interRay ); + + if ( distance < raycaster.near || distance > raycaster.far ) continue; + + intersects.push( { + + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4( this.matrixWorld ), + index: i, + face: null, + faceIndex: null, + object: this + + } ); + + } + + } + + } + + 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 ); + this.morphTargetDictionary[ name ] = m; + + } + + } + + } + + } + + } + + 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 + + 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 { + + constructor( geometry, material ) { + + super( geometry, material ); + + this.isLineLoop = true; + + this.type = 'LineLoop'; + + } + + } + + class PointsMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isPointsMaterial = true; + + this.type = 'PointsMaterial'; + + this.color = new Color( 0xffffff ); + + this.map = null; + + this.alphaMap = null; + + this.size = 1; + this.sizeAttenuation = true; + + this.fog = true; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.color.copy( source.color ); + + this.map = source.map; + + this.alphaMap = source.alphaMap; + + this.size = source.size; + this.sizeAttenuation = source.sizeAttenuation; + + 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(); + + this.isPoints = true; + + this.type = 'Points'; + + this.geometry = geometry; + 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 + + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + + _sphere.copy( geometry.boundingSphere ); + _sphere.applyMatrix4( matrixWorld ); + _sphere.radius += threshold; + + if ( raycaster.ray.intersectsSphere( _sphere ) === false ) return; + + // + + _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 ); + this.morphTargetDictionary[ name ] = m; + + } + + } + + } + + } + + } + + 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; + + intersects.push( { + + distance: distance, + distanceToRay: Math.sqrt( rayPointDistanceSq ), + point: intersectPoint, + index: index, + face: null, + object: object + + } ); + + } + + } + + class VideoTexture extends Texture { + + constructor( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { + + super( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + + this.isVideoTexture = true; + + this.minFilter = minFilter !== undefined ? minFilter : LinearFilter; + 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 { + + constructor( width, height, format ) { + + super( { width, height } ); + + this.isFramebufferTexture = true; + + this.format = format; + + this.magFilter = NearestFilter; + this.minFilter = NearestFilter; + + this.generateMipmaps = false; + + this.needsUpdate = true; + + } + + } + + class CompressedTexture extends Texture { + + constructor( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { + + super( null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); + + this.isCompressedTexture = true; + + this.image = { width: width, height: height }; + 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 + // 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 { + + constructor( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { + + super( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + + this.isCanvasTexture = true; + + this.needsUpdate = true; + + } + + } + + /** + * Extensible curve object. + * + * Some common of curve methods: + * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget ) + * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget ) + * .getPoints(), .getSpacedPoints() + * .getLength() + * .updateArcLengths() + * + * This following curves inherit from THREE.Curve: + * + * -- 2D curves -- + * THREE.ArcCurve + * THREE.CubicBezierCurve + * THREE.EllipseCurve + * THREE.LineCurve + * THREE.QuadraticBezierCurve + * THREE.SplineCurve + * + * -- 3D curves -- + * THREE.CatmullRomCurve3 + * THREE.CubicBezierCurve3 + * THREE.LineCurve3 + * THREE.QuadraticBezierCurve3 + * + * A series of curves can be represented as a THREE.CurvePath. + * + **/ + + class Curve { + + constructor() { + + this.type = 'Curve'; + + this.arcLengthDivisions = 200; + + } + + // Virtual base class method to overwrite and implement in subclasses + // - t [0 .. 1] + + getPoint( /* t, optionalTarget */ ) { + + console.warn( 'THREE.Curve: .getPoint() not implemented.' ); + return null; + + } + + // Get point at relative position in curve according to arc length + // - u [0 .. 1] + + getPointAt( u, optionalTarget ) { + + const t = this.getUtoTmapping( u ); + return this.getPoint( t, optionalTarget ); + + } + + // 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 ) + + 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 + + getLength() { + + const lengths = this.getLengths(); + return lengths[ lengths.length - 1 ]; + + } + + // 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 ); + 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. + + } + + updateArcLengths() { + + this.needsUpdate = true; + this.getLengths(); + + } + + // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant + + getUtoTmapping( u, distance ) { + + const arcLengths = this.getLengths(); + + let i = 0; + const il = arcLengths.length; + + let targetArcLength; // The targeted u distance value to get + + if ( distance ) { + + targetArcLength = distance; + + } else { + + targetArcLength = u * arcLengths[ il - 1 ]; + + } + + // binary search for the index with largest value smaller than target u distance + + let low = 0, high = il - 1, comparison; + + while ( low <= high ) { + + i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats + + comparison = arcLengths[ i ] - targetArcLength; + + if ( comparison < 0 ) { + + low = i + 1; + + } else if ( comparison > 0 ) { + + high = i - 1; + + } else { + + high = i; + 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 + + const lengthBefore = arcLengths[ i ]; + const lengthAfter = arcLengths[ i + 1 ]; + + const segmentLength = lengthAfter - lengthBefore; + + // 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 + // 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 + + if ( t1 < 0 ) t1 = 0; + if ( t2 > 1 ) t2 = 1; + + const pt1 = this.getPoint( t1 ); + const pt2 = this.getPoint( t2 ); + + const tangent = optionalTarget || ( ( pt1.isVector2 ) ? new Vector2() : new Vector3() ); + + 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 + + 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 + + normals[ 0 ] = new Vector3(); + binormals[ 0 ] = new Vector3(); + let min = Number.MAX_VALUE; + 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 + + 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 ( 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: { + version: 4.5, + type: 'Curve', + generator: 'Curve.toJSON' + } + }; + + data.arcLengthDivisions = this.arcLengthDivisions; + data.type = this.type; + + return data; + + } + + fromJSON( json ) { + + this.arcLengthDivisions = json.arcLengthDivisions; + + return this; + + } + + } + + class EllipseCurve extends Curve { + + constructor( aX = 0, aY = 0, xRadius = 1, yRadius = 1, aStartAngle = 0, aEndAngle = Math.PI * 2, aClockwise = false, aRotation = 0 ) { + + super(); + + this.isEllipseCurve = true; + + this.type = 'EllipseCurve'; + + this.aX = aX; + this.aY = aY; + + this.xRadius = xRadius; + this.yRadius = yRadius; + + this.aStartAngle = aStartAngle; + this.aEndAngle = aEndAngle; + + 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 + while ( deltaAngle < 0 ) deltaAngle += twoPi; + while ( deltaAngle > twoPi ) deltaAngle -= twoPi; + + if ( deltaAngle < Number.EPSILON ) { + + if ( samePoints ) { + + deltaAngle = 0; + + } else { + + deltaAngle = twoPi; + + } + + } + + if ( this.aClockwise === true && ! samePoints ) { + + if ( deltaAngle === twoPi ) { + + deltaAngle = - twoPi; + + } else { + + deltaAngle = deltaAngle - twoPi; + + } + + } + + 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. + 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; + this.aY = source.aY; + + this.xRadius = source.xRadius; + this.yRadius = source.yRadius; + + this.aStartAngle = source.aStartAngle; + this.aEndAngle = source.aEndAngle; + + this.aClockwise = source.aClockwise; + + this.aRotation = source.aRotation; + + return this; + + } + + toJSON() { + + const data = super.toJSON(); + + data.aX = this.aX; + data.aY = this.aY; + + data.xRadius = this.xRadius; + data.yRadius = this.yRadius; + + data.aStartAngle = this.aStartAngle; + data.aEndAngle = this.aEndAngle; + + data.aClockwise = this.aClockwise; + + data.aRotation = this.aRotation; + + return data; + + } + + fromJSON( json ) { + + super.fromJSON( json ); + + this.aX = json.aX; + this.aY = json.aY; + + this.xRadius = json.xRadius; + this.yRadius = json.yRadius; + + this.aStartAngle = json.aStartAngle; + this.aEndAngle = json.aEndAngle; + + this.aClockwise = json.aClockwise; + + this.aRotation = json.aRotation; + + return this; + + } + + } + + class ArcCurve extends EllipseCurve { + + constructor( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { + + super( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); + + this.isArcCurve = true; + + this.type = 'ArcCurve'; + + } + + } + + /** + * Centripetal CatmullRom Curve - which is useful for avoiding + * cusps and self-intersections in non-uniform catmull rom curves. + * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf + * + * curve.type accepts centripetal(default), chordal and catmullrom + * curve.tension is used for catmullrom which defaults to 0.5 + */ + + + /* + Based on an optimized c++ solution in + - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/ + - http://ideone.com/NoEbVM + + This CubicPoly class could be used for reusing some variables and calculations, + but for three.js curve use, it could be possible inlined and flatten into a single function call + which can be placed in CurveUtils. + */ + + function CubicPoly() { + + let c0 = 0, c1 = 0, c2 = 0, c3 = 0; + + /* + * Compute coefficients for a cubic polynomial + * p(s) = c0 + c1*s + c2*s^2 + c3*s^3 + * such that + * p(0) = x0, p(1) = x1 + * and + * p'(0) = t0, p'(1) = t1. + */ + function init( x0, x1, t0, t1 ) { + + c0 = x0; + c1 = t0; + c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1; + c3 = 2 * x0 - 2 * x1 + t0 + t1; + + } + + return { + + initCatmullRom: function ( x0, x1, x2, x3, tension ) { + + init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) ); + + }, + + 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] + t1 *= dt1; + t2 *= dt1; + + init( x1, x2, t1, t2 ); + + }, + + calc: function ( t ) { + + const t2 = t * t; + const t3 = t2 * t; + 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(); + + this.isCatmullRomCurve3 = true; + + this.type = 'CatmullRomCurve3'; + + this.points = points; + this.closed = closed; + this.curveType = curveType; + this.tension = tension; + + } + + getPoint( t, optionalTarget = new Vector3() ) { + + const point = optionalTarget; + + const points = this.points; + const l = points.length; + + 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 ) { + + p0 = points[ ( intPoint - 1 ) % l ]; + + } else { + + // extrapolate first point + 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 { + + // extrapolate last point + tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] ); + p3 = tmp; + + } + + if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) { + + // init Centripetal / Chordal Catmull-Rom + 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 + if ( dt1 < 1e-4 ) dt1 = 1.0; + if ( dt0 < 1e-4 ) dt0 = dt1; + if ( dt2 < 1e-4 ) dt2 = dt1; + + px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 ); + py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 ); + pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 ); + + } else if ( this.curveType === 'catmullrom' ) { + + px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension ); + py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension ); + pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension ); + + } + + point.set( + px.calc( weight ), + py.calc( weight ), + pz.calc( weight ) + ); + + return point; + + } + + 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 ); + + } + + class CubicBezierCurve extends Curve { + + constructor( v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2(), v3 = new Vector2() ) { + + super(); + + this.isCubicBezierCurve = true; + + this.type = 'CubicBezierCurve'; + + this.v0 = v0; + this.v1 = v1; + 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; + + 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 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); + this.v3.copy( source.v3 ); + + return this; + + } + + toJSON() { + + const data = super.toJSON(); + + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + data.v3 = this.v3.toArray(); + + return data; + + } + + fromJSON( json ) { + + super.fromJSON( json ); + + this.v0.fromArray( json.v0 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); + this.v3.fromArray( json.v3 ); + + return this; + + } + + } + + class CubicBezierCurve3 extends Curve { + + constructor( v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3(), v3 = new Vector3() ) { + + super(); + + this.isCubicBezierCurve3 = true; + + this.type = 'CubicBezierCurve3'; + + this.v0 = v0; + this.v1 = v1; + 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; + + 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 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); + this.v3.copy( source.v3 ); + + return this; + + } + + toJSON() { + + const data = super.toJSON(); + + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + data.v3 = this.v3.toArray(); + + return data; + + } + + fromJSON( json ) { + + super.fromJSON( json ); + + this.v0.fromArray( json.v0 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); + this.v3.fromArray( json.v3 ); + + return this; + + } + + } + + class LineCurve extends Curve { + + constructor( v1 = new Vector2(), v2 = new Vector2() ) { + + super(); + + this.isLineCurve = true; + + this.type = 'LineCurve'; + + 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 + 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 { + + constructor( v1 = new Vector3(), v2 = new Vector3() ) { + + super(); + + this.isLineCurve3 = true; + + this.type = 'LineCurve3'; + + 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 + 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 { + + constructor( v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2() ) { + + super(); + + this.isQuadraticBezierCurve = true; + + this.type = 'QuadraticBezierCurve'; + + this.v0 = v0; + this.v1 = v1; + this.v2 = v2; + + } + + getPoint( t, optionalTarget = new Vector2() ) { + + const point = optionalTarget; + + const v0 = this.v0, v1 = this.v1, v2 = this.v2; + + point.set( + QuadraticBezier( t, v0.x, v1.x, v2.x ), + QuadraticBezier( t, v0.y, v1.y, v2.y ) + ); + + return point; + + } + + copy( source ) { + + super.copy( source ); + + this.v0.copy( source.v0 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); + + return this; + + } + + toJSON() { + + const data = super.toJSON(); + + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + + return data; + + } + + fromJSON( json ) { + + super.fromJSON( json ); + + this.v0.fromArray( json.v0 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); + + return this; + + } + + } + + class QuadraticBezierCurve3 extends Curve { + + constructor( v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3() ) { + + super(); + + this.isQuadraticBezierCurve3 = true; + + this.type = 'QuadraticBezierCurve3'; + + this.v0 = v0; + this.v1 = v1; + this.v2 = v2; + + } + + getPoint( t, optionalTarget = new Vector3() ) { + + const point = optionalTarget; + + const v0 = this.v0, v1 = this.v1, v2 = this.v2; + + point.set( + QuadraticBezier( t, v0.x, v1.x, v2.x ), + QuadraticBezier( t, v0.y, v1.y, v2.y ), + QuadraticBezier( t, v0.z, v1.z, v2.z ) + ); + + return point; + + } + + copy( source ) { + + super.copy( source ); + + this.v0.copy( source.v0 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); + + return this; + + } + + toJSON() { + + const data = super.toJSON(); + + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + + return data; + + } + + fromJSON( json ) { + + super.fromJSON( json ); + + this.v0.fromArray( json.v0 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); + + return this; + + } + + } + + class SplineCurve extends Curve { + + constructor( points = [] ) { + + super(); + + this.isSplineCurve = true; + + this.type = 'SplineCurve'; + + this.points = points; + + } + + getPoint( t, optionalTarget = new Vector2() ) { + + const point = optionalTarget; + + const points = this.points; + const p = ( points.length - 1 ) * t; + + const intPoint = Math.floor( p ); + const weight = p - intPoint; + + const p0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ]; + const p1 = points[ intPoint ]; + const p2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ]; + const p3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ]; + + point.set( + CatmullRom( weight, p0.x, p1.x, p2.x, p3.x ), + CatmullRom( weight, p0.y, p1.y, p2.y, p3.y ) + ); + + return point; + + } + + 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({ + __proto__: null, + ArcCurve: ArcCurve, + CatmullRomCurve3: CatmullRomCurve3, + CubicBezierCurve: CubicBezierCurve, + CubicBezierCurve3: CubicBezierCurve3, + EllipseCurve: EllipseCurve, + LineCurve: LineCurve, + LineCurve3: LineCurve3, + QuadraticBezierCurve: QuadraticBezierCurve, + QuadraticBezierCurve3: QuadraticBezierCurve3, + SplineCurve: SplineCurve + }); + + /************************************************************** + * Curved Path - a curve path is simply a array of connected + * curves, but retains the api of a curve + **************************************************************/ + + class CurvePath extends Curve { + + constructor() { + + super(); + + this.type = 'CurvePath'; + + this.curves = []; + this.autoClose = false; // Automatically closes the path + + } + + 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 + // 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. + + while ( i < curveLengths.length ) { + + if ( curveLengths[ i ] >= d ) { + + const diff = curveLengths[ i ] - d; + const curve = this.curves[ i ]; + + const segmentLength = curve.getLength(); + const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; + + return curve.getPointAt( u, optionalTarget ); + + } + + i ++; + + } + + return null; + + // loop where sum != 0, sum > 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 { + + constructor( points ) { + + 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*/ ) { + + 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 { + + constructor( points = [ new Vector2( 0, - 0.5 ), new Vector2( 0.5, 0 ), new Vector2( 0, 0.5 ) ], segments = 12, phiStart = 0, phiLength = Math.PI * 2 ) { + + super(); + + this.type = 'LatheGeometry'; + + this.parameters = { + points: points, + segments: segments, + phiStart: phiStart, + phiLength: phiLength + }; + + segments = Math.floor( segments ); + + // clamp phiLength so it's in range of [ 0, 2PI ] + + phiLength = clamp( phiLength, 0, Math.PI * 2 ); + + // buffers + + const indices = []; + const vertices = []; + const uvs = []; + const initNormals = []; + const normals = []; + + // helper variables + + const inverseSegments = 1.0 / segments; + const vertex = new Vector3(); + const uv = new Vector2(); + const normal = new Vector3(); + const curNormal = new Vector3(); + const prevNormal = new Vector3(); + let dx = 0; + 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; + normal.y = - dx; + normal.z = dy * 0.0; + + prevNormal.copy( normal ); + + 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; + normal.y = - dx; + normal.z = dy * 0.0; + + curNormal.copy( normal ); + + normal.x += prevNormal.x; + normal.y += prevNormal.y; + normal.z += prevNormal.z; + + normal.normalize(); + + initNormals.push( normal.x, normal.y, normal.z ); + + prevNormal.copy( curNormal ); + + } + + } + + // 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 + + uv.x = i / segments; + uv.y = j / ( points.length - 1 ); + + 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 + + for ( let i = 0; i < segments; i ++ ) { + + for ( let j = 0; j < ( points.length - 1 ); j ++ ) { + + const base = j + i * points.length; + + const a = base; + const b = base + points.length; + const c = base + points.length + 1; + const d = base + 1; + + // faces + + indices.push( a, b, d ); + indices.push( c, d, b ); + + } + + } + + // 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 { + + constructor( radius = 1, length = 1, capSegments = 4, radialSegments = 8 ) { + + const path = new Path(); + path.absarc( 0, - length / 2, radius, Math.PI * 1.5, 0 ); + path.absarc( 0, length / 2, radius, 0, Math.PI * 0.5 ); + + super( path.getPoints( capSegments ), radialSegments ); + + this.type = 'CapsuleGeometry'; + + this.parameters = { + radius: radius, + height: length, + capSegments: capSegments, + radialSegments: radialSegments, + }; + + } + + static fromJSON( data ) { + + return new CapsuleGeometry( data.radius, data.length, data.capSegments, data.radialSegments ); + + } + + } + + class CircleGeometry extends BufferGeometry { + + constructor( radius = 1, segments = 32, thetaStart = 0, thetaLength = Math.PI * 2 ) { + + super(); + + this.type = 'CircleGeometry'; + + this.parameters = { + radius: radius, + segments: segments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + + segments = Math.max( 3, segments ); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + + // helper variables + + const vertex = new Vector3(); + 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 + + vertex.x = radius * Math.cos( segment ); + vertex.y = radius * Math.sin( segment ); + + vertices.push( vertex.x, vertex.y, vertex.z ); + + // normal + + normals.push( 0, 0, 1 ); + + // uvs + + uv.x = ( vertices[ i ] / radius + 1 ) / 2; + uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2; + + uvs.push( uv.x, uv.y ); + + } + + // indices + + for ( let i = 1; i <= segments; i ++ ) { + + indices.push( i, i + 1, 0 ); + + } + + // 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 { + + constructor( radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) { + + super(); + + this.type = 'CylinderGeometry'; + + this.parameters = { + radiusTop: radiusTop, + radiusBottom: radiusBottom, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + + const scope = this; + + radialSegments = Math.floor( radialSegments ); + heightSegments = Math.floor( heightSegments ); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + + // helper variables + + let index = 0; + const indexArray = []; + const halfHeight = height / 2; + let groupStart = 0; + + // generate geometry + + generateTorso(); + + if ( openEnded === false ) { + + if ( radiusTop > 0 ) generateCap( true ); + if ( radiusBottom > 0 ) generateCap( false ); + + } + + // 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 + 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 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 + + vertex.x = radius * sinTheta; + vertex.y = - v * height + halfHeight; + vertex.z = radius * cosTheta; + vertices.push( vertex.x, vertex.y, vertex.z ); + + // normal + + normal.set( sinTheta, slope, cosTheta ).normalize(); + normals.push( normal.x, normal.y, normal.z ); + + // uv + + 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 + + indexArray.push( indexRow ); + + } + + // 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 + + indices.push( a, b, d ); + indices.push( b, c, d ); + + // update group counter + + groupCount += 6; + + } + + } + + // add a group to the geometry. this will ensure multi material support + + 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; + + const uv = new Vector2(); + 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. + // 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 + + uvs.push( 0.5, 0.5 ); + + // increase index + + index ++; + + } + + // save the index of the last center vertex + const centerIndexEnd = index; + + // 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 + + vertex.x = radius * sinTheta; + vertex.y = halfHeight * sign; + vertex.z = radius * cosTheta; + vertices.push( vertex.x, vertex.y, vertex.z ); + + // normal + + 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 + + index ++; + + } + + // 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 + + scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 ); + + // 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 { + + constructor( radius = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) { + + super( 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); + + this.type = 'ConeGeometry'; + + this.parameters = { + radius: radius, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + 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 { + + constructor( vertices = [], indices = [], radius = 1, detail = 0 ) { + + super(); + + this.type = 'PolyhedronGeometry'; + + this.parameters = { + vertices: vertices, + indices: indices, + radius: radius, + detail: detail + }; + + // default buffer data + + const vertexBuffer = []; + const uvBuffer = []; + + // the subdivision creates the vertex buffer data + + subdivide( detail ); + + // all vertices should lie on a conceptual sphere with a given radius + + applyRadius( radius ); + + // 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 + + function subdivide( detail ) { + + const a = new Vector3(); + const b = new Vector3(); + 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 + + 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 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; + + } else { + + v[ i ][ j ] = aj.clone().lerp( bj, j / rows ); + + } + + } + + } + + // 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 ] ); + pushVertex( v[ i ][ k ] ); + + } else { + + pushVertex( v[ i ][ k + 1 ] ); + pushVertex( v[ i + 1 ][ k + 1 ] ); + pushVertex( v[ i + 1 ][ k ] ); + + } + + } + + } + + } + + function applyRadius( radius ) { + + 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 ]; + vertex.y = vertexBuffer[ i + 1 ]; + vertex.z = vertexBuffer[ i + 2 ]; + + vertex.normalize().multiplyScalar( radius ); + + vertexBuffer[ i + 0 ] = vertex.x; + vertexBuffer[ i + 1 ] = vertex.y; + vertexBuffer[ i + 2 ] = vertex.z; + + } + + } + + 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 ]; + vertex.z = vertexBuffer[ i + 2 ]; + + const u = azimuth( vertex ) / 2 / Math.PI + 0.5; + 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 + + if ( max > 0.9 && min < 0.1 ) { + + if ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1; + if ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1; + if ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1; + + } + + } + + } + + function pushVertex( vertex ) { + + vertexBuffer.push( vertex.x, vertex.y, vertex.z ); + + } + + function getVertexByIndex( index, vertex ) { + + 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(); + const c = new Vector3(); + + const centroid = new Vector3(); + + 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 ] ); + c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] ); + + uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] ); + uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] ); + uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] ); + + centroid.copy( a ).add( b ).add( c ).divideScalar( 3 ); + + const azi = azimuth( centroid ); + + correctUV( uvA, j + 0, a, azi ); + correctUV( uvB, j + 2, b, azi ); + 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. + + function azimuth( vector ) { + + return Math.atan2( vector.z, - vector.x ); + + } + + + // Angle above the XZ plane. + + function inclination( vector ) { + + return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) ); + + } + + } + + 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/φ) + - 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 ); + + this.type = 'DodecahedronGeometry'; + + this.parameters = { + radius: radius, + 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(); + + this.type = 'EdgesGeometry'; + + this.parameters = { + geometry: geometry, + thresholdAngle: thresholdAngle + }; + + if ( geometry !== null ) { + + const precisionPoints = 4; + const precision = Math.pow( 10, precisionPoints ); + const thresholdDot = Math.cos( DEG2RAD * thresholdAngle ); + + const indexAttr = geometry.getIndex(); + const positionAttr = geometry.getAttribute( 'position' ); + const indexCount = indexAttr ? indexAttr.count : positionAttr.count; + + const indexArr = [ 0, 0, 0 ]; + const vertKeys = [ 'a', 'b', 'c' ]; + const hashes = new Array( 3 ); + + const edgeData = {}; + const vertices = []; + for ( let i = 0; i < indexCount; i += 3 ) { + + if ( indexAttr ) { + + indexArr[ 0 ] = indexAttr.getX( i ); + indexArr[ 1 ] = indexAttr.getX( i + 1 ); + indexArr[ 2 ] = indexAttr.getX( i + 2 ); + + } else { + + indexArr[ 0 ] = i; + indexArr[ 1 ] = i + 1; + indexArr[ 2 ] = i + 2; + + } + + const { a, b, c } = _triangle; + a.fromBufferAttribute( positionAttr, indexArr[ 0 ] ); + b.fromBufferAttribute( positionAttr, indexArr[ 1 ] ); + c.fromBufferAttribute( positionAttr, indexArr[ 2 ] ); + _triangle.getNormal( _normal ); + + // 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 + if ( hashes[ 0 ] === hashes[ 1 ] || hashes[ 1 ] === hashes[ 2 ] || hashes[ 2 ] === hashes[ 0 ] ) { + + continue; + + } + + // 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; + const vecHash0 = hashes[ j ]; + const vecHash1 = hashes[ jNext ]; + const v0 = _triangle[ vertKeys[ j ] ]; + 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. + if ( _normal.dot( edgeData[ reverseHash ].normal ) <= thresholdDot ) { + + vertices.push( v0.x, v0.y, v0.z ); + vertices.push( v1.x, v1.y, v1.z ); + + } + + edgeData[ reverseHash ] = null; + + } else if ( ! ( hash in edgeData ) ) { + + // if we've already got an edge here then skip adding a new one + edgeData[ hash ] = { + + index0: indexArr[ j ], + index1: indexArr[ jNext ], + normal: _normal.clone(), + + }; + + } + + } + + } + + // 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 { + + constructor( points ) { + + super( points ); + + this.uuid = generateUUID(); + + 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) + + extractPoints( divisions ) { + + return { + + shape: this.getPoints( divisions ), + 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.4) + */ + + const Earcut = { + + triangulate: function ( data, holeIndices, dim = 2 ) { + + const hasHoles = holeIndices && holeIndices.length; + const outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length; + let outerNode = linkedList( data, 0, outerLen, dim, true ); + 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 ( 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 ]; + if ( x < minX ) minX = x; + if ( y < minY ) minY = y; + if ( x > maxX ) maxX = x; + if ( y > maxY ) maxY = y; + + } + + // minX, minY and invSize are later used to transform coords into integers for z-order calculation + invSize = Math.max( maxX - minX, maxY - minY ); + invSize = invSize !== 0 ? 32767 / invSize : 0; + + } + + earcutLinked( outerNode, triangles, dim, minX, minY, invSize, 0 ); + + return triangles; + + } + + }; + + // 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 + function filterPoints( start, end ) { + + if ( ! start ) return start; + if ( ! end ) end = start; + + let p = start, + again; + do { + + again = false; + + if ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) { + + removeNode( p ); + p = end = p.prev; + if ( p === p.next ) break; + again = true; + + } else { + + p = p.next; + + } + + } while ( again || p !== end ); + + return end; + + } + + // 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 ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize ); + + let stop = ear, + 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 | 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; + + // 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 + + } else if ( pass === 1 ) { + + ear = cureLocalIntersections( filterPoints( ear ), triangles, dim ); + earcutLinked( ear, triangles, dim, minX, minY, invSize, 2 ); + + // as a last resort, try splitting the remaining polygon into two + + } else if ( pass === 2 ) { + + splitEarcut( ear, triangles, dim, minX, minY, invSize ); + + } + + break; + + } + + } + + } + + // check whether a polygon node forms a valid ear with adjacent nodes + function isEar( ear ) { + + const a = ear.prev, + b = ear, + c = ear.next; + + if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear + + // now make sure we don't have other points inside the potential ear + 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 ); + + 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; + + 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 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 + while ( p && p.z >= minZ && n && n.z <= maxZ ) { + + 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.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 + while ( p && p.z >= minZ ) { + + 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 + while ( n && n.z <= maxZ ) { + + 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 + function cureLocalIntersections( start, triangles, dim ) { + + let p = start; + do { + + const a = p.prev, + 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 | 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 + 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 + a = filterPoints( a, a.next ); + c = filterPoints( c, c.next ); + + // 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 + 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; + list = linkedList( data, start, end, dim, false ); + if ( list === list.next ) list.steiner = true; + queue.push( getLeftmost( list ) ); + + } + + queue.sort( compareX ); + + // process holes from left to right + for ( i = 0; i < queue.length; i ++ ) { + + 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 + function eliminateHole( hole, outerNode ) { + + const bridge = findHoleBridge( hole, outerNode ); + if ( ! bridge ) { + + 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, + 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; + 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; + + // 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; + let tanMin = Infinity, 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 + + if ( locallyInside( p, hole ) && ( tan < tanMin || ( tan === tanMin && ( p.x > m.x || ( p.x === m.x && sectorContainsSector( m, p ) ) ) ) ) ) { + + m = p; + tanMin = tan; + + } + + } + + p = p.next; + + } while ( p !== stop ); + + return m; + + } + + // 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 + function indexCurve( start, minX, minY, invSize ) { + + let p = start; + do { + + 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 + function sortLinked( list ) { + + let i, 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; + p = p.nextZ; + pSize --; + + } else { + + e = q; + 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 + function zOrder( x, y, minX, minY, invSize ) { + + // coords are transformed into non-negative 15-bit integer range + 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; + x = ( x | ( x << 1 ) ) & 0x55555555; + + y = ( y | ( y << 8 ) ) & 0x00FF00FF; + y = ( y | ( y << 4 ) ) & 0x0F0F0F0F; + y = ( y | ( y << 2 ) ) & 0x33333333; + y = ( y | ( y << 1 ) ) & 0x55555555; + + return x | ( y << 1 ); + + } + + // find the leftmost node of a polygon ring + function getLeftmost( start ) { + + let p = start, + leftmost = start; + do { + + if ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) leftmost = p; + p = p.next; + + } while ( p !== start ); + + return leftmost; + + } + + // 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 ) && + ( 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 ) && // 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 + 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 + function equals( p1, p2 ) { + + return p1.x === p2.x && p1.y === p2.y; + + } + + // 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 ) ); + const o3 = sign( area( p2, q2, p1 ) ); + const o4 = sign( area( p2, q2, q1 ) ); + + 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 + 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 + 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 + 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 + function middleInside( a, b ) { + + let p = a, + inside = false; + const px = ( a.x + b.x ) / 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 + 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; + + a.next = b; + b.prev = a; + + a2.next = an; + an.prev = a2; + + b2.next = a2; + a2.prev = b2; + + bp.next = b2; + b2.prev = bp; + + return b2; + + } + + // create a node and optionally link it with previous one (in a circular doubly linked list) + function insertNode( i, x, y, last ) { + + const p = new Node( i, x, y ); + + if ( ! last ) { + + p.prev = p; + p.next = p; + + } else { + + p.next = last.next; + p.prev = 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.x = x; + this.y = y; + + // previous and next vertex nodes in a polygon ring + this.prev = null; + this.next = null; + + // 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.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 ); + + // + + 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 ); + + // + + 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 ); + vertices.push( contour[ i ].y ); + + } + + } + + /** + * Creates extruded geometry from a path shape. + * + * parameters = { + * + * curveSegments: , // number of points on the curves + * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too + * depth: , // Depth to extrude the shape + * + * bevelEnabled: , // turn on bevel + * bevelThickness: , // how deep into the original shape bevel goes + * bevelSize: , // how far from shape outline (including bevelOffset) is bevel + * bevelOffset: , // how far from shape outline does bevel start + * bevelSegments: , // number of bevel layers + * + * extrudePath: // curve to extrude shape along + * + * UVGenerator: // object that provides UV generator functions + * + * } + */ + + 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(); + + this.type = 'ExtrudeGeometry'; + + this.parameters = { + shapes: shapes, + options: options + }; + + shapes = Array.isArray( shapes ) ? shapes : [ shapes ]; + + 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 + + this.setAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) ); + + this.computeVertexNormals(); + + // functions + + function addShape( shape ) { + + const placeholder = []; + + // options + + const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; + const steps = options.steps !== undefined ? options.steps : 1; + const depth = options.depth !== undefined ? options.depth : 1; + + let bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; + let bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 0.2; + let bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 0.1; + 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; + + // + + let extrudePts, 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); + + binormal = new Vector3(); + normal = new Vector3(); + position2 = new Vector3(); + + } + + // Safeguards if bevels are not enabled + + if ( ! bevelEnabled ) { + + bevelSegments = 0; + bevelThickness = 0; + bevelSize = 0; + bevelOffset = 0; + + } + + // 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 ... + + 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 + + for ( let h = 0, hl = holes.length; h < hl; h ++ ) { + + 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 + + + function getBevelVec( inPt, inPrev, inNext ) { + + // computes for inPt the corresponding point inPt' on a new contour + // shifted by 1 unit (length of normalized vector) to the left + // if we walk along contour clockwise, this new contour is outside the old one + // + // inPt' is the intersection of the two lines parallel to the two + // adjacent edges of inPt at a distance of 1 unit on the left side. + + 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; + 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 + 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 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 sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y - + ( ptNextShift_y - ptPrevShift_y ) * v_next_x ) / + ( v_prev_x * v_next_y - v_prev_y * v_next_x ); + + // vector from inPt to intersection point + + v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x ); + v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y ); + + // Don't normalize!, otherwise sharp corners become ugly + // but prevent crazy spikes + 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 { + + shrink_by = Math.sqrt( v_trans_lensq / 2 ); + + } + + } else { + + // handle special case of collinear edges + + let direction_eq = false; // assumes: opposite + + if ( v_prev_x > Number.EPSILON ) { + + if ( v_next_x > Number.EPSILON ) { + + direction_eq = true; + + } + + } else { + + if ( v_prev_x < - Number.EPSILON ) { + + if ( v_next_x < - Number.EPSILON ) { + + direction_eq = true; + + } + + } else { + + if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) { + + direction_eq = true; + + } + + } + + } + + if ( direction_eq ) { + + // console.log("Warning: lines are a straight sequence"); + v_trans_x = - v_prev_y; + v_trans_y = v_prev_x; + shrink_by = Math.sqrt( v_prev_lensq ); + + } else { + + // console.log("Warning: lines are a straight spike"); + v_trans_x = v_prev_x; + v_trans_y = v_prev_y; + shrink_by = Math.sqrt( v_prev_lensq / 2 ); + + } + + } + + 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) + // console.log('i,j,k', i, j , k) + + contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); + + } + + const holesMovements = []; + let oneHoleMovements, 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) + oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); + + } + + holesMovements.push( oneHoleMovements ); + verticesMovements = verticesMovements.concat( oneHoleMovements ); + + } + + + // Loop bevelSegments, 1 for the front, 1 for the back + + for ( 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 + + 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 + + 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; + + // 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 + + 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 ++ ) { + 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 + + 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 + + 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 { + + v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z ); + + } + + } + + } + + } + + /* Faces */ + + // Top and bottom faces + + buildLidFaces(); + + // Sides faces + + buildSideFaces(); + + + ///// Internal functions + + function buildLidFaces() { + + const start = verticesArray.length / 3; + + if ( bevelEnabled ) { + + let layer = 0; // steps + 1 + let offset = vlen * layer; + + // 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 + + for ( let i = 0; i < flen; i ++ ) { + + const face = faces[ i ]; + f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset ); + + } + + } else { + + // Bottom faces + + for ( let i = 0; i < flen; i ++ ) { + + const face = faces[ i ]; + f3( face[ 2 ], face[ 1 ], face[ 0 ] ); + + } + + // 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 + + 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 + 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); + + 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; + + 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 ); + addVertex( c ); + + const nextIndex = verticesArray.length / 3; + const uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); + + addUV( uvs[ 0 ] ); + addUV( uvs[ 1 ] ); + addUV( uvs[ 2 ] ); + + } + + function f4( a, b, c, d ) { + + addVertex( a ); + addVertex( b ); + addVertex( d ); + + addVertex( b ); + addVertex( c ); + addVertex( d ); + + + const nextIndex = verticesArray.length / 3; + const uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); + + addUV( uvs[ 0 ] ); + addUV( uvs[ 1 ] ); + addUV( uvs[ 3 ] ); + + addUV( uvs[ 1 ] ); + addUV( uvs[ 2 ] ); + addUV( uvs[ 3 ] ); + + } + + function addVertex( index ) { + + verticesArray.push( placeholder[ index * 3 + 0 ] ); + verticesArray.push( placeholder[ index * 3 + 1 ] ); + verticesArray.push( placeholder[ index * 3 + 2 ] ); + + } + + + function addUV( vector2 ) { + + uvArray.push( vector2.x ); + uvArray.push( vector2.y ); + + } + + } + + } + + 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 ]; + const a_y = vertices[ indexA * 3 + 1 ]; + const b_x = vertices[ indexB * 3 ]; + const b_y = vertices[ indexB * 3 + 1 ]; + const c_x = vertices[ indexC * 3 ]; + const c_y = vertices[ indexC * 3 + 1 ]; + + return [ + new Vector2( a_x, a_y ), + new Vector2( b_x, b_y ), + new Vector2( c_x, c_y ) + ]; + + }, + + generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) { + + const a_x = vertices[ indexA * 3 ]; + const a_y = vertices[ indexA * 3 + 1 ]; + const a_z = vertices[ indexA * 3 + 2 ]; + const b_x = vertices[ indexB * 3 ]; + const b_y = vertices[ indexB * 3 + 1 ]; + const b_z = vertices[ indexB * 3 + 2 ]; + const c_x = vertices[ indexC * 3 ]; + const c_y = vertices[ indexC * 3 + 1 ]; + const c_z = vertices[ indexC * 3 + 2 ]; + 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 { + + return [ + new Vector2( a_y, 1 - a_z ), + new Vector2( b_y, 1 - b_z ), + new Vector2( c_y, 1 - c_z ), + new Vector2( d_y, 1 - d_z ) + ]; + + } + + } + + }; + + 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 ]; + + data.shapes.push( shape.uuid ); + + } + + } else { + + data.shapes.push( shapes.uuid ); + + } + + data.options = Object.assign( {}, options ); + + if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON(); + + return data; + + } + + class IcosahedronGeometry extends PolyhedronGeometry { + + constructor( radius = 1, detail = 0 ) { + + const t = ( 1 + Math.sqrt( 5 ) ) / 2; + + const vertices = [ + - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0, + 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, + t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1 + ]; + + const indices = [ + 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, + 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, + 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, + 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1 + ]; + + super( vertices, indices, radius, detail ); + + this.type = 'IcosahedronGeometry'; + + this.parameters = { + radius: radius, + detail: detail + }; + + } + + static fromJSON( data ) { + + return new IcosahedronGeometry( data.radius, data.detail ); + + } + + } + + class OctahedronGeometry extends PolyhedronGeometry { + + constructor( radius = 1, detail = 0 ) { + + const vertices = [ + 1, 0, 0, - 1, 0, 0, 0, 1, 0, + 0, - 1, 0, 0, 0, 1, 0, 0, - 1 + ]; + + const indices = [ + 0, 2, 4, 0, 4, 3, 0, 3, 5, + 0, 5, 2, 1, 2, 5, 1, 5, 3, + 1, 3, 4, 1, 4, 2 + ]; + + super( vertices, indices, radius, detail ); + + this.type = 'OctahedronGeometry'; + + this.parameters = { + radius: radius, + detail: detail + }; + + } + + static fromJSON( data ) { + + return new OctahedronGeometry( data.radius, data.detail ); + + } + + } + + class RingGeometry extends BufferGeometry { + + constructor( innerRadius = 0.5, outerRadius = 1, thetaSegments = 32, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2 ) { + + super(); + + this.type = 'RingGeometry'; + + this.parameters = { + innerRadius: innerRadius, + outerRadius: outerRadius, + thetaSegments: thetaSegments, + phiSegments: phiSegments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + + thetaSegments = Math.max( 3, thetaSegments ); + phiSegments = Math.max( 1, phiSegments ); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + 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 + + 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 + + vertex.x = radius * Math.cos( segment ); + vertex.y = radius * Math.sin( segment ); + + vertices.push( vertex.x, vertex.y, vertex.z ); + + // normal + + normals.push( 0, 0, 1 ); + + // 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 + + radius += radiusStep; + + } + + // 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 + + indices.push( a, b, d ); + indices.push( b, c, d ); + + } + + } + + // 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 { + + constructor( shapes = new Shape( [ new Vector2( 0, 0.5 ), new Vector2( - 0.5, - 0.5 ), new Vector2( 0.5, - 0.5 ) ] ), curveSegments = 12 ) { + + super(); + + this.type = 'ShapeGeometry'; + + this.parameters = { + shapes: shapes, + curveSegments: curveSegments + }; + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + + // helper variables + + let groupStart = 0; + let groupCount = 0; + + // allow single and array values for "shapes" parameter + + if ( Array.isArray( shapes ) === false ) { + + addShape( shapes ); + + } else { + + for ( let i = 0; i < shapes.length; i ++ ) { + + addShape( shapes[ i ] ); + + this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support + + groupStart += groupCount; + groupCount = 0; + + } + + } + + // 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 + + 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 + + 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 ); + + // 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 + + 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 + + } + + // indices + + for ( let i = 0, l = faces.length; i < l; i ++ ) { + + const face = faces[ i ]; + + const a = face[ 0 ] + indexOffset; + const b = face[ 1 ] + indexOffset; + const c = face[ 2 ] + indexOffset; + + indices.push( a, b, c ); + groupCount += 3; + + } + + } + + } + + 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 ]; + + data.shapes.push( shape.uuid ); + + } + + } else { + + data.shapes.push( shapes.uuid ); + + } + + return data; + + } + + class SphereGeometry extends BufferGeometry { + + constructor( radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI ) { + + super(); + + this.type = 'SphereGeometry'; + + this.parameters = { + radius: radius, + widthSegments: widthSegments, + heightSegments: heightSegments, + phiStart: phiStart, + phiLength: phiLength, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + + widthSegments = Math.max( 3, Math.floor( widthSegments ) ); + heightSegments = Math.max( 2, Math.floor( heightSegments ) ); + + const thetaEnd = Math.min( thetaStart + thetaLength, Math.PI ); + + let index = 0; + const grid = []; + + const vertex = new Vector3(); + const normal = new Vector3(); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + 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 + + 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 + + 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 + + normal.copy( vertex ).normalize(); + normals.push( normal.x, normal.y, normal.z ); + + // uv + + uvs.push( u + uOffset, 1 - v ); + + verticesRow.push( index ++ ); + + } + + grid.push( verticesRow ); + + } + + // indices + + for ( let iy = 0; iy < heightSegments; iy ++ ) { + + for ( let ix = 0; ix < widthSegments; ix ++ ) { + + const a = grid[ iy ][ ix + 1 ]; + const b = grid[ iy ][ ix ]; + const c = grid[ iy + 1 ][ ix ]; + const d = grid[ iy + 1 ][ ix + 1 ]; + + if ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d ); + if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d ); + + } + + } + + // build geometry + + this.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 { + + constructor( radius = 1, detail = 0 ) { + + const vertices = [ + 1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1 + ]; + + const indices = [ + 2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1 + ]; + + super( vertices, indices, radius, detail ); + + this.type = 'TetrahedronGeometry'; + + this.parameters = { + radius: radius, + detail: detail + }; + + } + + static fromJSON( data ) { + + return new TetrahedronGeometry( data.radius, data.detail ); + + } + + } + + class TorusGeometry extends BufferGeometry { + + constructor( radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48, arc = Math.PI * 2 ) { + + super(); + + this.type = 'TorusGeometry'; + + this.parameters = { + radius: radius, + tube: tube, + radialSegments: radialSegments, + tubularSegments: tubularSegments, + arc: arc + }; + + radialSegments = Math.floor( radialSegments ); + tubularSegments = Math.floor( tubularSegments ); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + + // helper variables + + const center = new Vector3(); + const vertex = new Vector3(); + 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 + + vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u ); + vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u ); + vertex.z = tube * Math.sin( v ); + + vertices.push( vertex.x, vertex.y, vertex.z ); + + // normal + + center.x = radius * Math.cos( u ); + center.y = radius * Math.sin( u ); + normal.subVectors( vertex, center ).normalize(); + + normals.push( normal.x, normal.y, normal.z ); + + // uv + + uvs.push( i / tubularSegments ); + uvs.push( j / radialSegments ); + + } + + } + + // generate indices + + 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 + + indices.push( a, b, d ); + indices.push( b, c, d ); + + } + + } + + // 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 { + + constructor( radius = 1, tube = 0.4, tubularSegments = 64, radialSegments = 8, p = 2, q = 3 ) { + + super(); + + this.type = 'TorusKnotGeometry'; + + this.parameters = { + radius: radius, + tube: tube, + tubularSegments: tubularSegments, + radialSegments: radialSegments, + p: p, + q: q + }; + + tubularSegments = Math.floor( tubularSegments ); + radialSegments = Math.floor( radialSegments ); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + + // helper variables + + const vertex = new Vector3(); + const normal = new Vector3(); + + const P1 = new Vector3(); + const P2 = new Vector3(); + + const B = new Vector3(); + const T = new Vector3(); + 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. + // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions + + calculatePositionOnCurve( u, p, q, radius, P1 ); + calculatePositionOnCurve( u + 0.01, p, q, radius, P2 ); + + // calculate orthonormal basis + + T.subVectors( P2, P1 ); + N.addVectors( P2, P1 ); + B.crossVectors( T, N ); + N.crossVectors( B, T ); + + // normalize B, N. T can be ignored, we don't use it + + B.normalize(); + N.normalize(); + + for ( 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. + // 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) + + normal.subVectors( vertex, P1 ).normalize(); + + normals.push( normal.x, normal.y, normal.z ); + + // uv + + uvs.push( i / tubularSegments ); + uvs.push( j / radialSegments ); + + } + + } + + // 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 + + indices.push( a, b, d ); + indices.push( b, c, d ); + + } + + } + + // 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 + + function calculatePositionOnCurve( u, p, q, radius, position ) { + + const cu = Math.cos( u ); + const su = Math.sin( u ); + const quOverP = q / p * u; + const cs = Math.cos( quOverP ); + + position.x = radius * ( 2 + cs ) * 0.5 * cu; + position.y = radius * ( 2 + cs ) * su * 0.5; + position.z = radius * Math.sin( quOverP ) * 0.5; + + } + + } + + static fromJSON( data ) { + + return new TorusKnotGeometry( data.radius, data.tube, data.tubularSegments, data.radialSegments, data.p, data.q ); + + } + + } + + class TubeGeometry extends BufferGeometry { + + constructor( path = new QuadraticBezierCurve3( new Vector3( - 1, - 1, 0 ), new Vector3( - 1, 1, 0 ), new Vector3( 1, 1, 0 ) ), tubularSegments = 64, radius = 1, radialSegments = 8, closed = false ) { + + super(); + + this.type = 'TubeGeometry'; + + this.parameters = { + path: path, + tubularSegments: tubularSegments, + radius: radius, + radialSegments: radialSegments, + closed: closed + }; + + const frames = path.computeFrenetFrames( tubularSegments, closed ); + + // expose internals + + this.tangents = frames.tangents; + this.normals = frames.normals; + this.binormals = frames.binormals; + + // helper variables + + const vertex = new Vector3(); + const normal = new Vector3(); + const uv = new Vector2(); + let P = new Vector3(); + + // buffer + + const vertices = []; + const normals = []; + const uvs = []; + const indices = []; + + // create buffer data + + generateBufferData(); + + // 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 + + 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 + // 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 ); + + // uvs are generated in a separate function. + // this makes it easy compute correct values for closed geometries + + 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 + + const N = frames.normals[ i ]; + 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 + + 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 + + vertex.x = P.x + radius * normal.x; + vertex.y = P.y + radius * normal.y; + vertex.z = P.z + radius * normal.z; + + vertices.push( vertex.x, vertex.y, vertex.z ); + + } + + } + + 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 + + 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 ++ ) { + + uv.x = i / tubularSegments; + uv.y = j / radialSegments; + + uvs.push( uv.x, uv.y ); + + } + + } + + } + + } + + 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 { + + constructor( geometry = null ) { + + super(); + + this.type = 'WireframeGeometry'; + + this.parameters = { + geometry: geometry + }; + + if ( geometry !== null ) { + + // buffer + + const vertices = []; + 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 + + 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 ); + + } + + } + + } + + } + + } else { + + // non-indexed BufferGeometry + + 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 + + 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 + + if ( edges.has( hash1 ) === true || edges.has( hash2 ) === true ) { + + return false; + + } else { + + edges.add( hash1 ); + edges.add( hash2 ); + return true; + + } + + } + + var Geometries = /*#__PURE__*/Object.freeze({ + __proto__: null, + BoxGeometry: BoxGeometry, + CapsuleGeometry: CapsuleGeometry, + CircleGeometry: CircleGeometry, + ConeGeometry: ConeGeometry, + CylinderGeometry: CylinderGeometry, + DodecahedronGeometry: DodecahedronGeometry, + EdgesGeometry: EdgesGeometry, + ExtrudeGeometry: ExtrudeGeometry, + IcosahedronGeometry: IcosahedronGeometry, + LatheGeometry: LatheGeometry, + OctahedronGeometry: OctahedronGeometry, + PlaneGeometry: PlaneGeometry, + PolyhedronGeometry: PolyhedronGeometry, + RingGeometry: RingGeometry, + ShapeGeometry: ShapeGeometry, + SphereGeometry: SphereGeometry, + TetrahedronGeometry: TetrahedronGeometry, + TorusGeometry: TorusGeometry, + TorusKnotGeometry: TorusKnotGeometry, + TubeGeometry: TubeGeometry, + WireframeGeometry: WireframeGeometry + }); + + class ShadowMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isShadowMaterial = true; + + this.type = 'ShadowMaterial'; + + this.color = new Color( 0x000000 ); + this.transparent = true; + + 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 { + + constructor( parameters ) { + + super( parameters ); + + this.isRawShaderMaterial = true; + + this.type = 'RawShaderMaterial'; + + } + + } + + class MeshStandardMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshStandardMaterial = true; + + this.defines = { 'STANDARD': '' }; + + this.type = 'MeshStandardMaterial'; + + this.color = new Color( 0xffffff ); // diffuse + this.roughness = 1.0; + this.metalness = 0.0; + + this.map = null; + + this.lightMap = null; + this.lightMapIntensity = 1.0; + + this.aoMap = null; + this.aoMapIntensity = 1.0; + + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.roughnessMap = null; + + this.metalnessMap = null; + + this.alphaMap = null; + + this.envMap = null; + this.envMapIntensity = 1.0; + + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + + this.flatShading = false; + + this.fog = true; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.defines = { 'STANDARD': '' }; + + this.color.copy( source.color ); + this.roughness = source.roughness; + this.metalness = source.metalness; + + this.map = source.map; + + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + + this.emissive.copy( source.emissive ); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; + + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.roughnessMap = source.roughnessMap; + + this.metalnessMap = source.metalnessMap; + + this.alphaMap = source.alphaMap; + + this.envMap = source.envMap; + this.envMapIntensity = source.envMapIntensity; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + + this.flatShading = source.flatShading; + + this.fog = source.fog; + + return this; + + } + + } + + class MeshPhysicalMaterial extends MeshStandardMaterial { + + constructor( parameters ) { + + super(); + + this.isMeshPhysicalMaterial = true; + + this.defines = { + + 'STANDARD': '', + 'PHYSICAL': '' + + }; + + this.type = 'MeshPhysicalMaterial'; + + this.clearcoatMap = null; + this.clearcoatRoughness = 0.0; + this.clearcoatRoughnessMap = null; + this.clearcoatNormalScale = new Vector2( 1, 1 ); + this.clearcoatNormalMap = null; + + this.ior = 1.5; + + Object.defineProperty( this, 'reflectivity', { + get: function () { + + return ( clamp( 2.5 * ( this.ior - 1 ) / ( this.ior + 1 ), 0, 1 ) ); + + }, + set: function ( reflectivity ) { + + this.ior = ( 1 + 0.4 * reflectivity ) / ( 1 - 0.4 * reflectivity ); + + } + } ); + + this.iridescenceMap = null; + this.iridescenceIOR = 1.3; + this.iridescenceThicknessRange = [ 100, 400 ]; + this.iridescenceThicknessMap = null; + + this.sheenColor = new Color( 0x000000 ); + this.sheenColorMap = null; + this.sheenRoughness = 1.0; + this.sheenRoughnessMap = null; + + this.transmissionMap = null; + + this.thickness = 0; + this.thicknessMap = null; + this.attenuationDistance = Infinity; + this.attenuationColor = new Color( 1, 1, 1 ); + + this.specularIntensity = 1.0; + this.specularIntensityMap = null; + this.specularColor = new Color( 1, 1, 1 ); + this.specularColorMap = null; + + this._sheen = 0.0; + this._clearcoat = 0; + this._iridescence = 0; + 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 = { + + 'STANDARD': '', + 'PHYSICAL': '' + + }; + + this.clearcoat = source.clearcoat; + this.clearcoatMap = source.clearcoatMap; + this.clearcoatRoughness = source.clearcoatRoughness; + this.clearcoatRoughnessMap = source.clearcoatRoughnessMap; + this.clearcoatNormalMap = source.clearcoatNormalMap; + this.clearcoatNormalScale.copy( source.clearcoatNormalScale ); + + this.ior = source.ior; + + this.iridescence = source.iridescence; + this.iridescenceMap = source.iridescenceMap; + this.iridescenceIOR = source.iridescenceIOR; + this.iridescenceThicknessRange = [ ...source.iridescenceThicknessRange ]; + this.iridescenceThicknessMap = source.iridescenceThicknessMap; + + this.sheen = source.sheen; + this.sheenColor.copy( source.sheenColor ); + this.sheenColorMap = source.sheenColorMap; + this.sheenRoughness = source.sheenRoughness; + this.sheenRoughnessMap = source.sheenRoughnessMap; + + this.transmission = source.transmission; + this.transmissionMap = source.transmissionMap; + + this.thickness = source.thickness; + this.thicknessMap = source.thicknessMap; + this.attenuationDistance = source.attenuationDistance; + this.attenuationColor.copy( source.attenuationColor ); + + this.specularIntensity = source.specularIntensity; + this.specularIntensityMap = source.specularIntensityMap; + this.specularColor.copy( source.specularColor ); + this.specularColorMap = source.specularColorMap; + + return this; + + } + + } + + class MeshPhongMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshPhongMaterial = true; + + this.type = 'MeshPhongMaterial'; + + this.color = new Color( 0xffffff ); // diffuse + this.specular = new Color( 0x111111 ); + this.shininess = 30; + + this.map = null; + + this.lightMap = null; + this.lightMapIntensity = 1.0; + + this.aoMap = null; + this.aoMapIntensity = 1.0; + + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.specularMap = null; + + this.alphaMap = null; + + this.envMap = null; + this.combine = MultiplyOperation; + this.reflectivity = 1; + this.refractionRatio = 0.98; + + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + + this.flatShading = false; + + this.fog = true; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.color.copy( source.color ); + this.specular.copy( source.specular ); + this.shininess = source.shininess; + + this.map = source.map; + + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + + this.emissive.copy( source.emissive ); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; + + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.specularMap = source.specularMap; + + this.alphaMap = source.alphaMap; + + this.envMap = source.envMap; + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + + this.flatShading = source.flatShading; + + this.fog = source.fog; + + return this; + + } + + } + + class MeshToonMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshToonMaterial = true; + + this.defines = { 'TOON': '' }; + + this.type = 'MeshToonMaterial'; + + this.color = new Color( 0xffffff ); + + this.map = null; + this.gradientMap = null; + + this.lightMap = null; + this.lightMapIntensity = 1.0; + + this.aoMap = null; + this.aoMapIntensity = 1.0; + + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.alphaMap = null; + + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + + this.fog = true; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.color.copy( source.color ); + + this.map = source.map; + this.gradientMap = source.gradientMap; + + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + + this.emissive.copy( source.emissive ); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; + + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.alphaMap = source.alphaMap; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + + this.fog = source.fog; + + return this; + + } + + } + + class MeshNormalMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshNormalMaterial = true; + + this.type = 'MeshNormalMaterial'; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.wireframe = false; + this.wireframeLinewidth = 1; + + this.flatShading = false; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + + this.flatShading = source.flatShading; + + return this; + + } + + } + + class MeshLambertMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshLambertMaterial = true; + + this.type = 'MeshLambertMaterial'; + + this.color = new Color( 0xffffff ); // diffuse + + this.map = null; + + this.lightMap = null; + this.lightMapIntensity = 1.0; + + this.aoMap = null; + this.aoMapIntensity = 1.0; + + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.specularMap = null; + + this.alphaMap = null; + + this.envMap = null; + this.combine = MultiplyOperation; + this.reflectivity = 1; + this.refractionRatio = 0.98; + + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + + this.flatShading = false; + + this.fog = true; + + 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.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.specularMap = source.specularMap; + + this.alphaMap = source.alphaMap; + + this.envMap = source.envMap; + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + + this.flatShading = source.flatShading; + + this.fog = source.fog; + + return this; + + } + + } + + class MeshMatcapMaterial extends Material { + + constructor( parameters ) { + + super(); + + this.isMeshMatcapMaterial = true; + + this.defines = { 'MATCAP': '' }; + + this.type = 'MeshMatcapMaterial'; + + this.color = new Color( 0xffffff ); // diffuse + + this.matcap = null; + + this.map = null; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.alphaMap = null; + + this.flatShading = false; + + this.fog = true; + + this.setValues( parameters ); + + } + + + copy( source ) { + + super.copy( source ); + + this.defines = { 'MATCAP': '' }; + + this.color.copy( source.color ); + + this.matcap = source.matcap; + + this.map = source.map; + + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.alphaMap = source.alphaMap; + + this.flatShading = source.flatShading; + + this.fog = source.fog; + + return this; + + } + + } + + class LineDashedMaterial extends LineBasicMaterial { + + constructor( parameters ) { + + super(); + + this.isLineDashedMaterial = true; + + this.type = 'LineDashedMaterial'; + + this.scale = 1; + this.dashSize = 3; + this.gapSize = 1; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.scale = source.scale; + this.dashSize = source.dashSize; + 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 + function convertArray( array, type, forceClone ) { + + 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 + + } + + return Array.prototype.slice.call( array ); // create Array + + } + + function isTypedArray( object ) { + + return ArrayBuffer.isView( object ) && + ! ( object instanceof DataView ); + + } + + // 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 + 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 flattenJSON( jsonKeys, times, values, valuePropertyName ) { + + let i = 1, key = jsonKeys[ 0 ]; + + while ( key !== undefined && key[ valuePropertyName ] === undefined ) { + + key = jsonKeys[ i ++ ]; + + } + + if ( key === undefined ) return; // no data + + let value = key[ valuePropertyName ]; + if ( value === undefined ) return; // no data + + if ( Array.isArray( value ) ) { + + do { + + value = key[ valuePropertyName ]; + + if ( value !== undefined ) { + + times.push( key.time ); + values.push.apply( values, value ); // push all elements + + } + + key = jsonKeys[ i ++ ]; + + } 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; + + // 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 + + 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 + for ( let i = 0; i < numTracks; ++ i ) { + + const referenceTrack = referenceClip.tracks[ i ]; + const referenceTrackType = referenceTrack.ValueTypeName; + + // 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 + if ( referenceTime <= referenceTrack.times[ 0 ] ) { + + // Reference frame is earlier than the first keyframe, so just use the first keyframe + const startIndex = referenceOffset; + const endIndex = referenceValueSize - referenceOffset; + referenceValue = arraySlice( referenceTrack.values, startIndex, endIndex ); + + } else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) { + + // Reference frame is after the last keyframe, so just use the last keyframe + const startIndex = lastIndex * referenceValueSize + referenceOffset; + const endIndex = startIndex + referenceValueSize - referenceOffset; + referenceValue = arraySlice( referenceTrack.values, startIndex, endIndex ); + + } else { + + // Interpolate to the reference value + const interpolant = referenceTrack.createInterpolant(); + const startIndex = referenceOffset; + const endIndex = referenceValueSize - referenceOffset; + interpolant.evaluate( referenceTime ); + referenceValue = arraySlice( interpolant.resultBuffer, startIndex, endIndex ); + + } + + // 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 + + 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 + for ( let k = 0; k < valueEnd; ++ k ) { + + targetTrack.values[ valueStart + k ] -= referenceValue[ k ]; + + } + + } + + } + + } + + targetClip.blendMode = AdditiveAnimationBlendMode; + + return targetClip; + + } + + var AnimationUtils = /*#__PURE__*/Object.freeze({ + __proto__: null, + arraySlice: arraySlice, + convertArray: convertArray, + flattenJSON: flattenJSON, + getKeyframeOrder: getKeyframeOrder, + isTypedArray: isTypedArray, + makeClipAdditive: makeClipAdditive, + sortedArray: sortedArray, + subclip: subclip + }); + + /** + * Abstract base class of interpolants over parametric samples. + * + * The parameter domain is one dimensional, typically the time or a path + * along a curve defined by the data. + * + * The sample values can have any dimensionality and derived classes may + * apply special interpretations to the data. + * + * This class provides the interval seek in a Template Method, deferring + * the actual interpolation to derived classes. + * + * Time complexity is O(1) for linear access crossing at most two points + * and O(log N) for random access, where N is the number of positions. + * + * References: + * + * http://www.oodesign.com/template-method-pattern.html + * + */ + + class Interpolant { + + constructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) { + + this.parameterPositions = parameterPositions; + this._cachedIndex = 0; + + this.resultBuffer = resultBuffer !== undefined ? + resultBuffer : new sampleValues.constructor( sampleSize ); + this.sampleValues = sampleValues; + this.valueSize = sampleSize; + + this.settings = null; + this.DefaultSettings_ = {}; + + } + + evaluate( t ) { + + const pp = this.parameterPositions; + let i1 = this._cachedIndex, + t1 = pp[ i1 ], + t0 = pp[ i1 - 1 ]; + + validate_interval: { + + seek: { + + let right; + + linear_scan: { + + //- See http://jsperf.com/comparison-to-undefined/3 + //- slower code: + //- + //- if ( t >= t1 || t1 === undefined ) { + forward_scan: if ( ! ( t < t1 ) ) { + + for ( let giveUpAt = i1 + 2; ; ) { + + if ( t1 === undefined ) { + + 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 + right = pp.length; + break linear_scan; + + } + + //- slower code: + //- if ( t < t0 || t0 === undefined ) { + if ( ! ( t >= t0 ) ) { + + // looping? + + const t1global = pp[ 1 ]; + + if ( t < t1global ) { + + i1 = 2; // + 1, using the scan for the details + t0 = t1global; + + } + + // 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 + right = i1; + i1 = 0; + break linear_scan; + + } + + // the interval is valid + + break validate_interval; + + } // linear scan + + // 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 + + if ( t0 === undefined ) { + + this._cachedIndex = 0; + return this.copySampleValue_( 0 ); + + } + + if ( t1 === undefined ) { + + i1 = pp.length; + this._cachedIndex = i1; + return this.copySampleValue_( i1 - 1 ); + + } + + } // 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; + + for ( let i = 0; i !== stride; ++ i ) { + + result[ i ] = values[ offset + i ]; + + } + + return result; + + } + + // Template methods for derived classes: + + interpolate_( /* i1, t0, t, t1 */ ) { + + throw new Error( 'call to abstract method' ); + // implementations shall return this.resultBuffer + + } + + intervalChanged_( /* i1, t0, t1 */ ) { + + // empty + + } + + } + + /** + * Fast and simple cubic spline interpolant. + * + * It was derived from a Hermitian construction setting the first derivative + * at each sample position to the linear slope between neighboring positions + * over their parameter interval. + */ + + class CubicInterpolant extends Interpolant { + + constructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) { + + super( parameterPositions, sampleValues, sampleSize, resultBuffer ); + + this._weightPrev = - 0; + this._offsetPrev = - 0; + this._weightNext = - 0; + this._offsetNext = - 0; + + this.DefaultSettings_ = { + + endingStart: ZeroCurvatureEnding, + endingEnd: ZeroCurvatureEnding + + }; + + } + + intervalChanged_( i1, t0, t1 ) { + + const pp = this.parameterPositions; + let iPrev = i1 - 2, + iNext = i1 + 1, + + tPrev = pp[ iPrev ], + tNext = pp[ iNext ]; + + if ( tPrev === undefined ) { + + switch ( this.getSettings_().endingStart ) { + + case ZeroSlopeEnding: + + // f'(t0) = 0 + iPrev = i1; + tPrev = 2 * t0 - t1; + + break; + + case 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: + + // f'(tN) = 0 + iNext = i1; + tNext = 2 * t1 - t0; + + break; + + case WrapAroundEnding: + + // use the other end of the curve + iNext = 1; + tNext = t1 + pp[ 1 ] - pp[ 0 ]; + + break; + + default: // ZeroCurvatureEnding + + // f''(tN) = 0, a.k.a. Natural Spline + iNext = i1 - 1; + tNext = t0; + + } + + } + + const halfDt = ( t1 - t0 ) * 0.5, + stride = this.valueSize; + + this._weightPrev = halfDt / ( t0 - tPrev ); + this._weightNext = halfDt / ( tNext - t1 ); + this._offsetPrev = iPrev * stride; + this._offsetNext = iNext * stride; + + } + + interpolate_( 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 + + 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 + + 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; + + for ( let i = 0; i !== stride; ++ i ) { + + result[ i ] = + values[ offset0 + i ] * weight0 + + values[ offset1 + i ] * weight1; + + } + + return result; + + } + + } + + /** + * + * Interpolant that evaluates to the sample value at the position preceding + * the parameter. + */ + + class DiscreteInterpolant extends Interpolant { + + constructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) { + + super( parameterPositions, sampleValues, sampleSize, resultBuffer ); + + } + + interpolate_( i1 /*, t0, t, t1 */ ) { + + return this.copySampleValue_( i1 - 1 ); + + } + + } + + class KeyframeTrack { + + constructor( name, times, values, interpolation ) { + + if ( name === undefined ) throw new Error( 'THREE.KeyframeTrack: track name is undefined' ); + if ( times === undefined || times.length === 0 ) throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + name ); + + this.name = name; + + this.times = 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): + + static toJSON( track ) { + + const trackType = track.constructor; + + let json; + + // derived classes can define a static toJSON method + if ( trackType.toJSON !== this.toJSON ) { + + json = trackType.toJSON( track ); + + } else { + + // by default, we assume the data can be serialized as-is + json = { + + 'name': track.name, + 'times': convertArray( track.times, Array ), + '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 ) { + + this.setInterpolation( this.DefaultInterpolation ); + + } else { + + throw new Error( message ); // fatal, in this case + + } + + } + + 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 + 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( 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 + trim( startTime, endTime ) { + + const times = this.times, + nKeys = times.length; + + let from = 0, + 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 ) { + + // empty tracks are forbidden, so keep at least one keyframe + if ( from >= to ) { + + 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 + 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; + + 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; + break; + + } + + } + + } + + } + + return valid; + + } + + // removes equivalent sequential keys as common in morph target sequences + // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0) + optimize() { + + // 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; + + 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 + + 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; + + for ( let j = 0; j !== stride; ++ j ) { + + const value = values[ offset + j ]; + + if ( value !== values[ offsetP + j ] || + value !== values[ offsetN + j ] ) { + + keep = true; + break; + + } + + } + + } else { + + keep = true; + + } + + } + + // in-place compaction + + if ( keep ) { + + if ( i !== writeIndex ) { + + times[ writeIndex ] = times[ i ]; + + const readOffset = i * stride, + writeOffset = writeIndex * stride; + + for ( let j = 0; j !== stride; ++ j ) { + + values[ writeOffset + j ] = values[ readOffset + j ]; + + } + + } + + ++ writeIndex; + + } + + } + + // 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 ); + + } else { + + 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. + track.createInterpolant = this.createInterpolant; + + return track; + + } + + } + + KeyframeTrack.prototype.TimeBufferType = Float32Array; + KeyframeTrack.prototype.ValueBufferType = Float32Array; + 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; + + /** + * A Track of keyframe values that represent color. + */ + class ColorKeyframeTrack extends KeyframeTrack {} + + ColorKeyframeTrack.prototype.ValueTypeName = 'color'; + + /** + * A Track of numeric keyframe values. + */ + class NumberKeyframeTrack extends KeyframeTrack {} + + NumberKeyframeTrack.prototype.ValueTypeName = 'number'; + + /** + * Spherical linear unit quaternion interpolant. + */ + + 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 ); + + 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.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; + StringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined; + StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; + + /** + * A Track of vectored keyframe values. + */ + class VectorKeyframeTrack extends KeyframeTrack {} + + VectorKeyframeTrack.prototype.ValueTypeName = 'vector'; + + class AnimationClip { + + constructor( name, duration = - 1, tracks, blendMode = NormalAnimationBlendMode ) { + + this.name = name; + this.tracks = tracks; + this.duration = duration; + this.blendMode = blendMode; + + 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 ); + + 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; + + const json = { + + 'name': clip.name, + 'duration': clip.duration, + 'tracks': tracks, + '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 = []; + + times.push( + ( i + numMorphTargets - 1 ) % numMorphTargets, + i, + ( i + 1 ) % numMorphTargets ); + + 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. + 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 + // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 + const pattern = /^([\w-]*?)([\d]+)$/; + + // 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 + 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 + 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. + 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 + 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 + // 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': + case 'double': + case 'float': + 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 = []; + + flattenJSON( json.keys, times, values, 'value' ); + + json.times = times; + json.values = values; + + } + + // derived classes can define a static parse method + if ( trackType.parse !== undefined ) { + + return trackType.parse( json ); + + } else { + + // by default, we assume a constructor compatible with the base + return new trackType( json.name, json.times, json.values, json.interpolation ); + + } + + } + + const Cache = { + + enabled: false, + + files: {}, + + add: function ( key, file ) { + + 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 ); + + return this.files[ key ]; + + }, + + remove: function ( key ) { + + delete this.files[ key ]; + + }, + + clear: function () { + + this.files = {}; + + } + + }; + + class LoadingManager { + + constructor( onLoad, onProgress, onError ) { + + const scope = this; + + let isLoading = false; + let itemsLoaded = 0; + let itemsTotal = 0; + let urlModifier = undefined; + 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 ]; + const loader = handlers[ i + 1 ]; + + if ( regex.global ) regex.lastIndex = 0; // see #17920 + + if ( regex.test( file ) ) { + + return loader; + + } + + } + + return null; + + }; + + } + + } + + const DefaultLoadingManager = /*@__PURE__*/ new LoadingManager(); + + class Loader { + + constructor( manager ) { + + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + + this.crossOrigin = 'anonymous'; + this.withCredentials = false; + this.path = ''; + this.resourcePath = ''; + this.requestHeader = {}; + + } + + load( /* url, onLoad, onProgress, onError */ ) {} + + loadAsync( url, onProgress ) { + + const scope = this; + + return new Promise( function ( resolve, reject ) { + + scope.load( url, resolve, onProgress, reject ); + + } ); + + } + + parse( /* data */ ) {} + + 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( () => { + + if ( onLoad ) onLoad( cached ); + + this.manager.itemEnd( url ); + + }, 0 ); + + return cached; + + } + + // Check if request is duplicate + + if ( loading[ url ] !== undefined ) { + + loading[ url ].push( { + + onLoad: onLoad, + onProgress: onProgress, + onError: onError + + } ); + + return; + + } + + // Initialise array for duplicate requests + loading[ url ] = []; + + loading[ url ].push( { + onLoad: onLoad, + onProgress: onProgress, + onError: onError, + } ); + + // 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 ) + const mimeType = this.mimeType; + 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 + + if ( typeof ReadableStream === 'undefined' || response.body === undefined || response.body.getReader === undefined ) { + + return response; + + } + + const callbacks = loading[ url ]; + const reader = response.body.getReader(); + + // 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 + const stream = new ReadableStream( { + start( controller ) { + + readData(); + + function readData() { + + reader.read().then( ( { done, value } ) => { + + if ( done ) { + + controller.close(); + + } else { + + loaded += value.byteLength; + + const event = new ProgressEvent( 'progress', { lengthComputable, 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 { + + throw new HttpError( `fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`, response ); + + } + + } ) + .then( response => { + + 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(); + + } else { + + // sniff encoding + const re = /charset="?([^;"\s]*)"?/i; + const exec = re.exec( mimeType ); + const label = exec && exec[ 1 ] ? exec[ 1 ].toLowerCase() : undefined; + 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 + // error response bodies as proper responses to requests. + 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 ]; + + 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 ); + loader.setPath( this.path ); + loader.setRequestHeader( this.requestHeader ); + loader.setWithCredentials( this.withCredentials ); + loader.load( url, function ( text ) { + + try { + + onLoad( scope.parse( JSON.parse( text ) ) ); + + } catch ( e ) { + + if ( onError ) { + + onError( e ); + + } else { + + console.error( e ); + + } + + scope.manager.itemError( url ); + + } + + }, onProgress, onError ); + + } + + parse( json ) { + + const animations = []; + + for ( let i = 0; i < json.length; i ++ ) { + + const clip = AnimationClip.parse( json[ i ] ); + + animations.push( clip ); + + } + + return animations; + + } + + } + + /** + * Abstract Base class to block based textures loader (dds, pvr, ...) + * + * Sub classes have to implement the parse() method which will be used in load(). + */ + + class CompressedTextureLoader extends Loader { + + constructor( manager ) { + + super( manager ); + + } + + load( url, onLoad, onProgress, onError ) { + + const scope = this; + + const images = []; + + const texture = new CompressedTexture(); + + const loader = new FileLoader( this.manager ); + loader.setPath( this.path ); + loader.setResponseType( 'arraybuffer' ); + 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 ); + + images[ i ] = { + width: texDatas.width, + height: texDatas.height, + format: texDatas.format, + mipmaps: texDatas.mipmaps + }; + + loaded += 1; + + if ( loaded === 6 ) { + + if ( texDatas.mipmapCount === 1 ) texture.minFilter = LinearFilter; + + texture.image = images; + texture.format = texDatas.format; + texture.needsUpdate = true; + + if ( onLoad ) onLoad( texture ); + + } + + }, 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; + images[ f ].width = texDatas.width; + 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 () { + + if ( onLoad ) onLoad( cached ); + + scope.manager.itemEnd( url ); + + }, 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; + + } + + } + + /** + * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...) + * + * Sub classes have to implement the parse() method which will be used in load(). + */ + + class DataTextureLoader extends Loader { + + constructor( manager ) { + + super( manager ); + + } + + load( url, onLoad, onProgress, onError ) { + + const scope = this; + + const texture = new DataTexture(); + + const loader = new FileLoader( this.manager ); + loader.setResponseType( 'arraybuffer' ); + loader.setRequestHeader( this.requestHeader ); + loader.setPath( this.path ); + loader.setWithCredentials( scope.withCredentials ); + loader.load( url, function ( buffer ) { + + const texData = scope.parse( buffer ); + + if ( ! texData ) return; + + if ( texData.image !== undefined ) { + + texture.image = texData.image; + + } else if ( texData.data !== undefined ) { + + texture.image.width = texData.width; + texture.image.height = texData.height; + texture.image.data = texData.data; + + } + + 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... + + } + + 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 ); + loader.setCrossOrigin( this.crossOrigin ); + loader.setPath( this.path ); + + loader.load( url, function ( image ) { + + texture.image = image; + texture.needsUpdate = true; + + if ( onLoad !== undefined ) { + + onLoad( texture ); + + } + + }, onProgress, onError ); + + return texture; + + } + + } + + class Light extends Object3D { + + constructor( color, intensity = 1 ) { + + super(); + + this.isLight = true; + + this.type = 'Light'; + + this.color = new Color( color ); + this.intensity = intensity; + + } + + dispose() { + + // 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(); + data.object.intensity = this.intensity; + + if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex(); + + if ( this.distance !== undefined ) data.object.distance = this.distance; + if ( this.angle !== undefined ) data.object.angle = this.angle; + if ( this.decay !== undefined ) data.object.decay = this.decay; + if ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra; + + if ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON(); + + return data; + + } + + } + + class HemisphereLight extends Light { + + constructor( skyColor, groundColor, intensity ) { + + super( skyColor, intensity ); + + this.isHemisphereLight = true; + + this.type = 'HemisphereLight'; + + this.position.copy( Object3D.DEFAULT_UP ); + 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; + + this.bias = 0; + this.normalBias = 0; + this.radius = 1; + this.blurSamples = 8; + + this.mapSize = new Vector2( 512, 512 ); + + this.map = null; + this.mapPass = null; + this.matrix = new Matrix4(); + + this.autoUpdate = true; + this.needsUpdate = false; + + this._frustum = new Frustum(); + this._frameExtents = new Vector2( 1, 1 ); + + this._viewportCount = 1; + + this._viewports = [ + + new Vector4( 0, 0, 1, 1 ) + + ]; + + } + + 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( _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; + this.radius = source.radius; + + 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; + if ( this.normalBias !== 0 ) object.normalBias = this.normalBias; + if ( this.radius !== 1 ) object.radius = this.radius; + if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray(); + + object.camera = this.camera.toJSON( false ).object; + delete object.camera.matrix; + + return object; + + } + + } + + class SpotLightShadow extends LightShadow { + + constructor() { + + super( new PerspectiveCamera( 50, 1, 0.5, 500 ) ); + + 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 = 2 ) { + + super( color, intensity ); + + this.isSpotLight = true; + + this.type = 'SpotLight'; + + this.position.copy( Object3D.DEFAULT_UP ); + this.updateMatrix(); + + this.target = new Object3D(); + + this.distance = distance; + this.angle = angle; + this.penumbra = penumbra; + 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; + this.angle = source.angle; + this.penumbra = source.penumbra; + this.decay = source.decay; + + this.target = source.target.clone(); + + 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 + // following orientation: + // + // xzXZ + // y Y + // + // X - Positive x direction + // x - Negative x direction + // Y - Positive y direction + // y - Negative y direction + // Z - Positive z direction + // z - Negative z direction + + // positive X + new Vector4( 2, 1, 1, 1 ), + // negative X + new Vector4( 0, 1, 1, 1 ), + // positive Z + new Vector4( 3, 1, 1, 1 ), + // negative Z + new Vector4( 1, 1, 1, 1 ), + // positive Y + new Vector4( 3, 0, 1, 1 ), + // negative Y + new Vector4( 1, 0, 1, 1 ) + ]; + + this._cubeDirections = [ + new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ), + new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 ) + ]; + + this._cubeUps = [ + new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), + new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 ) + ]; + + } + + 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 = 2 ) { + + super( color, intensity ); + + this.isPointLight = true; + + this.type = 'PointLight'; + + this.distance = distance; + 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; + this.decay = source.decay; + + this.shadow = source.shadow.clone(); + + return this; + + } + + } + + class DirectionalLightShadow extends LightShadow { + + constructor() { + + super( new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) ); + + this.isDirectionalLightShadow = true; + + } + + } + + class DirectionalLight extends Light { + + constructor( color, intensity ) { + + super( color, intensity ); + + this.isDirectionalLight = true; + + this.type = 'DirectionalLight'; + + this.position.copy( Object3D.DEFAULT_UP ); + this.updateMatrix(); + + 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 { + + constructor( color, intensity ) { + + super( color, intensity ); + + this.isAmbientLight = true; + + this.type = 'AmbientLight'; + + } + + } + + class RectAreaLight extends Light { + + constructor( color, intensity, width = 10, height = 10 ) { + + super( color, intensity ); + + this.isRectAreaLight = true; + + this.type = 'RectAreaLight'; + + 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; + + } + + } + + /** + * Primary reference: + * https://graphics.stanford.edu/papers/envmap/envmap.pdf + * + * Secondary reference: + * https://www.ppsloan.org/publications/StupidSH36.pdf + */ + + // 3-band SH defined by 9 coefficients + + 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 + 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 + target.copy( coeff[ 0 ] ).multiplyScalar( 0.282095 ); + + // band 1 + target.addScaledVector( coeff[ 1 ], 0.488603 * y ); + target.addScaledVector( coeff[ 2 ], 0.488603 * z ); + target.addScaledVector( coeff[ 3 ], 0.488603 * x ); + + // band 2 + target.addScaledVector( coeff[ 4 ], 1.092548 * ( x * y ) ); + target.addScaledVector( coeff[ 5 ], 1.092548 * ( y * z ) ); + target.addScaledVector( coeff[ 6 ], 0.315392 * ( 3.0 * z * z - 1.0 ) ); + target.addScaledVector( coeff[ 7 ], 1.092548 * ( x * z ) ); + target.addScaledVector( coeff[ 8 ], 0.546274 * ( x * x - y * y ) ); + + return target; + + } + + // get the irradiance (radiance convolved with cosine lobe) in the direction of the normal + // target is a Vector3 + // https://graphics.stanford.edu/papers/envmap/envmap.pdf + 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 + target.copy( coeff[ 0 ] ).multiplyScalar( 0.886227 ); // π * 0.282095 + + // band 1 + target.addScaledVector( coeff[ 1 ], 2.0 * 0.511664 * y ); // ( 2 * π / 3 ) * 0.488603 + target.addScaledVector( coeff[ 2 ], 2.0 * 0.511664 * z ); + target.addScaledVector( coeff[ 3 ], 2.0 * 0.511664 * x ); + + // band 2 + target.addScaledVector( coeff[ 4 ], 2.0 * 0.429043 * x * y ); // ( π / 4 ) * 1.092548 + target.addScaledVector( coeff[ 5 ], 2.0 * 0.429043 * y * z ); + target.addScaledVector( coeff[ 6 ], 0.743125 * z * z - 0.247708 ); // ( π / 4 ) * 0.315392 * 3 + target.addScaledVector( coeff[ 7 ], 2.0 * 0.429043 * x * z ); + target.addScaledVector( coeff[ 8 ], 0.429043 * ( x * x - y * y ) ); // ( π / 4 ) * 0.546274 + + return target; + + } + + 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 ] + static getBasisAt( normal, shBasis ) { + + // normal is assumed to be unit length + + const x = normal.x, y = normal.y, z = normal.z; + + // band 0 + shBasis[ 0 ] = 0.282095; + + // band 1 + shBasis[ 1 ] = 0.488603 * y; + shBasis[ 2 ] = 0.488603 * z; + shBasis[ 3 ] = 0.488603 * x; + + // band 2 + shBasis[ 4 ] = 1.092548 * x * y; + shBasis[ 5 ] = 1.092548 * y * z; + shBasis[ 6 ] = 0.315392 * ( 3 * z * z - 1 ); + shBasis[ 7 ] = 1.092548 * x * z; + shBasis[ 8 ] = 0.546274 * ( x * x - y * y ); + + } + + } + + class LightProbe extends Light { + + constructor( sh = new SphericalHarmonics3(), intensity = 1 ) { + + super( undefined, intensity ); + + 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 { + + constructor( manager ) { + + super( manager ); + this.textures = {}; + + } + + load( url, onLoad, onProgress, onError ) { + + const scope = this; + + const loader = new FileLoader( scope.manager ); + loader.setPath( scope.path ); + loader.setRequestHeader( scope.requestHeader ); + loader.setWithCredentials( scope.withCredentials ); + loader.load( url, function ( text ) { + + try { + + onLoad( scope.parse( JSON.parse( text ) ) ); + + } catch ( e ) { + + if ( onError ) { + + onError( e ); + + } else { + + console.error( e ); + + } + + scope.manager.itemError( url ); + + } + + }, onProgress, onError ); + + } + + parse( 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; + if ( json.color !== undefined && material.color !== undefined ) material.color.setHex( json.color ); + if ( json.roughness !== undefined ) material.roughness = json.roughness; + if ( json.metalness !== undefined ) material.metalness = json.metalness; + if ( json.sheen !== undefined ) material.sheen = json.sheen; + if ( json.sheenColor !== undefined ) material.sheenColor = new Color().setHex( json.sheenColor ); + if ( json.sheenRoughness !== undefined ) material.sheenRoughness = json.sheenRoughness; + if ( json.emissive !== undefined && material.emissive !== undefined ) material.emissive.setHex( json.emissive ); + if ( json.specular !== undefined && material.specular !== undefined ) material.specular.setHex( json.specular ); + if ( json.specularIntensity !== undefined ) material.specularIntensity = json.specularIntensity; + if ( json.specularColor !== undefined && material.specularColor !== undefined ) material.specularColor.setHex( json.specularColor ); + if ( json.shininess !== undefined ) material.shininess = json.shininess; + if ( json.clearcoat !== undefined ) material.clearcoat = json.clearcoat; + if ( json.clearcoatRoughness !== undefined ) material.clearcoatRoughness = json.clearcoatRoughness; + if ( json.iridescence !== undefined ) material.iridescence = json.iridescence; + if ( json.iridescenceIOR !== undefined ) material.iridescenceIOR = json.iridescenceIOR; + if ( json.iridescenceThicknessRange !== undefined ) material.iridescenceThicknessRange = json.iridescenceThicknessRange; + if ( json.transmission !== undefined ) material.transmission = json.transmission; + if ( json.thickness !== undefined ) material.thickness = json.thickness; + if ( json.attenuationDistance !== undefined ) material.attenuationDistance = json.attenuationDistance; + if ( json.attenuationColor !== undefined && material.attenuationColor !== undefined ) material.attenuationColor.setHex( json.attenuationColor ); + if ( json.fog !== undefined ) material.fog = json.fog; + if ( json.flatShading !== undefined ) material.flatShading = json.flatShading; + if ( json.blending !== undefined ) material.blending = json.blending; + if ( json.combine !== undefined ) material.combine = json.combine; + if ( json.side !== undefined ) material.side = json.side; + if ( json.shadowSide !== undefined ) material.shadowSide = json.shadowSide; + if ( json.opacity !== undefined ) material.opacity = json.opacity; + if ( json.transparent !== undefined ) material.transparent = json.transparent; + if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest; + if ( json.depthTest !== undefined ) material.depthTest = json.depthTest; + if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite; + if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite; + + if ( json.stencilWrite !== undefined ) material.stencilWrite = json.stencilWrite; + if ( json.stencilWriteMask !== undefined ) material.stencilWriteMask = json.stencilWriteMask; + if ( json.stencilFunc !== undefined ) material.stencilFunc = json.stencilFunc; + if ( json.stencilRef !== undefined ) material.stencilRef = json.stencilRef; + if ( json.stencilFuncMask !== undefined ) material.stencilFuncMask = json.stencilFuncMask; + if ( json.stencilFail !== undefined ) material.stencilFail = json.stencilFail; + if ( json.stencilZFail !== undefined ) material.stencilZFail = json.stencilZFail; + if ( json.stencilZPass !== undefined ) material.stencilZPass = json.stencilZPass; + + if ( json.wireframe !== undefined ) material.wireframe = json.wireframe; + if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth; + if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap; + if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin; + + if ( json.rotation !== undefined ) material.rotation = json.rotation; + + if ( json.linewidth !== 1 ) material.linewidth = json.linewidth; + if ( json.dashSize !== undefined ) material.dashSize = json.dashSize; + if ( json.gapSize !== undefined ) material.gapSize = json.gapSize; + if ( json.scale !== undefined ) material.scale = json.scale; + + if ( json.polygonOffset !== undefined ) material.polygonOffset = json.polygonOffset; + if ( json.polygonOffsetFactor !== undefined ) material.polygonOffsetFactor = json.polygonOffsetFactor; + if ( json.polygonOffsetUnits !== undefined ) material.polygonOffsetUnits = json.polygonOffsetUnits; + + if ( json.dithering !== undefined ) material.dithering = json.dithering; + + if ( json.alphaToCoverage !== undefined ) material.alphaToCoverage = json.alphaToCoverage; + if ( json.premultipliedAlpha !== undefined ) material.premultipliedAlpha = json.premultipliedAlpha; + if ( json.forceSinglePass !== undefined ) material.forceSinglePass = json.forceSinglePass; + + 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 + + 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 ]; + + } + + } + + // for PointsMaterial + + if ( json.size !== undefined ) material.size = json.size; + 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 ); + + if ( json.alphaMap !== undefined ) material.alphaMap = getTexture( json.alphaMap ); + + if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap ); + if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale; + + if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap ); + if ( json.normalMapType !== undefined ) material.normalMapType = json.normalMapType; + 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; + + if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap ); + if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap ); + + if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap ); + if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity; + + if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap ); + if ( json.specularIntensityMap !== undefined ) material.specularIntensityMap = getTexture( json.specularIntensityMap ); + if ( json.specularColorMap !== undefined ) material.specularColorMap = getTexture( json.specularColorMap ); + + if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap ); + if ( json.envMapIntensity !== undefined ) material.envMapIntensity = json.envMapIntensity; + + if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity; + if ( json.refractionRatio !== undefined ) material.refractionRatio = json.refractionRatio; + + if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap ); + if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity; + + if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap ); + if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity; + + if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap ); + + if ( json.clearcoatMap !== undefined ) material.clearcoatMap = getTexture( json.clearcoatMap ); + if ( json.clearcoatRoughnessMap !== undefined ) material.clearcoatRoughnessMap = getTexture( json.clearcoatRoughnessMap ); + if ( json.clearcoatNormalMap !== undefined ) material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap ); + if ( json.clearcoatNormalScale !== undefined ) material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale ); + + if ( json.iridescenceMap !== undefined ) material.iridescenceMap = getTexture( json.iridescenceMap ); + if ( json.iridescenceThicknessMap !== undefined ) material.iridescenceThicknessMap = getTexture( json.iridescenceThicknessMap ); + + if ( json.transmissionMap !== undefined ) material.transmissionMap = getTexture( json.transmissionMap ); + if ( json.thicknessMap !== undefined ) material.thicknessMap = getTexture( json.thicknessMap ); + + if ( json.sheenColorMap !== undefined ) material.sheenColorMap = getTexture( json.sheenColorMap ); + if ( json.sheenRoughnessMap !== undefined ) material.sheenRoughnessMap = getTexture( json.sheenRoughnessMap ); + + return material; + + } + + setTextures( value ) { + + this.textures = value; + return this; + + } + + static createMaterialFromType( type ) { + + const materialLib = { + ShadowMaterial, + SpriteMaterial, + RawShaderMaterial, + ShaderMaterial, + PointsMaterial, + MeshPhysicalMaterial, + MeshStandardMaterial, + MeshPhongMaterial, + MeshToonMaterial, + MeshNormalMaterial, + MeshLambertMaterial, + MeshDepthMaterial, + MeshDistanceMaterial, + MeshBasicMaterial, + MeshMatcapMaterial, + LineDashedMaterial, + LineBasicMaterial, + Material + }; + + 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. + + 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 ( /^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 + if ( /^data:.*,.*$/i.test( url ) ) return url; + + // Blob URL + if ( /^blob:.*$/i.test( url ) ) return url; + + // Relative URL + return path + url; + + } + + } + + class InstancedBufferGeometry extends BufferGeometry { + + constructor() { + + super(); + + this.isInstancedBufferGeometry = true; + + this.type = 'InstancedBufferGeometry'; + this.instanceCount = Infinity; + + } + + copy( source ) { + + super.copy( source ); + + this.instanceCount = source.instanceCount; + + return this; + + } + + toJSON() { + + 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 ); + loader.setPath( scope.path ); + loader.setRequestHeader( scope.requestHeader ); + loader.setWithCredentials( scope.withCredentials ); + loader.load( url, function ( text ) { + + try { + + onLoad( scope.parse( JSON.parse( text ) ) ); + + } catch ( e ) { + + if ( onError ) { + + onError( e ); + + } else { + + console.error( e ); + + } + + scope.manager.itemError( url ); + + } + + }, onProgress, onError ); + + } + + parse( json ) { + + const interleavedBufferMap = {}; + const arrayBufferMap = {}; + + function getInterleavedBuffer( json, uuid ) { + + if ( interleavedBufferMap[ uuid ] !== undefined ) return interleavedBufferMap[ uuid ]; + + const interleavedBuffers = json.interleavedBuffers; + const interleavedBuffer = interleavedBuffers[ uuid ]; + + const buffer = getArrayBuffer( json, interleavedBuffer.buffer ); + + const array = getTypedArray( interleavedBuffer.type, buffer ); + const ib = new InterleavedBuffer( array, interleavedBuffer.stride ); + ib.uuid = interleavedBuffer.uuid; + + interleavedBufferMap[ uuid ] = ib; + + return ib; + + } + + function getArrayBuffer( json, uuid ) { + + if ( arrayBufferMap[ uuid ] !== undefined ) return arrayBufferMap[ uuid ]; + + const arrayBuffers = json.arrayBuffers; + const arrayBuffer = arrayBuffers[ uuid ]; + + const ab = new Uint32Array( arrayBuffer ).buffer; + + 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 ); + + } else { + + const typedArray = getTypedArray( attribute.type, attribute.array ); + 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 ); + + } else { + + 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; + this.resourcePath = this.resourcePath || path; + + const loader = new FileLoader( this.manager ); + loader.setPath( this.path ); + loader.setRequestHeader( this.requestHeader ); + loader.setWithCredentials( this.withCredentials ); + loader.load( url, function ( text ) { + + let json = null; + + try { + + json = JSON.parse( text ); + + } catch ( error ) { + + if ( onError !== undefined ) onError( error ); + + console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message ); + + return; + + } + + 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; + this.resourcePath = this.resourcePath || path; + + const loader = new FileLoader( this.manager ); + loader.setPath( this.path ); + loader.setRequestHeader( this.requestHeader ); + loader.setWithCredentials( this.withCredentials ); + + 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 ); + const geometries = this.parseGeometries( json.geometries, shapes ); + + const images = this.parseImages( json.images, function () { + + if ( onLoad !== undefined ) onLoad( object ); + + } ); + + const textures = this.parseTextures( json.textures, images ); + 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 ); + + // + + 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 ); + const geometries = this.parseGeometries( json.geometries, shapes ); + + const images = await this.parseImagesAsync( json.images ); + + const textures = this.parseTextures( json.textures, images ); + 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 ); + + 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 + + object.traverse( function ( child ) { + + if ( child.isBone ) bones[ child.uuid ] = child; + + } ); + + // create skeletons + + if ( json !== undefined ) { + + for ( let i = 0, l = json.length; i < l; i ++ ) { + + const skeleton = new Skeleton().fromJSON( json[ i ], bones ); + + 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; + + 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 ( 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 ]; + + const clip = AnimationClip.parse( data ); + + 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 () { + + scope.manager.itemEnd( url ); + + }, undefined, function () { + + scope.manager.itemError( url ); + scope.manager.itemEnd( url ); + + } ); + + } + + function deserializeImage( image ) { + + if ( typeof image === 'string' ) { + + const url = image; + + const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url; + + return loadImage( path ); + + } else { + + if ( image.data ) { + + return { + data: getTypedArray( image.type, image.data ), + width: image.width, + height: image.height + }; + + } else { + + return null; + + } + + } + + } + + 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 = []; + + 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; + + const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url; + + return await loader.loadAsync( path ); + + } else { + + if ( image.data ) { + + return { + data: getTypedArray( image.type, image.data ), + width: image.width, + height: image.height + }; + + } else { + + return null; + + } + + } + + } + + 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 = []; + + 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; + + } else { + + if ( image && image.data ) { + + texture = new DataTexture(); + + } else { + + texture = new Texture(); + + } + + if ( image ) texture.needsUpdate = true; // textures can have undefined image data + + } + + texture.source = source; + + texture.uuid = data.uuid; + + if ( data.name !== undefined ) texture.name = data.name; + + if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING ); + + if ( data.offset !== undefined ) texture.offset.fromArray( data.offset ); + if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat ); + if ( data.center !== undefined ) texture.center.fromArray( data.center ); + if ( data.rotation !== undefined ) texture.rotation = data.rotation; + + if ( data.wrap !== undefined ) { + + texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING ); + texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING ); + + } + + if ( data.format !== undefined ) texture.format = data.format; + if ( data.type !== undefined ) texture.type = data.type; + if ( data.encoding !== undefined ) texture.encoding = data.encoding; + + if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER ); + if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER ); + if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy; + + if ( data.flipY !== undefined ) texture.flipY = data.flipY; + + if ( data.generateMipmaps !== undefined ) texture.generateMipmaps = data.generateMipmaps; + if ( data.premultiplyAlpha !== undefined ) texture.premultiplyAlpha = data.premultiplyAlpha; + if ( data.unpackAlignment !== undefined ) texture.unpackAlignment = data.unpackAlignment; + + if ( data.userData !== undefined ) texture.userData = data.userData; + + 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 ); + + } else { + + 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 ); + + } else if ( data.fog.type === 'FogExp2' ) { + + object.fog = new FogExp2( data.fog.color, data.fog.density ); + + } + + } + + if ( data.backgroundBlurriness !== undefined ) object.backgroundBlurriness = data.backgroundBlurriness; + if ( data.backgroundIntensity !== undefined ) object.backgroundIntensity = data.backgroundIntensity; + + break; + + case 'PerspectiveCamera': + + object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far ); + + if ( data.focus !== undefined ) object.focus = data.focus; + if ( data.zoom !== undefined ) object.zoom = data.zoom; + if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge; + if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset; + if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); + + break; + + 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 ); + + object = new SkinnedMesh( geometry, material ); + + if ( data.bindMode !== undefined ) object.bindMode = data.bindMode; + 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 ); + const count = data.count; + const instanceMatrix = data.instanceMatrix; + const instanceColor = data.instanceColor; + + object = new InstancedMesh( geometry, material, count ); + 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; + if ( object.matrixAutoUpdate ) object.matrix.decompose( object.position, object.quaternion, object.scale ); + + } else { + + if ( data.position !== undefined ) object.position.fromArray( data.position ); + if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation ); + if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion ); + if ( data.scale !== undefined ) object.scale.fromArray( data.scale ); + + } + + 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; + if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius; + if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize ); + if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera ); + + } + + 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, 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 { + + child.bind( skeleton, child.bindMatrix ); + + } + + } + + } ); + + } + + } + + const TEXTURE_MAPPING = { + UVMapping: UVMapping, + CubeReflectionMapping: CubeReflectionMapping, + CubeRefractionMapping: CubeRefractionMapping, + EquirectangularReflectionMapping: EquirectangularReflectionMapping, + EquirectangularRefractionMapping: EquirectangularRefractionMapping, + CubeUVReflectionMapping: CubeUVReflectionMapping + }; + + const TEXTURE_WRAPPING = { + RepeatWrapping: RepeatWrapping, + ClampToEdgeWrapping: ClampToEdgeWrapping, + MirroredRepeatWrapping: MirroredRepeatWrapping + }; + + const TEXTURE_FILTER = { + NearestFilter: NearestFilter, + NearestMipmapNearestFilter: NearestMipmapNearestFilter, + NearestMipmapLinearFilter: NearestMipmapLinearFilter, + LinearFilter: LinearFilter, + LinearMipmapNearestFilter: LinearMipmapNearestFilter, + LinearMipmapLinearFilter: LinearMipmapLinearFilter + }; + + 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 () { + + if ( onLoad ) onLoad( cached ); + + scope.manager.itemEnd( url ); + + }, 0 ); + + return cached; + + } + + const fetchOptions = {}; + fetchOptions.credentials = ( this.crossOrigin === 'anonymous' ) ? 'same-origin' : 'include'; + fetchOptions.headers = this.requestHeader; + + fetch( url, fetchOptions ).then( function ( res ) { + + return res.blob(); + + } ).then( function ( blob ) { + + return createImageBitmap( blob, Object.assign( scope.options, { colorSpaceConversion: 'none' } ) ); + + } ).then( function ( imageBitmap ) { + + Cache.add( url, imageBitmap ); + + if ( onLoad ) onLoad( imageBitmap ); + + scope.manager.itemEnd( url ); + + } ).catch( function ( e ) { + + if ( onError ) onError( e ); + + scope.manager.itemError( url ); + scope.manager.itemEnd( url ); + + } ); + + scope.manager.itemStart( url ); + + } + + } + + let _context; + + class AudioContext { + + static getContext() { + + if ( _context === undefined ) { + + _context = new ( window.AudioContext || window.webkitAudioContext )(); + + } + + return _context; + + } + + 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 ); + loader.setResponseType( 'arraybuffer' ); + loader.setPath( this.path ); + loader.setRequestHeader( this.requestHeader ); + loader.setWithCredentials( this.withCredentials ); + loader.load( url, function ( buffer ) { + + try { + + // Create a copy of the buffer. The `decodeAudioData` method + // detaches the buffer when complete, preventing reuse. + const bufferCopy = buffer.slice( 0 ); + + const context = AudioContext.getContext(); + context.decodeAudioData( bufferCopy, function ( audioBuffer ) { + + onLoad( audioBuffer ); + + } ); + + } catch ( e ) { + + if ( onError ) { + + onError( e ); + + } else { + + console.error( e ); + + } + + scope.manager.itemError( url ); + + } + + }, onProgress, onError ); + + } + + } + + class HemisphereLightProbe extends LightProbe { + + constructor( skyColor, groundColor, intensity = 1 ) { + + super( undefined, intensity ); + + this.isHemisphereLightProbe = true; + + 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 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 ); + 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'; + + this.aspect = 1; + + this.eyeSep = 0.064; + + this.cameraL = new PerspectiveCamera(); + this.cameraL.layers.enable( 1 ); + this.cameraL.matrixAutoUpdate = false; + + this.cameraR = new PerspectiveCamera(); + this.cameraR.layers.enable( 2 ); + this.cameraR.matrixAutoUpdate = false; + + this._cache = { + focus: null, + fov: null, + aspect: null, + near: null, + far: null, + zoom: null, + eyeSep: null + }; + + } + + 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; + cache.aspect = camera.aspect * this.aspect; + cache.near = camera.near; + cache.far = camera.far; + cache.zoom = camera.zoom; + cache.eyeSep = this.eyeSep; + + // Off-axis stereoscopic effect based on + // http://paulbourke.net/stereographics/stereorender/ + + _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 + + _eyeLeft.elements[ 12 ] = - eyeSepHalf; + _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 + + xmin = - ymax * cache.aspect - eyeSepOnProjection; + xmax = ymax * cache.aspect - eyeSepOnProjection; + + _projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin ); + _projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); + + this.cameraR.projectionMatrix.copy( _projectionMatrix ); + + } + + this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeLeft ); + this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeRight ); + + } + + } + + class Clock { + + constructor( autoStart = true ) { + + this.autoStart = autoStart; + + this.startTime = 0; + this.oldTime = 0; + 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(); + + this.type = 'AudioListener'; + + this.context = AudioContext.getContext(); + + this.gain = this.context.createGain(); + this.gain.connect( this.context.destination ); + + this.filter = null; + + this.timeDelta = 0; + + // private + + this._clock = new Clock(); + + } + + getInput() { + + return this.gain; + + } + + removeFilter() { + + if ( this.filter !== null ) { + + this.gain.disconnect( this.filter ); + this.filter.disconnect( this.context.destination ); + this.gain.connect( this.context.destination ); + this.filter = null; + + } + + return this; + + } + + getFilter() { + + return this.filter; + + } + + setFilter( value ) { + + if ( this.filter !== null ) { + + this.gain.disconnect( this.filter ); + this.filter.disconnect( this.context.destination ); + + } else { + + this.gain.disconnect( this.context.destination ); + + } + + this.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 ); + listener.positionZ.linearRampToValueAtTime( _position$1.z, endTime ); + listener.forwardX.linearRampToValueAtTime( _orientation$1.x, endTime ); + listener.forwardY.linearRampToValueAtTime( _orientation$1.y, endTime ); + listener.forwardZ.linearRampToValueAtTime( _orientation$1.z, endTime ); + listener.upX.linearRampToValueAtTime( up.x, endTime ); + listener.upY.linearRampToValueAtTime( up.y, endTime ); + listener.upZ.linearRampToValueAtTime( up.z, endTime ); + + } else { + + listener.setPosition( _position$1.x, _position$1.y, _position$1.z ); + listener.setOrientation( _orientation$1.x, _orientation$1.y, _orientation$1.z, up.x, up.y, up.z ); + + } + + } + + } + + class Audio extends Object3D { + + constructor( listener ) { + + super(); + + this.type = 'Audio'; + + this.listener = listener; + this.context = listener.context; + + this.gain = this.context.createGain(); + this.gain.connect( listener.getInput() ); + + this.autoplay = false; + + this.buffer = null; + this.detune = 0; + this.loop = false; + this.loopStart = 0; + this.loopEnd = 0; + this.offset = 0; + this.duration = undefined; + this.playbackRate = 1; + this.isPlaying = false; + this.hasPlaybackControl = true; + this.source = null; + this.sourceType = 'empty'; + + this._startedAt = 0; + this._progress = 0; + this._connected = false; + + this.filters = []; + + } + + getOutput() { + + return this.gain; + + } + + setNodeSource( audioNode ) { + + this.hasPlaybackControl = false; + this.sourceType = 'audioNode'; + this.source = audioNode; + this.connect(); + + return this; + + } + + setMediaElementSource( mediaElement ) { + + this.hasPlaybackControl = false; + this.sourceType = 'mediaNode'; + this.source = this.context.createMediaElementSource( mediaElement ); + this.connect(); + + return this; + + } + + setMediaStreamSource( mediaStream ) { + + this.hasPlaybackControl = false; + this.sourceType = 'mediaStreamNode'; + this.source = this.context.createMediaStreamSource( mediaStream ); + 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; + source.loop = this.loop; + source.loopStart = this.loopStart; + source.loopEnd = this.loopEnd; + source.onended = this.onEnded.bind( this ); + source.start( this._startedAt, this._progress + this.offset, this.duration ); + + this.isPlaying = true; + + this.source = source; + + this.setDetune( this.detune ); + this.setPlaybackRate( this.playbackRate ); + + return this.connect(); + + } + + 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; + + 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; + + if ( this.source !== null ) { + + 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(); + this.connect(); + + } else { + + this.filters = value.slice(); + + } + + return this; + + } + + setDetune( value ) { + + this.detune = value; + + if ( this.source.detune === undefined ) return; // only set detune when available + + 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 ); + + this.panner = this.context.createPanner(); + 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 ); + panner.positionZ.linearRampToValueAtTime( _position.z, endTime ); + panner.orientationX.linearRampToValueAtTime( _orientation.x, endTime ); + panner.orientationY.linearRampToValueAtTime( _orientation.y, endTime ); + panner.orientationZ.linearRampToValueAtTime( _orientation.z, endTime ); + + } else { + + panner.setPosition( _position.x, _position.y, _position.z ); + panner.setOrientation( _orientation.x, _orientation.y, _orientation.z ); + + } + + } + + } + + class AudioAnalyser { + + constructor( audio, fftSize = 2048 ) { + + this.analyser = audio.context.createAnalyser(); + this.analyser.fftSize = fftSize; + + 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) ] + // + // interpolators can use .buffer as their .result + // the data then goes to 'incoming' + // + // 'accu0' and 'accu1' are used frame-interleaved for + // the cumulative result and are compared to detect + // changes + // + // 'orig' stores the original state of the property + // + // 'add' is used for additive cumulative results + // + // 'work' is optional and is only present for quaternion types. It is used + // to store intermediate quaternion multiplication results + + switch ( typeName ) { + + case 'quaternion': + mixFunction = this._slerp; + mixFunctionAdditive = this._slerpAdditive; + setIdentity = this._setAdditiveIdentityQuaternion; + + this.buffer = new Float64Array( valueSize * 6 ); + this._workIndex = 5; + break; + + 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 + 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; + this._origIndex = 3; + this._addIndex = 4; + + this.cumulativeWeight = 0; + this.cumulativeWeightAdditive = 0; + + this.useCount = 0; + this.referenceCount = 0; + + } + + // 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; + + 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' + accumulateAdditive( weight ) { + + const buffer = this.buffer, + stride = this.valueSize, + offset = stride * this._addIndex; + + if ( this.cumulativeWeightAdditive === 0 ) { + + // add = identity + + this._setIdentity(); + + } + + // 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( accuIndex ) { + + const stride = this.valueSize, + buffer = this.buffer, + offset = accuIndex * stride + stride, + + weight = this.cumulativeWeight, + weightAdditive = this.cumulativeWeightAdditive, + + binding = this.binding; + + this.cumulativeWeight = 0; + this.cumulativeWeightAdditive = 0; + + if ( weight < 1 ) { + + // accuN := accuN + original * ( 1 - cumulativeWeight ) + + 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 + 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 + for ( let i = stride, e = originalValueOffset; i !== e; ++ i ) { + + buffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ]; + + } + + // Add to identity for additive + this._setIdentity(); + + this.cumulativeWeight = 0; + this.cumulativeWeightAdditive = 0; + + } + + // 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 + + _select( buffer, dstOffset, srcOffset, t, stride ) { + + if ( t >= 0.5 ) { + + for ( let i = 0; i !== stride; ++ i ) { + + buffer[ dstOffset + i ] = buffer[ srcOffset + i ]; + + } + + } + + } + + _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 + 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' ); + + // 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( '\\.', '' ) + ']'; + + // 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 ); + + // 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 ); + + // 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', '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 + 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: + // '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 ); + + 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 ); + + } else { + + return new PropertyBinding.Composite( root, path, parsedPath ); + + } + + } + + /** + * Replaces spaces with underscores and removes unsupported characters from + * node names, to ensure compatibility with parseTrackName(). + * + * @param {string} name Node name to be sanitized. + * @return {string} + */ + 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 ], + objectName: matches[ 3 ], + objectIndex: matches[ 4 ], + propertyName: matches[ 5 ], // required + 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 + // 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. + if ( root.skeleton ) { + + const bone = root.skeleton.getBoneByName( nodeName ); + + if ( bone !== undefined ) { + + return bone; + + } + + } + + // 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 + _getValue_unavailable() {} + _setValue_unavailable() {} + + // 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 + + _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 + + _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 + + _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 + + _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 + 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.node = targetObject; + + } + + // 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 + 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.... + 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. + + 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 + 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 + 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 + 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 ) ) { + + bindingType = this.BindingType.EntireArray; + + this.resolvedProperty = nodeProperty; + + } else { + + this.propertyName = propertyName; + + } + + // 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.getValue = this._getValue_unbound; + this.setValue = this._setValue_unbound; + + } + + } + + PropertyBinding.Composite = Composite; + + PropertyBinding.prototype.BindingType = { + Direct: 0, + EntireArray: 1, + ArrayElement: 2, + HasFromToArray: 3 + }; + + PropertyBinding.prototype.Versioning = { + None: 0, + NeedsUpdate: 1, + 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._setValue_fromArray, + PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate, + PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate, + + ] + + ]; + + /** + * + * A group of objects that receives a shared animation state. + * + * Usage: + * + * - Add objects you would otherwise pass as 'root' to the + * constructor or the .clipAction method of AnimationMixer. + * + * - Instead pass this object as 'root'. + * + * - You can also add and remove objects later when the mixer + * is running. + * + * Note: + * + * Objects of this class appear as one object to the mixer, + * so cache control of the individual objects must be done + * on the group. + * + * Limitation: + * + * - The animated properties must be compatible among the + * all objects in the group. + * + * - A single property can either be controlled through a + * target group or directly, but not both. + */ + + class AnimationObjectGroup { + + constructor() { + + this.isAnimationObjectGroup = true; + + 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 + + const indices = {}; + this._indicesByUUID = indices; // for bookkeeping + + 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; + + this.stats = { + + objects: { + 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; + + let knownObject = undefined, + nObjects = objects.length, + nCachedObjects = this.nCachedObjects_; + + for ( let i = 0, n = arguments.length; i !== n; ++ i ) { + + const object = arguments[ i ], + 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 + + 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 + + const firstActiveIndex = -- nCachedObjects, + lastCachedObject = objects[ firstActiveIndex ]; + + indicesByUUID[ lastCachedObject.uuid ] = index; + objects[ index ] = lastCachedObject; + + indicesByUUID[ uuid ] = firstActiveIndex; + objects[ firstActiveIndex ] = object; + + // accounting is done, now do the same for all bindings + + for ( let j = 0, m = nBindings; j !== m; ++ j ) { + + const bindingsForPath = bindings[ j ], + lastCached = bindingsForPath[ firstActiveIndex ]; + + let binding = bindingsForPath[ index ]; - class LineDashedMaterial extends LineBasicMaterial { - constructor(parameters) { - super(); - this.isLineDashedMaterial = true; - this.type = 'LineDashedMaterial'; - this.scale = 1; - this.dashSize = 3; - this.gapSize = 1; - this.setValues(parameters); - } + bindingsForPath[ index ] = lastCached; - copy(source) { - super.copy(source); - this.scale = source.scale; - this.dashSize = source.dashSize; - this.gapSize = source.gapSize; - return this; - } + if ( binding === undefined ) { - } + // since we do not bother to create new bindings + // for objects that are cached, the binding may + // or may not exist - const materialLib = { - ShadowMaterial, - SpriteMaterial, - RawShaderMaterial, - ShaderMaterial, - PointsMaterial, - MeshPhysicalMaterial, - MeshStandardMaterial, - MeshPhongMaterial, - MeshToonMaterial, - MeshNormalMaterial, - MeshLambertMaterial, - MeshDepthMaterial, - MeshDistanceMaterial, - MeshBasicMaterial, - MeshMatcapMaterial, - LineDashedMaterial, - LineBasicMaterial, - Material - }; + binding = new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ); - Material.fromType = function (type) { - return new materialLib[type](); - }; + } - const AnimationUtils = { - // same as Array.prototype.slice, but also works on typed arrays - arraySlice: function (array, from, to) { - if (AnimationUtils.isTypedArray(array)) { - // in ios9 array.subarray(from, undefined) will return empty array - // but array.subarray(from) or array.subarray(from, len) is correct - return new array.constructor(array.subarray(from, to !== undefined ? to : array.length)); - } + bindingsForPath[ firstActiveIndex ] = binding; - return array.slice(from, to); - }, - // converts an array to a specific type - convertArray: function (array, type, forceClone) { - 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 - } + } else if ( objects[ index ] !== knownObject ) { - return Array.prototype.slice.call(array); // create Array - }, - isTypedArray: function (object) { - return ArrayBuffer.isView(object) && !(object instanceof DataView); - }, - // returns an array by which times and values can be sorted - getKeyframeOrder: function (times) { - function compareTime(i, j) { - return times[i] - times[j]; - } + console.error( 'THREE.AnimationObjectGroup: Different objects with the same UUID ' + + 'detected. Clean the caches or recreate your infrastructure when reloading scenes.' ); - const n = times.length; - const result = new Array(n); + } // else the object is already where we want it to be - for (let i = 0; i !== n; ++i) result[i] = i; + } // for arguments - result.sort(compareTime); - return result; - }, - // uses the array previously returned by 'getKeyframeOrder' to sort data - sortedArray: function (values, stride, order) { - const nValues = values.length; - const result = new values.constructor(nValues); + this.nCachedObjects_ = nCachedObjects; - 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]; - } - } + remove() { - return result; - }, - // function for parsing AOS keyframe formats - flattenJSON: function (jsonKeys, times, values, valuePropertyName) { - let i = 1, - key = jsonKeys[0]; + const objects = this._objects, + indicesByUUID = this._indicesByUUID, + bindings = this._bindings, + nBindings = bindings.length; - while (key !== undefined && key[valuePropertyName] === undefined) { - key = jsonKeys[i++]; - } + let nCachedObjects = this.nCachedObjects_; - if (key === undefined) return; // no data + for ( let i = 0, n = arguments.length; i !== n; ++ i ) { - let value = key[valuePropertyName]; - if (value === undefined) return; // no data + const object = arguments[ i ], + uuid = object.uuid, + index = indicesByUUID[ uuid ]; - if (Array.isArray(value)) { - do { - value = key[valuePropertyName]; + if ( index !== undefined && index >= nCachedObjects ) { - if (value !== undefined) { - times.push(key.time); - values.push.apply(values, value); // push all elements - } + // move existing object into the CACHED region - key = jsonKeys[i++]; - } while (key !== undefined); - } else if (value.toArray !== undefined) { - // ...assume THREE.Math-ish - do { - value = key[valuePropertyName]; + const lastCachedIndex = nCachedObjects ++, + firstActiveObject = objects[ lastCachedIndex ]; - if (value !== undefined) { - times.push(key.time); - value.toArray(values, values.length); - } + indicesByUUID[ firstActiveObject.uuid ] = index; + objects[ index ] = firstActiveObject; - key = jsonKeys[i++]; - } while (key !== undefined); - } else { - // otherwise push as-is - do { - value = key[valuePropertyName]; + indicesByUUID[ uuid ] = lastCachedIndex; + objects[ lastCachedIndex ] = object; - if (value !== undefined) { - times.push(key.time); - values.push(value); - } + // accounting is done, now do the same for all bindings - key = jsonKeys[i++]; - } while (key !== undefined); - } - }, - subclip: function (sourceClip, name, startFrame, endFrame, fps = 30) { - const clip = sourceClip.clone(); - clip.name = name; - const tracks = []; + for ( let j = 0, m = nBindings; j !== m; ++ j ) { - for (let i = 0; i < clip.tracks.length; ++i) { - const track = clip.tracks[i]; - const valueSize = track.getValueSize(); - const times = []; - const values = []; + const bindingsForPath = bindings[ j ], + firstActive = bindingsForPath[ lastCachedIndex ], + binding = bindingsForPath[ index ]; - 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]); + bindingsForPath[ index ] = firstActive; + bindingsForPath[ lastCachedIndex ] = binding; - for (let k = 0; k < valueSize; ++k) { - values.push(track.values[j * valueSize + k]); } + } - if (times.length === 0) continue; - track.times = AnimationUtils.convertArray(times, track.times.constructor); - track.values = AnimationUtils.convertArray(values, track.values.constructor); - tracks.push(track); - } + } // for arguments - clip.tracks = tracks; // find minimum .times value across all tracks in the trimmed clip + this.nCachedObjects_ = nCachedObjects; - 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 + // remove & forget + uncache() { + const objects = this._objects, + indicesByUUID = this._indicesByUUID, + bindings = this._bindings, + nBindings = bindings.length; - for (let i = 0; i < clip.tracks.length; ++i) { - clip.tracks[i].shift(-1 * minStartTime); - } + let nCachedObjects = this.nCachedObjects_, + nObjects = objects.length; - clip.resetDuration(); - return clip; - }, - makeClipAdditive: function (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 + for ( let i = 0, n = arguments.length; i !== n; ++ i ) { - 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 object = arguments[ i ], + uuid = object.uuid, + index = indicesByUUID[ uuid ]; - if (referenceTrackType === 'bool' || referenceTrackType === 'string') continue; // Find the track in the target clip whose name and type matches the reference track + if ( index !== undefined ) { - 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(); + delete indicesByUUID[ uuid ]; - if (referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { - referenceOffset = referenceValueSize / 3; - } + if ( index < nCachedObjects ) { - let targetOffset = 0; - const targetValueSize = targetTrack.getValueSize(); + // object is cached, shrink the CACHED region - if (targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { - targetOffset = targetValueSize / 3; - } + const firstActiveIndex = -- nCachedObjects, + lastCachedObject = objects[ firstActiveIndex ], + lastIndex = -- nObjects, + lastObject = objects[ lastIndex ]; - const lastIndex = referenceTrack.times.length - 1; - let referenceValue; // Find the value to subtract out of the track + // last cached object takes this object's place + indicesByUUID[ lastCachedObject.uuid ] = index; + objects[ index ] = lastCachedObject; - if (referenceTime <= referenceTrack.times[0]) { - // Reference frame is earlier than the first keyframe, so just use the first keyframe - const startIndex = referenceOffset; - const endIndex = referenceValueSize - referenceOffset; - referenceValue = AnimationUtils.arraySlice(referenceTrack.values, startIndex, endIndex); - } else if (referenceTime >= referenceTrack.times[lastIndex]) { - // Reference frame is after the last keyframe, so just use the last keyframe - const startIndex = lastIndex * referenceValueSize + referenceOffset; - const endIndex = startIndex + referenceValueSize - referenceOffset; - referenceValue = AnimationUtils.arraySlice(referenceTrack.values, startIndex, endIndex); - } else { - // Interpolate to the reference value - const interpolant = referenceTrack.createInterpolant(); - const startIndex = referenceOffset; - const endIndex = referenceValueSize - referenceOffset; - interpolant.evaluate(referenceTime); - referenceValue = AnimationUtils.arraySlice(interpolant.resultBuffer, startIndex, endIndex); - } // Conjugate the quaternion + // 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 - if (referenceTrackType === 'quaternion') { - const referenceQuat = new Quaternion().fromArray(referenceValue).normalize().conjugate(); - referenceQuat.toArray(referenceValue); - } // Subtract the reference value from all of the track values + for ( let j = 0, m = nBindings; j !== m; ++ j ) { + const bindingsForPath = bindings[ j ], + lastCached = bindingsForPath[ firstActiveIndex ], + last = bindingsForPath[ lastIndex ]; - const numTimes = targetTrack.times.length; + bindingsForPath[ index ] = lastCached; + bindingsForPath[ firstActiveIndex ] = last; + bindingsForPath.pop(); - 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 - - for (let k = 0; k < valueEnd; ++k) { - targetTrack.values[valueStart + k] -= referenceValue[k]; - } - } - } - } - targetClip.blendMode = AdditiveAnimationBlendMode; - return targetClip; - } - }; + // object is active, just swap with the last and pop - /** - * Abstract base class of interpolants over parametric samples. - * - * The parameter domain is one dimensional, typically the time or a path - * along a curve defined by the data. - * - * The sample values can have any dimensionality and derived classes may - * apply special interpretations to the data. - * - * This class provides the interval seek in a Template Method, deferring - * the actual interpolation to derived classes. - * - * Time complexity is O(1) for linear access crossing at most two points - * and O(log N) for random access, where N is the number of positions. - * - * References: - * - * http://www.oodesign.com/template-method-pattern.html - * - */ - class Interpolant { - constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { - this.parameterPositions = parameterPositions; - this._cachedIndex = 0; - this.resultBuffer = resultBuffer !== undefined ? resultBuffer : new sampleValues.constructor(sampleSize); - this.sampleValues = sampleValues; - this.valueSize = sampleSize; - this.settings = null; - this.DefaultSettings_ = {}; - } + const lastIndex = -- nObjects, + lastObject = objects[ lastIndex ]; - evaluate(t) { - const pp = this.parameterPositions; - let i1 = this._cachedIndex, - t1 = pp[i1], - t0 = pp[i1 - 1]; + if ( lastIndex > 0 ) { - validate_interval: { - seek: { - let right; + indicesByUUID[ lastObject.uuid ] = index; - linear_scan: { - //- See http://jsperf.com/comparison-to-undefined/3 - //- slower code: - //- - //- if ( t >= t1 || t1 === undefined ) { - forward_scan: if (!(t < t1)) { - for (let giveUpAt = i1 + 2;;) { - if (t1 === undefined) { - if (t < t0) break forward_scan; // after end + } - i1 = pp.length; - this._cachedIndex = i1; - return this.copySampleValue_(i1 - 1); - } + objects[ index ] = lastObject; + objects.pop(); - if (i1 === giveUpAt) break; // this loop + // accounting is done, now do the same for all bindings - t0 = t1; - t1 = pp[++i1]; + for ( let j = 0, m = nBindings; j !== m; ++ j ) { - if (t < t1) { - // we have arrived at the sought interval - break seek; - } - } // prepare binary search on the right side of the index + const bindingsForPath = bindings[ j ]; + bindingsForPath[ index ] = bindingsForPath[ lastIndex ]; + bindingsForPath.pop(); - right = pp.length; - break linear_scan; - } //- slower code: - //- if ( t < t0 || t0 === undefined ) { + } + } // cached or active - if (!(t >= t0)) { - // looping? - const t1global = pp[1]; + } // if object is known - if (t < t1global) { - i1 = 2; // + 1, using the scan for the details + } // for arguments - t0 = t1global; - } // linear reverse scan + this.nCachedObjects_ = nCachedObjects; + } - for (let giveUpAt = i1 - 2;;) { - if (t0 === undefined) { - // before start - this._cachedIndex = 0; - return this.copySampleValue_(0); - } + // Internal interface used by befriended PropertyBinding.Composite: - if (i1 === giveUpAt) break; // this loop + subscribe_( path, parsedPath ) { - t1 = t0; - t0 = pp[--i1 - 1]; + // returns an array of bindings for the given path that is changed + // according to the contained objects in the group - if (t >= t0) { - // we have arrived at the sought interval - break seek; - } - } // prepare binary search on the left side of the index + const indicesByPath = this._bindingsIndicesByPath; + let index = indicesByPath[ path ]; + const bindings = this._bindings; + if ( index !== undefined ) return bindings[ index ]; - right = i1; - i1 = 0; - break linear_scan; - } // the interval is valid + const paths = this._paths, + parsedPaths = this._parsedPaths, + objects = this._objects, + nObjects = objects.length, + nCachedObjects = this.nCachedObjects_, + bindingsForPath = new Array( nObjects ); + index = bindings.length; - break validate_interval; - } // linear scan - // binary search + indicesByPath[ path ] = index; + paths.push( path ); + parsedPaths.push( parsedPath ); + bindings.push( bindingsForPath ); - while (i1 < right) { - const mid = i1 + right >>> 1; + for ( let i = nCachedObjects, n = objects.length; i !== n; ++ i ) { - if (t < pp[mid]) { - right = mid; - } else { - i1 = mid + 1; - } - } + const object = objects[ i ]; + bindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath ); - t1 = pp[i1]; - t0 = pp[i1 - 1]; // check boundary cases, again + } - if (t0 === undefined) { - this._cachedIndex = 0; - return this.copySampleValue_(0); - } + return bindingsForPath; - if (t1 === undefined) { - i1 = pp.length; - this._cachedIndex = i1; - return this.copySampleValue_(i1 - 1); - } - } // seek + } + unsubscribe_( path ) { - this._cachedIndex = i1; - this.intervalChanged_(i1, t0, t1); - } // validate_interval + // 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 ]; - return this.interpolate_(i1, t0, t, t1); - } + if ( index !== undefined ) { - getSettings_() { - return this.settings || this.DefaultSettings_; - } + const paths = this._paths, + parsedPaths = this._parsedPaths, + bindings = this._bindings, + lastBindingsIndex = bindings.length - 1, + lastBindings = bindings[ lastBindingsIndex ], + lastBindingsPath = path[ lastBindingsIndex ]; - copySampleValue_(index) { - // copies a sample value to the result buffer - const result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, - offset = index * stride; + indicesByPath[ lastBindingsPath ] = index; - for (let i = 0; i !== stride; ++i) { - result[i] = values[offset + i]; - } + bindings[ index ] = lastBindings; + bindings.pop(); - return result; - } // Template methods for derived classes: + parsedPaths[ index ] = parsedPaths[ lastBindingsIndex ]; + parsedPaths.pop(); + paths[ index ] = paths[ lastBindingsIndex ]; + paths.pop(); - interpolate_() { - throw new Error('call to abstract method'); // implementations shall return this.resultBuffer - } + } - intervalChanged_() {// empty } } - /** - * Fast and simple cubic spline interpolant. - * - * It was derived from a Hermitian construction setting the first derivative - * at each sample position to the linear slope between neighboring positions - * over their parameter interval. - */ + class AnimationAction { - class CubicInterpolant extends Interpolant { - constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { - super(parameterPositions, sampleValues, sampleSize, resultBuffer); - this._weightPrev = -0; - this._offsetPrev = -0; - this._weightNext = -0; - this._offsetNext = -0; - this.DefaultSettings_ = { + constructor( mixer, clip, localRoot = null, blendMode = clip.blendMode ) { + + this._mixer = mixer; + this._clip = clip; + this._localRoot = localRoot; + this.blendMode = blendMode; + + const tracks = clip.tracks, + nTracks = tracks.length, + interpolants = new Array( nTracks ); + + const interpolantSettings = { endingStart: ZeroCurvatureEnding, endingEnd: ZeroCurvatureEnding }; - } - intervalChanged_(i1, t0, t1) { - const pp = this.parameterPositions; - let iPrev = i1 - 2, - iNext = i1 + 1, - tPrev = pp[iPrev], - tNext = pp[iNext]; - - if (tPrev === undefined) { - switch (this.getSettings_().endingStart) { - case ZeroSlopeEnding: - // f'(t0) = 0 - iPrev = i1; - tPrev = 2 * t0 - t1; - break; + for ( let i = 0; i !== nTracks; ++ i ) { - case WrapAroundEnding: - // use the other end of the curve - iPrev = pp.length - 2; - tPrev = t0 + pp[iPrev] - pp[iPrev + 1]; - break; + const interpolant = tracks[ i ].createInterpolant( null ); + interpolants[ i ] = interpolant; + interpolant.settings = interpolantSettings; - default: - // ZeroCurvatureEnding - // f''(t0) = 0 a.k.a. Natural Spline - iPrev = i1; - tPrev = t1; - } } - if (tNext === undefined) { - switch (this.getSettings_().endingEnd) { - case ZeroSlopeEnding: - // f'(tN) = 0 - iNext = i1; - tNext = 2 * t1 - t0; - break; + this._interpolantSettings = interpolantSettings; - case WrapAroundEnding: - // use the other end of the curve - iNext = 1; - tNext = t1 + pp[1] - pp[0]; - break; + this._interpolants = interpolants; // bound by the mixer + + // inside: PropertyMixer (managed by the mixer) + this._propertyBindings = new Array( nTracks ); + + this._cacheIndex = null; // for the memory manager + 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 + // it's set back to 'null' upon start of the action + this._startTime = null; + + // 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; + + this.weight = 1; + this._effectiveWeight = 1; - default: - // ZeroCurvatureEnding - // f''(tN) = 0, a.k.a. Natural Spline - iNext = i1 - 1; - tNext = t0; - } - } + this.repetitions = Infinity; // no. of repetitions when looping - const halfDt = (t1 - t0) * 0.5, - stride = this.valueSize; - this._weightPrev = halfDt / (t0 - tPrev); - this._weightNext = halfDt / (tNext - t1); - this._offsetPrev = iPrev * stride; - this._offsetNext = iNext * stride; - } + this.paused = false; // true -> zero effective time scale + this.enabled = true; // false -> zero effective weight - 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 - - 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 - - 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]; - } + 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 - return result; } - } + // State & Scheduling - class LinearInterpolant extends Interpolant { - constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { - super(parameterPositions, sampleValues, sampleSize, resultBuffer); - } + play() { - 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; + this._mixer._activateAction( this ); - for (let i = 0; i !== stride; ++i) { - result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1; - } + return this; - return result; } - } + stop() { - /** - * - * Interpolant that evaluates to the sample value at the position preceding - * the parameter. - */ + this._mixer._deactivateAction( this ); - class DiscreteInterpolant extends Interpolant { - constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { - super(parameterPositions, sampleValues, sampleSize, resultBuffer); - } + return this.reset(); - interpolate_(i1 - /*, t0, t, t1 */ - ) { - return this.copySampleValue_(i1 - 1); } - } + reset() { - class KeyframeTrack { - constructor(name, times, values, interpolation) { - if (name === undefined) throw new Error('THREE.KeyframeTrack: track name is undefined'); - if (times === undefined || times.length === 0) throw new Error('THREE.KeyframeTrack: no keyframes in track named ' + name); - this.name = name; - this.times = AnimationUtils.convertArray(times, this.TimeBufferType); - this.values = AnimationUtils.convertArray(values, this.ValueBufferType); - this.setInterpolation(interpolation || this.DefaultInterpolation); - } // Serialization (in static context, because of constructor invocation - // and automatic invocation of .toJSON): + this.paused = false; + this.enabled = true; + this.time = 0; // restart clip + this._loopCount = - 1;// forget previous loops + this._startTime = null;// forget scheduling - static toJSON(track) { - const trackType = track.constructor; - let json; // derived classes can define a static toJSON method + return this.stopFading().stopWarping(); - if (trackType.toJSON !== this.toJSON) { - json = trackType.toJSON(track); - } else { - // by default, we assume the data can be serialized as-is - json = { - 'name': track.name, - 'times': AnimationUtils.convertArray(track.times, Array), - 'values': AnimationUtils.convertArray(track.values, Array) - }; - const interpolation = track.getInterpolation(); + } - if (interpolation !== track.DefaultInterpolation) { - json.interpolation = interpolation; - } - } + isRunning() { - json.type = track.ValueTypeName; // mandatory + return this.enabled && ! this.paused && this.timeScale !== 0 && + this._startTime === null && this._mixer._isActiveAction( this ); - return json; } - InterpolantFactoryMethodDiscrete(result) { - return new DiscreteInterpolant(this.times, this.values, this.getValueSize(), result); - } + // return true when play has been called + isScheduled() { - InterpolantFactoryMethodLinear(result) { - return new LinearInterpolant(this.times, this.values, this.getValueSize(), result); - } + return this._mixer._isActiveAction( this ); - InterpolantFactoryMethodSmooth(result) { - return new CubicInterpolant(this.times, this.values, this.getValueSize(), result); } - setInterpolation(interpolation) { - let factoryMethod; - - switch (interpolation) { - case InterpolateDiscrete: - factoryMethod = this.InterpolantFactoryMethodDiscrete; - break; + startAt( time ) { - case InterpolateLinear: - factoryMethod = this.InterpolantFactoryMethodLinear; - break; + this._startTime = time; - case InterpolateSmooth: - factoryMethod = this.InterpolantFactoryMethodSmooth; - break; - } + return this; - 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) { - this.setInterpolation(this.DefaultInterpolation); - } else { - throw new Error(message); // fatal, in this case - } - } + setLoop( mode, repetitions ) { - console.warn('THREE.KeyframeTrack:', message); - return this; - } + this.loop = mode; + this.repetitions = repetitions; - this.createInterpolant = factoryMethod; return this; + } - getInterpolation() { - switch (this.createInterpolant) { - case this.InterpolantFactoryMethodDiscrete: - return InterpolateDiscrete; + // Weight - case this.InterpolantFactoryMethodLinear: - return InterpolateLinear; + // 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._effectiveWeight = this.enabled ? weight : 0; + + return this.stopFading(); - case this.InterpolantFactoryMethodSmooth: - return InterpolateSmooth; - } } - getValueSize() { - return this.values.length / this.times.length; - } // move all keyframes either forwards or backwards in time + // return the weight considering fading and .enabled + getEffectiveWeight() { + return this._effectiveWeight; - shift(timeOffset) { - if (timeOffset !== 0.0) { - const times = this.times; + } - for (let i = 0, n = times.length; i !== n; ++i) { - times[i] += timeOffset; - } - } + fadeIn( duration ) { - return this; - } // scale all keyframe times by a factor (useful for frame <-> seconds conversions) + return this._scheduleFading( duration, 0, 1 ); + } - scale(timeScale) { - if (timeScale !== 1.0) { - const times = this.times; + fadeOut( duration ) { - for (let i = 0, n = times.length; i !== n; ++i) { - times[i] *= timeScale; - } - } + return this._scheduleFading( duration, 1, 0 ); - 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 + } + crossFadeFrom( fadeOutAction, duration, warp ) { - trim(startTime, endTime) { - const times = this.times, - nKeys = times.length; - let from = 0, - to = nKeys - 1; + fadeOutAction.fadeOut( duration ); + this.fadeIn( duration ); - while (from !== nKeys && times[from] < startTime) { - ++from; - } + if ( warp ) { - while (to !== -1 && times[to] > endTime) { - --to; - } + const fadeInDuration = this._clip.duration, + fadeOutDuration = fadeOutAction._clip.duration, - ++to; // inclusive -> exclusive bound + startEndRatio = fadeOutDuration / fadeInDuration, + endStartRatio = fadeInDuration / fadeOutDuration; - if (from !== 0 || to !== nKeys) { - // empty tracks are forbidden, so keep at least one keyframe - if (from >= to) { - to = Math.max(to, 1); - from = to - 1; - } + fadeOutAction.warp( 1.0, startEndRatio, duration ); + this.warp( endStartRatio, 1.0, duration ); - const stride = this.getValueSize(); - this.times = AnimationUtils.arraySlice(times, from, to); - this.values = AnimationUtils.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 + } - 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; - } + crossFadeTo( fadeInAction, duration, warp ) { - const times = this.times, - values = this.values, - nKeys = times.length; + return fadeInAction.crossFadeFrom( this, duration, warp ); - if (nKeys === 0) { - console.error('THREE.KeyframeTrack: Track is empty.', this); - valid = false; - } + } - let prevTime = null; + stopFading() { - for (let i = 0; i !== nKeys; i++) { - const currTime = times[i]; + const weightInterpolant = this._weightInterpolant; - if (typeof currTime === 'number' && isNaN(currTime)) { - console.error('THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime); - valid = false; - break; - } + if ( weightInterpolant !== null ) { - if (prevTime !== null && prevTime > currTime) { - console.error('THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime); - valid = false; - break; - } + this._weightInterpolant = null; + this._mixer._takeBackControlInterpolant( weightInterpolant ); - prevTime = currTime; } - if (values !== undefined) { - if (AnimationUtils.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; - break; - } - } - } - } + return this; - 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) + } + // Time Scale Control - optimize() { - // times or values may be shared with other tracks, so overwriting is unsafe - const times = AnimationUtils.arraySlice(this.times), - values = AnimationUtils.arraySlice(this.values), - stride = this.getValueSize(), - smoothInterpolation = this.getInterpolation() === InterpolateSmooth, - lastIndex = times.length - 1; - let writeIndex = 1; + // 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 ) { - 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 + this.timeScale = timeScale; + this._effectiveTimeScale = this.paused ? 0 : timeScale; - 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; + return this.stopWarping(); - for (let j = 0; j !== stride; ++j) { - const value = values[offset + j]; + } - if (value !== values[offsetP + j] || value !== values[offsetN + j]) { - keep = true; - break; - } - } - } else { - keep = true; - } - } // in-place compaction + // return the time scale considering warping and .paused + getEffectiveTimeScale() { + return this._effectiveTimeScale; - if (keep) { - if (i !== writeIndex) { - times[writeIndex] = times[i]; - const readOffset = i * stride, - writeOffset = writeIndex * stride; + } - for (let j = 0; j !== stride; ++j) { - values[writeOffset + j] = values[readOffset + j]; - } - } + setDuration( duration ) { - ++writeIndex; - } - } // flush last keyframe (compaction looks ahead) + this.timeScale = this._clip.duration / duration; + return this.stopWarping(); - 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]; - } + syncWith( action ) { - ++writeIndex; - } + this.time = action.time; + this.timeScale = action.timeScale; - if (writeIndex !== times.length) { - this.times = AnimationUtils.arraySlice(times, 0, writeIndex); - this.values = AnimationUtils.arraySlice(values, 0, writeIndex * stride); - } else { - this.times = times; - this.values = values; - } + return this.stopWarping(); - return this; } - clone() { - const times = AnimationUtils.arraySlice(this.times, 0); - const values = AnimationUtils.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. + halt( duration ) { + + return this.warp( this._effectiveTimeScale, 0, duration ); - track.createInterpolant = this.createInterpolant; - return track; } - } + warp( startTimeScale, endTimeScale, duration ) { - KeyframeTrack.prototype.TimeBufferType = Float32Array; - KeyframeTrack.prototype.ValueBufferType = Float32Array; - KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; + const mixer = this._mixer, + now = mixer.time, + timeScale = this.timeScale; - /** - * A Track of Boolean keyframe values. - */ + let interpolant = this._timeScaleInterpolant; - class BooleanKeyframeTrack extends KeyframeTrack {} + if ( interpolant === null ) { - 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 + interpolant = mixer._lendControlInterpolant(); + this._timeScaleInterpolant = interpolant; - /** - * A Track of keyframe values that represent color. - */ + } - class ColorKeyframeTrack extends KeyframeTrack {} + const times = interpolant.parameterPositions, + values = interpolant.sampleValues; - ColorKeyframeTrack.prototype.ValueTypeName = 'color'; // ValueBufferType is inherited + times[ 0 ] = now; + times[ 1 ] = now + duration; - /** - * A Track of numeric keyframe values. - */ + values[ 0 ] = startTimeScale / timeScale; + values[ 1 ] = endTimeScale / timeScale; - class NumberKeyframeTrack extends KeyframeTrack {} + return this; - NumberKeyframeTrack.prototype.ValueTypeName = 'number'; // ValueBufferType is inherited + } - /** - * Spherical linear unit quaternion interpolant. - */ + stopWarping() { - class QuaternionLinearInterpolant extends Interpolant { - constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { - super(parameterPositions, sampleValues, sampleSize, resultBuffer); - } + const timeScaleInterpolant = this._timeScaleInterpolant; - interpolate_(i1, t0, t, t1) { - const result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, - alpha = (t - t0) / (t1 - t0); - let offset = i1 * stride; + if ( timeScaleInterpolant !== null ) { + + this._timeScaleInterpolant = null; + this._mixer._takeBackControlInterpolant( timeScaleInterpolant ); - for (let end = offset + stride; offset !== end; offset += 4) { - Quaternion.slerpFlat(result, 0, values, offset - stride, values, offset, alpha); } - return result; + return this; + + } + + // Object Accessors + + getMixer() { + + return this._mixer; + } - } + getClip() { - /** - * A Track of quaternion keyframe values. - */ + return this._clip; - class QuaternionKeyframeTrack extends KeyframeTrack { - InterpolantFactoryMethodLinear(result) { - return new QuaternionLinearInterpolant(this.times, this.values, this.getValueSize(), result); } - } - - QuaternionKeyframeTrack.prototype.ValueTypeName = 'quaternion'; // ValueBufferType is inherited + getRoot() { - QuaternionKeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; - QuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; + return this._localRoot || this._mixer._root; - /** - * A Track that interpolates Strings - */ + } - class StringKeyframeTrack extends KeyframeTrack {} + // Interna - StringKeyframeTrack.prototype.ValueTypeName = 'string'; - StringKeyframeTrack.prototype.ValueBufferType = Array; - StringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete; - StringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined; - StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; + _update( time, deltaTime, timeDirection, accuIndex ) { - /** - * A Track of vectored keyframe values. - */ + // called by the mixer - class VectorKeyframeTrack extends KeyframeTrack {} + if ( ! this.enabled ) { - VectorKeyframeTrack.prototype.ValueTypeName = 'vector'; // ValueBufferType is inherited + // call ._updateWeight() to update ._effectiveWeight - class AnimationClip { - constructor(name, duration = -1, tracks, blendMode = NormalAnimationBlendMode) { - this.name = name; - 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._updateWeight( time ); + return; - if (this.duration < 0) { - this.resetDuration(); } - } - static parse(json) { - const tracks = [], - jsonTracks = json.tracks, - frameTime = 1.0 / (json.fps || 1.0); + const startTime = this._startTime; - for (let i = 0, n = jsonTracks.length; i !== n; ++i) { - tracks.push(parseKeyframeTrack(jsonTracks[i]).scale(frameTime)); - } + if ( startTime !== null ) { - const clip = new this(json.name, json.duration, tracks, json.blendMode); - clip.uuid = json.uuid; - return clip; - } + // check for scheduled start of action - static toJSON(clip) { - const tracks = [], - clipTracks = clip.tracks; - const json = { - 'name': clip.name, - 'duration': clip.duration, - 'tracks': tracks, - 'uuid': clip.uuid, - 'blendMode': clip.blendMode - }; + const timeRunning = ( time - startTime ) * timeDirection; + if ( timeRunning < 0 || timeDirection === 0 ) { - for (let i = 0, n = clipTracks.length; i !== n; ++i) { - tracks.push(KeyframeTrack.toJSON(clipTracks[i])); - } + deltaTime = 0; - return json; - } + } else { - static CreateFromMorphTargetSequence(name, morphTargetSequence, fps, noLoop) { - const numMorphTargets = morphTargetSequence.length; - const tracks = []; - for (let i = 0; i < numMorphTargets; i++) { - let times = []; - let values = []; - times.push((i + numMorphTargets - 1) % numMorphTargets, i, (i + 1) % numMorphTargets); - values.push(0, 1, 0); - const order = AnimationUtils.getKeyframeOrder(times); - times = AnimationUtils.sortedArray(times, 1, order); - values = AnimationUtils.sortedArray(values, 1, order); // if there is a key at the first frame, duplicate it as the - // last frame as well for perfect loop. + this._startTime = null; // unschedule + deltaTime = timeDirection * timeRunning; - 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); - } + // apply time scale and advance time - static findByName(objectOrClipArray, name) { - let clipArray = objectOrClipArray; + deltaTime *= this._updateTimeScale( time ); + const clipTime = this._updateTime( deltaTime ); - if (!Array.isArray(objectOrClipArray)) { - const o = objectOrClipArray; - clipArray = o.geometry && o.geometry.animations || o.animations; - } + // note: _updateTime may disable the action resulting in + // an effective weight of 0 - for (let i = 0; i < clipArray.length; i++) { - if (clipArray[i].name === name) { - return clipArray[i]; - } - } + const weight = this._updateWeight( time ); - return null; - } + if ( weight > 0 ) { - static CreateClipsFromMorphTargetSequences(morphTargets, fps, noLoop) { - const animationToMorphTargets = {}; // tested with https://regex101.com/ on trick sequences - // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 + const interpolants = this._interpolants; + const propertyMixers = this._propertyBindings; - const pattern = /^([\w-]*?)([\d]+)$/; // sort morph target names into animation groups based - // patterns like Walk_001, Walk_002, Run_001, Run_002 + switch ( this.blendMode ) { - for (let i = 0, il = morphTargets.length; i < il; i++) { - const morphTarget = morphTargets[i]; - const parts = morphTarget.name.match(pattern); + case AdditiveAnimationBlendMode: - if (parts && parts.length > 1) { - const name = parts[1]; - let animationMorphTargets = animationToMorphTargets[name]; + for ( let j = 0, m = interpolants.length; j !== m; ++ j ) { - if (!animationMorphTargets) { - animationToMorphTargets[name] = animationMorphTargets = []; - } + interpolants[ j ].evaluate( clipTime ); + propertyMixers[ j ].accumulateAdditive( weight ); - animationMorphTargets.push(morphTarget); - } - } + } - const clips = []; + break; - for (const name in animationToMorphTargets) { - clips.push(this.CreateFromMorphTargetSequence(name, animationToMorphTargets[name], fps, noLoop)); - } + case NormalAnimationBlendMode: + default: - return clips; - } // parse the animation.hierarchy format + for ( let j = 0, m = interpolants.length; j !== m; ++ j ) { + interpolants[ j ].evaluate( clipTime ); + propertyMixers[ j ].accumulate( accuIndex, weight ); + + } + + } - 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 = []; - AnimationUtils.flattenJSON(animationKeys, times, values, propertyName); // empty keys are filtered out, so check again + } - if (times.length !== 0) { - destTracks.push(new trackType(trackName, times, values)); - } - } - }; + _updateWeight( time ) { - const tracks = []; - const clipName = animation.name || 'default'; - const fps = animation.fps || 30; - const blendMode = animation.blendMode; // automatic length determination in AnimationClip. + let weight = 0; - let duration = animation.length || -1; - const hierarchyTracks = animation.hierarchy || []; + if ( this.enabled ) { - for (let h = 0; h < hierarchyTracks.length; h++) { - const animationKeys = hierarchyTracks[h].keys; // skip empty tracks + weight = this.weight; + const interpolant = this._weightInterpolant; - if (!animationKeys || animationKeys.length === 0) continue; // process morph targets + if ( interpolant !== null ) { - if (animationKeys[0].morphTargets) { - // figure out all morph targets used in this track - const morphTargetNames = {}; - let k; + const interpolantValue = interpolant.evaluate( time )[ 0 ]; - 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 - // morphTargetInfluences except for the keys in which - // the morphTarget is named. + weight *= interpolantValue; + if ( time > interpolant.parameterPositions[ 1 ] ) { - for (const morphTargetName in morphTargetNames) { - const times = []; - const values = []; + this.stopFading(); + + if ( interpolantValue === 0 ) { + + // faded out, disable + this.enabled = false; - 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._effectiveWeight = weight; + return weight; - this.duration = duration; - return this; } - trim() { - for (let i = 0; i < this.tracks.length; i++) { - this.tracks[i].trim(0, this.duration); - } + _updateTimeScale( time ) { - return this; - } + let timeScale = 0; - validate() { - let valid = true; + if ( ! this.paused ) { - for (let i = 0; i < this.tracks.length; i++) { - valid = valid && this.tracks[i].validate(); - } + timeScale = this.timeScale; - return valid; - } + const interpolant = this._timeScaleInterpolant; - optimize() { - for (let i = 0; i < this.tracks.length; i++) { - this.tracks[i].optimize(); - } + if ( interpolant !== null ) { - return this; - } + const interpolantValue = interpolant.evaluate( time )[ 0 ]; - clone() { - const tracks = []; + timeScale *= interpolantValue; - for (let i = 0; i < this.tracks.length; i++) { - tracks.push(this.tracks[i].clone()); - } + if ( time > interpolant.parameterPositions[ 1 ] ) { - return new this.constructor(this.name, this.duration, tracks, this.blendMode); - } + this.stopWarping(); - toJSON() { - return this.constructor.toJSON(this); - } + if ( timeScale === 0 ) { - } + // motion has halted, pause + this.paused = true; - function getTrackTypeForValueTypeName(typeName) { - switch (typeName.toLowerCase()) { - case 'scalar': - case 'double': - case 'float': - case 'number': - case 'integer': - return NumberKeyframeTrack; + } else { - case 'vector': - case 'vector2': - case 'vector3': - case 'vector4': - return VectorKeyframeTrack; + // warp done - apply final time scale + this.timeScale = timeScale; - 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); - } + this._effectiveTimeScale = timeScale; + return timeScale; - 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 = []; - AnimationUtils.flattenJSON(json.keys, times, values, 'value'); - json.times = times; - json.values = values; - } // derived classes can define a static parse method + _updateTime( deltaTime ) { + const duration = this._clip.duration; + const loop = this.loop; - if (trackType.parse !== undefined) { - return trackType.parse(json); - } else { - // by default, we assume a constructor compatible with the base - return new trackType(json.name, json.times, json.values, json.interpolation); - } - } + let time = this.time + deltaTime; + let loopCount = this._loopCount; - const Cache = { - enabled: false, - files: {}, - add: function (key, file) { - if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Adding key:', key ); + const pingPong = ( loop === LoopPingPong ); - this.files[key] = file; - }, - get: function (key) { - if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Checking key:', key ); + if ( deltaTime === 0 ) { - return this.files[key]; - }, - remove: function (key) { - delete this.files[key]; - }, - clear: function () { - this.files = {}; - } - }; + if ( loopCount === - 1 ) return time; - class LoadingManager { - constructor(onLoad, onProgress, onError) { - const scope = this; - let isLoading = false; - let itemsLoaded = 0; - let itemsTotal = 0; - let urlModifier = undefined; - const handlers = []; // Refer to #5689 for the reason why we don't set .onStart - // in the constructor + return ( pingPong && ( loopCount & 1 ) === 1 ) ? duration - time : time; - this.onStart = undefined; - this.onLoad = onLoad; - this.onProgress = onProgress; - this.onError = onError; + } - this.itemStart = function (url) { - itemsTotal++; + if ( loop === LoopOnce ) { - if (isLoading === false) { - if (scope.onStart !== undefined) { - scope.onStart(url, itemsLoaded, itemsTotal); - } - } + if ( loopCount === - 1 ) { - isLoading = true; - }; + // just started - this.itemEnd = function (url) { - itemsLoaded++; + this._loopCount = 0; + this._setEndings( true, true, false ); - if (scope.onProgress !== undefined) { - scope.onProgress(url, itemsLoaded, itemsTotal); } - if (itemsLoaded === itemsTotal) { - isLoading = false; + handle_stop: { - if (scope.onLoad !== undefined) { - scope.onLoad(); - } - } - }; + if ( time >= duration ) { - this.itemError = function (url) { - if (scope.onError !== undefined) { - scope.onError(url); - } - }; + time = duration; - this.resolveURL = function (url) { - if (urlModifier) { - return urlModifier(url); - } + } else if ( time < 0 ) { - return url; - }; + time = 0; - this.setURLModifier = function (transform) { - urlModifier = transform; - return this; - }; + } else { - this.addHandler = function (regex, loader) { - handlers.push(regex, loader); - return this; - }; + this.time = time; + + break handle_stop; - this.removeHandler = function (regex) { - const index = handlers.indexOf(regex); + } - if (index !== -1) { - handlers.splice(index, 2); - } + if ( this.clampWhenFinished ) this.paused = true; + else this.enabled = false; - return this; - }; + this.time = time; - this.getHandler = function (file) { - for (let i = 0, l = handlers.length; i < l; i += 2) { - const regex = handlers[i]; - const loader = handlers[i + 1]; - if (regex.global) regex.lastIndex = 0; // see #17920 + this._mixer.dispatchEvent( { + type: 'finished', action: this, + direction: deltaTime < 0 ? - 1 : 1 + } ); - if (regex.test(file)) { - return loader; - } } - return null; - }; - } + } else { // repetitive Repeat or PingPong - } + if ( loopCount === - 1 ) { - const DefaultLoadingManager = new LoadingManager(); + // just started - class Loader { - constructor(manager) { - this.manager = manager !== undefined ? manager : DefaultLoadingManager; - this.crossOrigin = 'anonymous'; - this.withCredentials = false; - this.path = ''; - this.resourcePath = ''; - this.requestHeader = {}; - } + if ( deltaTime >= 0 ) { - load() {} + loopCount = 0; - loadAsync(url, onProgress) { - const scope = this; - return new Promise(function (resolve, reject) { - scope.load(url, resolve, onProgress, reject); - }); - } + this._setEndings( true, this.repetitions === 0, pingPong ); - parse() {} + } else { - setCrossOrigin(crossOrigin) { - this.crossOrigin = crossOrigin; - return this; - } + // when looping in reverse direction, the initial + // transition through zero counts as a repetition, + // so leave loopCount at -1 - setWithCredentials(value) { - this.withCredentials = value; - return this; - } + this._setEndings( this.repetitions === 0, true, pingPong ); - setPath(path) { - this.path = path; - return this; - } + } - setResourcePath(resourcePath) { - this.resourcePath = resourcePath; - return this; - } + } - setRequestHeader(requestHeader) { - this.requestHeader = requestHeader; - return this; - } + if ( time >= duration || time < 0 ) { - } + // wrap around - const loading = {}; + const loopDelta = Math.floor( time / duration ); // signed + time -= duration * loopDelta; - 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(() => { - if (onLoad) onLoad(cached); - this.manager.itemEnd(url); - }, 0); - return cached; - } // Check if request is duplicate + loopCount += Math.abs( loopDelta ); + const pending = this.repetitions - loopCount; - if (loading[url] !== undefined) { - loading[url].push({ - onLoad: onLoad, - onProgress: onProgress, - onError: onError - }); - return; - } // Initialise array for duplicate requests + if ( pending <= 0 ) { + // have to stop (switch state, clamp time, fire event) - loading[url] = []; - loading[url].push({ - onLoad: onLoad, - onProgress: onProgress, - onError: onError - }); // create request + if ( this.clampWhenFinished ) this.paused = true; + else this.enabled = false; - 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 + time = deltaTime > 0 ? duration : 0; - }); // record states ( avoid data race ) + this.time = time; - const mimeType = this.mimeType; - 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 - - - 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'); - const total = contentLength ? parseInt(contentLength) : 0; - const lengthComputable = total !== 0; - 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, - value - }) => { - if (done) { - controller.close(); - } else { - loaded += value.byteLength; - const event = new ProgressEvent('progress', { - lengthComputable, - loaded, - total - }); - - for (let i = 0, il = callbacks.length; i < il; i++) { - const callback = callbacks[i]; - if (callback.onProgress) callback.onProgress(event); - } + this._mixer.dispatchEvent( { + type: 'finished', action: this, + direction: deltaTime > 0 ? 1 : - 1 + } ); - controller.enqueue(value); - readData(); - } - }); - } - } + } else { - }); - return new Response(stream); - } else { - throw Error(`fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`); - } - }).then(response => { - switch (responseType) { - case 'arraybuffer': - return response.arrayBuffer(); + // keep running - case 'blob': - return response.blob(); + if ( pending === 1 ) { - case 'document': - return response.text().then(text => { - const parser = new DOMParser(); - return parser.parseFromString(text, mimeType); - }); + // entering the last round - case 'json': - return response.json(); + const atStart = deltaTime < 0; + this._setEndings( atStart, ! atStart, pingPong ); - default: - if (mimeType === undefined) { - return response.text(); } else { - // sniff encoding - const re = /charset="?([^;"\s]*)"?/i; - const exec = re.exec(mimeType); - const label = exec && exec[1] ? exec[1].toLowerCase() : undefined; - const decoder = new TextDecoder(label); - return response.arrayBuffer().then(ab => decoder.decode(ab)); + + this._setEndings( false, false, pingPong ); + } - } - }).then(data => { - // Add to cache only on HTTP success, so that we do not cache - // error response bodies as proper responses to requests. - Cache.add(url, data); - const callbacks = loading[url]; - delete loading[url]; + this._loopCount = loopCount; - 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]; + this.time = time; - if (callbacks === undefined) { - // When onLoad was called and url was deleted in `loading` - this.manager.itemError(url); - throw err; - } + this._mixer.dispatchEvent( { + type: 'loop', action: this, loopDelta: loopDelta + } ); + + } + + } else { - delete loading[url]; + this.time = time; - 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); - } + if ( pingPong && ( loopCount & 1 ) === 1 ) { - setResponseType(value) { - this.responseType = value; - return this; - } + // invert time for the "pong round" - setMimeType(value) { - this.mimeType = value; - return this; - } + return duration - time; - } + } - class AnimationLoader extends Loader { - constructor(manager) { - super(manager); - } + } - load(url, onLoad, onProgress, onError) { - const scope = this; - const loader = new FileLoader(this.manager); - loader.setPath(this.path); - loader.setRequestHeader(this.requestHeader); - loader.setWithCredentials(this.withCredentials); - loader.load(url, function (text) { - try { - onLoad(scope.parse(JSON.parse(text))); - } catch (e) { - if (onError) { - onError(e); - } else { - console.error(e); - } + return time; - scope.manager.itemError(url); - } - }, onProgress, onError); } - parse(json) { - const animations = []; + _setEndings( atStart, atEnd, pingPong ) { - for (let i = 0; i < json.length; i++) { - const clip = AnimationClip.parse(json[i]); - animations.push(clip); - } + const settings = this._interpolantSettings; - return animations; - } + if ( pingPong ) { - } + settings.endingStart = ZeroSlopeEnding; + settings.endingEnd = ZeroSlopeEnding; - /** - * Abstract Base class to block based textures loader (dds, pvr, ...) - * - * Sub classes have to implement the parse() method which will be used in load(). - */ + } else { - class CompressedTextureLoader extends Loader { - constructor(manager) { - super(manager); - } + // assuming for LoopOnce atStart == atEnd == true - load(url, onLoad, onProgress, onError) { - const scope = this; - const images = []; - const texture = new CompressedTexture(); - const loader = new FileLoader(this.manager); - loader.setPath(this.path); - loader.setResponseType('arraybuffer'); - loader.setRequestHeader(this.requestHeader); - loader.setWithCredentials(scope.withCredentials); - let loaded = 0; + if ( atStart ) { - function loadTexture(i) { - loader.load(url[i], function (buffer) { - const texDatas = scope.parse(buffer, true); - images[i] = { - width: texDatas.width, - height: texDatas.height, - format: texDatas.format, - mipmaps: texDatas.mipmaps - }; - loaded += 1; + settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding; - if (loaded === 6) { - if (texDatas.mipmapCount === 1) texture.minFilter = LinearFilter; - texture.image = images; - texture.format = texDatas.format; - texture.needsUpdate = true; - if (onLoad) onLoad(texture); - } - }, onProgress, onError); - } + } else { + + settings.endingStart = WrapAroundEnding; - 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; + if ( atEnd ) { - for (let f = 0; f < faces; f++) { - images[f] = { - mipmaps: [] - }; + settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; - for (let i = 0; i < texDatas.mipmapCount; i++) { - images[f].mipmaps.push(texDatas.mipmaps[f * texDatas.mipmapCount + i]); - images[f].format = texDatas.format; - images[f].width = texDatas.width; - images[f].height = texDatas.height; - } - } + } else { - texture.image = images; - } else { - texture.image.width = texDatas.width; - texture.image.height = texDatas.height; - texture.mipmaps = texDatas.mipmaps; - } + settings.endingEnd = WrapAroundEnding; - 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); - } + _scheduleFading( duration, weightNow, weightThen ) { - 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 () { - if (onLoad) onLoad(cached); - scope.manager.itemEnd(url); - }, 0); - return cached; - } + const mixer = this._mixer, now = mixer.time; + let interpolant = this._weightInterpolant; - const image = createElementNS('img'); + if ( interpolant === null ) { - function onImageLoad() { - removeEventListeners(); - Cache.add(url, this); - if (onLoad) onLoad(this); - scope.manager.itemEnd(url); - } + interpolant = mixer._lendControlInterpolant(); + this._weightInterpolant = interpolant; - 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); - } + const times = interpolant.parameterPositions, + values = interpolant.sampleValues; - image.addEventListener('load', onImageLoad, false); - image.addEventListener('error', onImageError, false); + times[ 0 ] = now; + values[ 0 ] = weightNow; + times[ 1 ] = now + duration; + values[ 1 ] = weightThen; - if (url.slice(0, 5) !== 'data:') { - if (this.crossOrigin !== undefined) image.crossOrigin = this.crossOrigin; - } + return this; - scope.manager.itemStart(url); - image.src = url; - return image; } } - class CubeTextureLoader extends Loader { - constructor(manager) { - super(manager); - } + const _controlInterpolantsResultBuffer = new Float32Array( 1 ); - 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++; + class AnimationMixer extends EventDispatcher { - if (loaded === 6) { - texture.needsUpdate = true; - if (onLoad) onLoad(texture); - } - }, undefined, onError); - } + constructor( root ) { - for (let i = 0; i < urls.length; ++i) { - loadTexture(i); - } + super(); + + this._root = root; + this._initMemoryManager(); + this._accuIndex = 0; + this.time = 0; + this.timeScale = 1.0; - return texture; } - } + _bindAction( action, prototypeAction ) { - /** - * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...) - * - * Sub classes have to implement the parse() method which will be used in load(). - */ + 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; - class DataTextureLoader extends Loader { - constructor(manager) { - super(manager); - } + let bindingsByName = bindingsByRoot[ rootUuid ]; - load(url, onLoad, onProgress, onError) { - const scope = this; - const texture = new DataTexture(); - const loader = new FileLoader(this.manager); - loader.setResponseType('arraybuffer'); - loader.setRequestHeader(this.requestHeader); - loader.setPath(this.path); - loader.setWithCredentials(scope.withCredentials); - loader.load(url, function (buffer) { - const texData = scope.parse(buffer); - if (!texData) return; - - if (texData.image !== undefined) { - texture.image = texData.image; - } else if (texData.data !== undefined) { - texture.image.width = texData.width; - texture.image.height = texData.height; - texture.image.data = texData.data; - } + if ( bindingsByName === undefined ) { - 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; + bindingsByName = {}; + bindingsByRoot[ rootUuid ] = bindingsByName; - if (texData.encoding !== undefined) { - texture.encoding = texData.encoding; - } + } - if (texData.flipY !== undefined) { - texture.flipY = texData.flipY; - } + for ( let i = 0; i !== nTracks; ++ i ) { - if (texData.format !== undefined) { - texture.format = texData.format; - } + const track = tracks[ i ], + trackName = track.name; - if (texData.type !== undefined) { - texture.type = texData.type; - } + let binding = bindingsByName[ trackName ]; - if (texData.mipmaps !== undefined) { - texture.mipmaps = texData.mipmaps; - texture.minFilter = LinearMipmapLinearFilter; // presumably... - } + if ( binding !== undefined ) { - if (texData.mipmapCount === 1) { - texture.minFilter = LinearFilter; - } + ++ binding.referenceCount; + bindings[ i ] = binding; - if (texData.generateMipmaps !== undefined) { - texture.generateMipmaps = texData.generateMipmaps; - } + } else { - texture.needsUpdate = true; - if (onLoad) onLoad(texture, texData); - }, onProgress, onError); - return texture; - } + binding = bindings[ i ]; - } + if ( binding !== undefined ) { - class TextureLoader extends Loader { - constructor(manager) { - super(manager); - } + // existing binding, make sure the cache knows - load(url, onLoad, onProgress, onError) { - const texture = new Texture(); - const loader = new ImageLoader(this.manager); - loader.setCrossOrigin(this.crossOrigin); - loader.setPath(this.path); - loader.load(url, function (image) { - texture.image = image; - texture.needsUpdate = true; + if ( binding._cacheIndex === null ) { - if (onLoad !== undefined) { - onLoad(texture); - } - }, onProgress, onError); - return texture; - } + ++ binding.referenceCount; + this._addInactiveBinding( binding, rootUuid, trackName ); + + } + + continue; + + } - } + const path = prototypeAction && prototypeAction. + _propertyBindings[ i ].binding.parsedPath; - class Light extends Object3D { - constructor(color, intensity = 1) { - super(); - this.isLight = true; - this.type = 'Light'; - this.color = new Color(color); - this.intensity = intensity; - } + binding = new PropertyMixer( + PropertyBinding.create( root, trackName, path ), + track.ValueTypeName, track.getValueSize() ); - dispose() {// Empty here in base class; some subclasses override. - } + ++ binding.referenceCount; + this._addInactiveBinding( binding, rootUuid, trackName ); - copy(source, recursive) { - super.copy(source, recursive); - this.color.copy(source.color); - this.intensity = source.intensity; - return this; - } + bindings[ i ] = binding; - toJSON(meta) { - const data = super.toJSON(meta); - data.object.color = this.color.getHex(); - data.object.intensity = this.intensity; - if (this.groundColor !== undefined) data.object.groundColor = this.groundColor.getHex(); - if (this.distance !== undefined) data.object.distance = this.distance; - if (this.angle !== undefined) data.object.angle = this.angle; - if (this.decay !== undefined) data.object.decay = this.decay; - if (this.penumbra !== undefined) data.object.penumbra = this.penumbra; - if (this.shadow !== undefined) data.object.shadow = this.shadow.toJSON(); - return data; - } + } - } + interpolants[ i ].resultBuffer = binding.buffer; - class HemisphereLight extends Light { - constructor(skyColor, groundColor, intensity) { - super(skyColor, intensity); - this.isHemisphereLight = true; - this.type = 'HemisphereLight'; - this.position.copy(Object3D.DefaultUp); - 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(); + _activateAction( action ) { - const _lightPositionWorld$1 = /*@__PURE__*/new Vector3(); + if ( ! this._isActiveAction( action ) ) { - const _lookTarget$1 = /*@__PURE__*/new Vector3(); + if ( action._cacheIndex === null ) { - class LightShadow { - constructor(camera) { - this.camera = camera; - this.bias = 0; - this.normalBias = 0; - this.radius = 1; - this.blurSamples = 8; - this.mapSize = new Vector2(512, 512); - this.map = null; - this.mapPass = null; - this.matrix = new Matrix4(); - this.autoUpdate = true; - this.needsUpdate = false; - this._frustum = new Frustum(); - this._frameExtents = new Vector2(1, 1); - this._viewportCount = 1; - this._viewports = [new Vector4(0, 0, 1, 1)]; - } + // this action has been forgotten by the cache, but the user + // appears to be still using it -> rebind - getViewportCount() { - return this._viewportCount; - } + const rootUuid = ( action._localRoot || this._root ).uuid, + clipUuid = action._clip.uuid, + actionsForClip = this._actionsByClip[ clipUuid ]; - getFrustum() { - return this._frustum; - } + this._bindAction( action, + actionsForClip && actionsForClip.knownActions[ 0 ] ); - updateMatrices(light) { - const shadowCamera = this.camera; - const shadowMatrix = this.matrix; + this._addInactiveAction( action, clipUuid, rootUuid ); - _lightPositionWorld$1.setFromMatrixPosition(light.matrixWorld); + } - shadowCamera.position.copy(_lightPositionWorld$1); + const bindings = action._propertyBindings; - _lookTarget$1.setFromMatrixPosition(light.target.matrixWorld); + // increment reference counts / sort out state + for ( let i = 0, n = bindings.length; i !== n; ++ i ) { - shadowCamera.lookAt(_lookTarget$1); - shadowCamera.updateMatrixWorld(); + const binding = bindings[ i ]; - _projScreenMatrix$1.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse); + if ( binding.useCount ++ === 0 ) { - this._frustum.setFromProjectionMatrix(_projScreenMatrix$1); + this._lendBinding( binding ); + binding.saveOriginalState(); - shadowMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0); - shadowMatrix.multiply(shadowCamera.projectionMatrix); - shadowMatrix.multiply(shadowCamera.matrixWorldInverse); - } + } - getViewport(viewportIndex) { - return this._viewports[viewportIndex]; - } + } - getFrameExtents() { - return this._frameExtents; - } + this._lendAction( action ); - dispose() { - if (this.map) { - this.map.dispose(); } - if (this.mapPass) { - this.mapPass.dispose(); - } } - copy(source) { - this.camera = source.camera.clone(); - this.bias = source.bias; - this.radius = source.radius; - this.mapSize.copy(source.mapSize); - return this; - } + _deactivateAction( action ) { - clone() { - return new this.constructor().copy(this); - } + if ( this._isActiveAction( action ) ) { - toJSON() { - const object = {}; - if (this.bias !== 0) object.bias = this.bias; - if (this.normalBias !== 0) object.normalBias = this.normalBias; - if (this.radius !== 1) object.radius = this.radius; - if (this.mapSize.x !== 512 || this.mapSize.y !== 512) object.mapSize = this.mapSize.toArray(); - object.camera = this.camera.toJSON(false).object; - delete object.camera.matrix; - return object; - } + const bindings = action._propertyBindings; - } + // decrement reference counts / sort out state + for ( let i = 0, n = bindings.length; i !== n; ++ i ) { - class SpotLightShadow extends LightShadow { - constructor() { - super(new PerspectiveCamera(50, 1, 0.5, 500)); - this.isSpotLightShadow = true; - this.focus = 1; - } + const binding = bindings[ i ]; - 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 ( -- binding.useCount === 0 ) { - if (fov !== camera.fov || aspect !== camera.aspect || far !== camera.far) { - camera.fov = fov; - camera.aspect = aspect; - camera.far = far; - camera.updateProjectionMatrix(); - } + binding.restoreOriginalState(); + this._takeBackBinding( binding ); - super.updateMatrices(light); - } + } - copy(source) { - super.copy(source); - this.focus = source.focus; - return this; - } + } - } + this._takeBackAction( action ); - class SpotLight extends Light { - constructor(color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 1) { - super(color, intensity); - this.isSpotLight = true; - this.type = 'SpotLight'; - this.position.copy(Object3D.DefaultUp); - this.updateMatrix(); - this.target = new Object3D(); - this.distance = distance; - this.angle = angle; - this.penumbra = penumbra; - this.decay = decay; // for physically correct lights, should be 2. + } - 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; - } + // Memory manager - set power(power) { - // set the light's intensity (in candela) from the desired luminous power (in lumens) - this.intensity = power / Math.PI; - } + _initMemoryManager() { - dispose() { - this.shadow.dispose(); - } + this._actions = []; // 'nActiveActions' followed by inactive ones + this._nActiveActions = 0; - copy(source, recursive) { - super.copy(source, recursive); - this.distance = source.distance; - this.angle = source.angle; - this.penumbra = source.penumbra; - this.decay = source.decay; - this.target = source.target.clone(); - this.shadow = source.shadow.clone(); - return this; - } + this._actionsByClip = {}; + // inside: + // { + // knownActions: Array< AnimationAction > - used as prototypes + // actionByRoot: AnimationAction - lookup + // } - } - const _projScreenMatrix = /*@__PURE__*/new Matrix4(); + this._bindings = []; // 'nActiveBindings' followed by inactive ones + this._nActiveBindings = 0; - const _lightPositionWorld = /*@__PURE__*/new Vector3(); + this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer > - 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 - // following orientation: - // - // xzXZ - // y Y - // - // X - Positive x direction - // x - Negative x direction - // Y - Positive y direction - // y - Negative y direction - // Z - Positive z direction - // z - Negative z direction - // positive X - new Vector4(2, 1, 1, 1), // negative X - new Vector4(0, 1, 1, 1), // positive Z - new Vector4(3, 1, 1, 1), // negative Z - new Vector4(1, 1, 1, 1), // positive Y - new Vector4(3, 0, 1, 1), // negative Y - new Vector4(1, 0, 1, 1)]; - this._cubeDirections = [new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1), new Vector3(0, 1, 0), new Vector3(0, -1, 0)]; - this._cubeUps = [new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1)]; - } - - updateMatrices(light, viewportIndex = 0) { - const camera = this.camera; - const shadowMatrix = this.matrix; - const far = light.distance || camera.far; + this._controlInterpolants = []; // same game as above + this._nActiveControlInterpolants = 0; - if (far !== camera.far) { - camera.far = far; - camera.updateProjectionMatrix(); - } + const scope = this; - _lightPositionWorld.setFromMatrixPosition(light.matrixWorld); + this.stats = { - camera.position.copy(_lightPositionWorld); + actions: { + get total() { - _lookTarget.copy(camera.position); + return scope._actions.length; - _lookTarget.add(this._cubeDirections[viewportIndex]); + }, + get inUse() { - camera.up.copy(this._cubeUps[viewportIndex]); - camera.lookAt(_lookTarget); - camera.updateMatrixWorld(); - shadowMatrix.makeTranslation(-_lightPositionWorld.x, -_lightPositionWorld.y, -_lightPositionWorld.z); + return scope._nActiveActions; - _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); + } + }, + bindings: { + get total() { - this._frustum.setFromProjectionMatrix(_projScreenMatrix); - } + return scope._bindings.length; - } + }, + get inUse() { - class PointLight extends Light { - constructor(color, intensity, distance = 0, decay = 1) { - super(color, intensity); - this.isPointLight = true; - this.type = 'PointLight'; - this.distance = distance; - this.decay = decay; // for physically correct lights, should be 2. + return scope._nActiveBindings; - this.shadow = new PointLightShadow(); - } + } + }, + controlInterpolants: { + get total() { - 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; - } + return scope._controlInterpolants.length; - set power(power) { - // set the light's intensity (in candela) from the desired luminous power (in lumens) - this.intensity = power / (4 * Math.PI); - } + }, + get inUse() { - dispose() { - this.shadow.dispose(); - } + return scope._nActiveControlInterpolants; - copy(source, recursive) { - super.copy(source, recursive); - this.distance = source.distance; - this.decay = source.decay; - this.shadow = source.shadow.clone(); - return this; - } + } + } - } + }; - class DirectionalLightShadow extends LightShadow { - constructor() { - super(new OrthographicCamera(-5, 5, 5, -5, 0.5, 500)); - this.isDirectionalLightShadow = true; } - } + // Memory management for AnimationAction objects - class DirectionalLight extends Light { - constructor(color, intensity) { - super(color, intensity); - this.isDirectionalLight = true; - this.type = 'DirectionalLight'; - this.position.copy(Object3D.DefaultUp); - this.updateMatrix(); - this.target = new Object3D(); - this.shadow = new DirectionalLightShadow(); - } + _isActiveAction( action ) { - dispose() { - this.shadow.dispose(); - } + const index = action._cacheIndex; + return index !== null && index < this._nActiveActions; - copy(source) { - super.copy(source); - this.target = source.target.clone(); - this.shadow = source.shadow.clone(); - return this; } - } + _addInactiveAction( action, clipUuid, rootUuid ) { - class AmbientLight extends Light { - constructor(color, intensity) { - super(color, intensity); - this.isAmbientLight = true; - this.type = 'AmbientLight'; - } + const actions = this._actions, + actionsByClip = this._actionsByClip; - } + let actionsForClip = actionsByClip[ clipUuid ]; - class RectAreaLight extends Light { - constructor(color, intensity, width = 10, height = 10) { - super(color, intensity); - this.isRectAreaLight = true; - this.type = 'RectAreaLight'; - this.width = width; - this.height = height; - } + if ( actionsForClip === undefined ) { - get power() { - // compute the light's luminous power (in lumens) from its intensity (in nits) - return this.intensity * this.width * this.height * Math.PI; - } + actionsForClip = { - 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); - } + knownActions: [ action ], + actionByRoot: {} - 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; - } + action._byClipCacheIndex = 0; + + actionsByClip[ clipUuid ] = actionsForClip; - } + } else { - /** - * Primary reference: - * https://graphics.stanford.edu/papers/envmap/envmap.pdf - * - * Secondary reference: - * https://www.ppsloan.org/publications/StupidSH36.pdf - */ - // 3-band SH defined by 9 coefficients + const knownActions = actionsForClip.knownActions; - class SphericalHarmonics3 { - constructor() { - this.isSphericalHarmonics3 = true; - this.coefficients = []; + action._byClipCacheIndex = knownActions.length; + knownActions.push( action ); - 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]); - } + action._cacheIndex = actions.length; + actions.push( action ); + + actionsForClip.actionByRoot[ rootUuid ] = action; - return this; } - zero() { - for (let i = 0; i < 9; i++) { - this.coefficients[i].set(0, 0, 0); - } + _removeInactiveAction( action ) { - return this; - } // get the radiance in the direction of the normal - // target is a Vector3 + const actions = this._actions, + lastInactiveAction = actions[ actions.length - 1 ], + cacheIndex = action._cacheIndex; + lastInactiveAction._cacheIndex = cacheIndex; + actions[ cacheIndex ] = lastInactiveAction; + actions.pop(); - 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 - - target.copy(coeff[0]).multiplyScalar(0.282095); // band 1 - - target.addScaledVector(coeff[1], 0.488603 * y); - target.addScaledVector(coeff[2], 0.488603 * z); - target.addScaledVector(coeff[3], 0.488603 * x); // band 2 - - target.addScaledVector(coeff[4], 1.092548 * (x * y)); - target.addScaledVector(coeff[5], 1.092548 * (y * z)); - target.addScaledVector(coeff[6], 0.315392 * (3.0 * z * z - 1.0)); - target.addScaledVector(coeff[7], 1.092548 * (x * z)); - target.addScaledVector(coeff[8], 0.546274 * (x * x - y * y)); - return target; - } // get the irradiance (radiance convolved with cosine lobe) in the direction of the normal - // target is a Vector3 - // https://graphics.stanford.edu/papers/envmap/envmap.pdf + action._cacheIndex = null; - 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 + const clipUuid = action._clip.uuid, + actionsByClip = this._actionsByClip, + actionsForClip = actionsByClip[ clipUuid ], + knownActionsForClip = actionsForClip.knownActions, - target.copy(coeff[0]).multiplyScalar(0.886227); // π * 0.282095 - // band 1 + lastKnownAction = + knownActionsForClip[ knownActionsForClip.length - 1 ], - target.addScaledVector(coeff[1], 2.0 * 0.511664 * y); // ( 2 * π / 3 ) * 0.488603 + byClipCacheIndex = action._byClipCacheIndex; - target.addScaledVector(coeff[2], 2.0 * 0.511664 * z); - target.addScaledVector(coeff[3], 2.0 * 0.511664 * x); // band 2 + lastKnownAction._byClipCacheIndex = byClipCacheIndex; + knownActionsForClip[ byClipCacheIndex ] = lastKnownAction; + knownActionsForClip.pop(); - target.addScaledVector(coeff[4], 2.0 * 0.429043 * x * y); // ( π / 4 ) * 1.092548 + action._byClipCacheIndex = null; - 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 + const actionByRoot = actionsForClip.actionByRoot, + rootUuid = ( action._localRoot || this._root ).uuid; - return target; - } + delete actionByRoot[ rootUuid ]; - add(sh) { - for (let i = 0; i < 9; i++) { - this.coefficients[i].add(sh.coefficients[i]); - } + if ( knownActionsForClip.length === 0 ) { - return this; - } + delete actionsByClip[ clipUuid ]; - 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); - } + this._removeInactiveBindingsForAction( action ); - return this; } - lerp(sh, alpha) { - for (let i = 0; i < 9; i++) { - this.coefficients[i].lerp(sh.coefficients[i], alpha); - } + _removeInactiveBindingsForAction( action ) { - return this; - } + const bindings = action._propertyBindings; - equals(sh) { - for (let i = 0; i < 9; i++) { - if (!this.coefficients[i].equals(sh.coefficients[i])) { - return false; - } - } + for ( let i = 0, n = bindings.length; i !== n; ++ i ) { - return true; - } + const binding = bindings[ i ]; - copy(sh) { - return this.set(sh.coefficients); - } + if ( -- binding.referenceCount === 0 ) { - clone() { - return new this.constructor().copy(this); - } + this._removeInactiveBinding( binding ); - 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; + _lendAction( action ) { - for (let i = 0; i < 9; i++) { - coefficients[i].toArray(array, offset + i * 3); - } + // [ active actions | inactive actions ] + // [ active actions >| inactive actions ] + // s a + // <-swap-> + // a s - return array; - } // evaluate the basis functions - // shBasis is an Array[ 9 ] + const actions = this._actions, + prevIndex = action._cacheIndex, + lastActiveIndex = this._nActiveActions ++, - static getBasisAt(normal, shBasis) { - // normal is assumed to be unit length - const x = normal.x, - y = normal.y, - z = normal.z; // band 0 + firstInactiveAction = actions[ lastActiveIndex ]; - shBasis[0] = 0.282095; // band 1 + action._cacheIndex = lastActiveIndex; + actions[ lastActiveIndex ] = action; - shBasis[1] = 0.488603 * y; - shBasis[2] = 0.488603 * z; - shBasis[3] = 0.488603 * x; // band 2 + firstInactiveAction._cacheIndex = prevIndex; + actions[ prevIndex ] = firstInactiveAction; - 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); } - } + _takeBackAction( action ) { - class LightProbe extends Light { - constructor(sh = new SphericalHarmonics3(), intensity = 1) { - super(undefined, intensity); - this.isLightProbe = true; - this.sh = sh; - } + // [ active actions | inactive actions ] + // [ active actions |< inactive actions ] + // a s + // <-swap-> + // s a - copy(source) { - super.copy(source); - this.sh.copy(source.sh); - return this; - } + const actions = this._actions, + prevIndex = action._cacheIndex, - fromJSON(json) { - this.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON(); + firstInactiveIndex = -- this._nActiveActions, - this.sh.fromArray(json.sh); - return this; - } + lastActiveAction = actions[ firstInactiveIndex ]; - toJSON(meta) { - const data = super.toJSON(meta); - data.object.sh = this.sh.toArray(); - return data; - } + action._cacheIndex = firstInactiveIndex; + actions[ firstInactiveIndex ] = action; - } + lastActiveAction._cacheIndex = prevIndex; + actions[ prevIndex ] = lastActiveAction; - class MaterialLoader extends Loader { - constructor(manager) { - super(manager); - this.textures = {}; } - load(url, onLoad, onProgress, onError) { - const scope = this; - const loader = new FileLoader(scope.manager); - loader.setPath(scope.path); - loader.setRequestHeader(scope.requestHeader); - loader.setWithCredentials(scope.withCredentials); - loader.load(url, function (text) { - try { - onLoad(scope.parse(JSON.parse(text))); - } catch (e) { - if (onError) { - onError(e); - } else { - console.error(e); - } + // Memory management for PropertyMixer objects - scope.manager.itemError(url); - } - }, onProgress, onError); - } + _addInactiveBinding( binding, rootUuid, trackName ) { - parse(json) { - const textures = this.textures; + const bindingsByRoot = this._bindingsByRootAndName, + bindings = this._bindings; - function getTexture(name) { - if (textures[name] === undefined) { - console.warn('THREE.MaterialLoader: Undefined texture', name); - } - - return textures[name]; - } - - const material = Material.fromType(json.type); - if (json.uuid !== undefined) material.uuid = json.uuid; - if (json.name !== undefined) material.name = json.name; - if (json.color !== undefined && material.color !== undefined) material.color.setHex(json.color); - if (json.roughness !== undefined) material.roughness = json.roughness; - if (json.metalness !== undefined) material.metalness = json.metalness; - if (json.sheen !== undefined) material.sheen = json.sheen; - if (json.sheenColor !== undefined) material.sheenColor = new Color().setHex(json.sheenColor); - if (json.sheenRoughness !== undefined) material.sheenRoughness = json.sheenRoughness; - if (json.emissive !== undefined && material.emissive !== undefined) material.emissive.setHex(json.emissive); - if (json.specular !== undefined && material.specular !== undefined) material.specular.setHex(json.specular); - if (json.specularIntensity !== undefined) material.specularIntensity = json.specularIntensity; - if (json.specularColor !== undefined && material.specularColor !== undefined) material.specularColor.setHex(json.specularColor); - if (json.shininess !== undefined) material.shininess = json.shininess; - if (json.clearcoat !== undefined) material.clearcoat = json.clearcoat; - if (json.clearcoatRoughness !== undefined) material.clearcoatRoughness = json.clearcoatRoughness; - if (json.iridescence !== undefined) material.iridescence = json.iridescence; - if (json.iridescenceIOR !== undefined) material.iridescenceIOR = json.iridescenceIOR; - if (json.iridescenceThicknessRange !== undefined) material.iridescenceThicknessRange = json.iridescenceThicknessRange; - if (json.transmission !== undefined) material.transmission = json.transmission; - if (json.thickness !== undefined) material.thickness = json.thickness; - if (json.attenuationDistance !== undefined) material.attenuationDistance = json.attenuationDistance; - if (json.attenuationColor !== undefined && material.attenuationColor !== undefined) material.attenuationColor.setHex(json.attenuationColor); - if (json.fog !== undefined) material.fog = json.fog; - if (json.flatShading !== undefined) material.flatShading = json.flatShading; - if (json.blending !== undefined) material.blending = json.blending; - if (json.combine !== undefined) material.combine = json.combine; - if (json.side !== undefined) material.side = json.side; - if (json.shadowSide !== undefined) material.shadowSide = json.shadowSide; - if (json.opacity !== undefined) material.opacity = json.opacity; - if (json.transparent !== undefined) material.transparent = json.transparent; - if (json.alphaTest !== undefined) material.alphaTest = json.alphaTest; - if (json.depthTest !== undefined) material.depthTest = json.depthTest; - if (json.depthWrite !== undefined) material.depthWrite = json.depthWrite; - if (json.colorWrite !== undefined) material.colorWrite = json.colorWrite; - if (json.stencilWrite !== undefined) material.stencilWrite = json.stencilWrite; - if (json.stencilWriteMask !== undefined) material.stencilWriteMask = json.stencilWriteMask; - if (json.stencilFunc !== undefined) material.stencilFunc = json.stencilFunc; - if (json.stencilRef !== undefined) material.stencilRef = json.stencilRef; - if (json.stencilFuncMask !== undefined) material.stencilFuncMask = json.stencilFuncMask; - if (json.stencilFail !== undefined) material.stencilFail = json.stencilFail; - if (json.stencilZFail !== undefined) material.stencilZFail = json.stencilZFail; - if (json.stencilZPass !== undefined) material.stencilZPass = json.stencilZPass; - if (json.wireframe !== undefined) material.wireframe = json.wireframe; - if (json.wireframeLinewidth !== undefined) material.wireframeLinewidth = json.wireframeLinewidth; - if (json.wireframeLinecap !== undefined) material.wireframeLinecap = json.wireframeLinecap; - if (json.wireframeLinejoin !== undefined) material.wireframeLinejoin = json.wireframeLinejoin; - if (json.rotation !== undefined) material.rotation = json.rotation; - if (json.linewidth !== 1) material.linewidth = json.linewidth; - if (json.dashSize !== undefined) material.dashSize = json.dashSize; - if (json.gapSize !== undefined) material.gapSize = json.gapSize; - if (json.scale !== undefined) material.scale = json.scale; - if (json.polygonOffset !== undefined) material.polygonOffset = json.polygonOffset; - if (json.polygonOffsetFactor !== undefined) material.polygonOffsetFactor = json.polygonOffsetFactor; - if (json.polygonOffsetUnits !== undefined) material.polygonOffsetUnits = json.polygonOffsetUnits; - if (json.dithering !== undefined) material.dithering = json.dithering; - if (json.alphaToCoverage !== undefined) material.alphaToCoverage = json.alphaToCoverage; - if (json.premultipliedAlpha !== undefined) material.premultipliedAlpha = json.premultipliedAlpha; - 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 + let bindingByName = bindingsByRoot[ rootUuid ]; + if ( bindingByName === undefined ) { - if (json.uniforms !== undefined) { - for (const name in json.uniforms) { - const uniform = json.uniforms[name]; - material.uniforms[name] = {}; + bindingByName = {}; + bindingsByRoot[ rootUuid ] = bindingByName; - 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; + bindingByName[ trackName ] = binding; - case 'v2': - material.uniforms[name].value = new Vector2().fromArray(uniform.value); - break; + binding._cacheIndex = bindings.length; + bindings.push( binding ); - case 'v3': - material.uniforms[name].value = new Vector3().fromArray(uniform.value); - break; + } - case 'v4': - material.uniforms[name].value = new Vector4().fromArray(uniform.value); - break; + _removeInactiveBinding( binding ) { - case 'm3': - material.uniforms[name].value = new Matrix3().fromArray(uniform.value); - break; + const bindings = this._bindings, + propBinding = binding.binding, + rootUuid = propBinding.rootNode.uuid, + trackName = propBinding.path, + bindingsByRoot = this._bindingsByRootAndName, + bindingByName = bindingsByRoot[ rootUuid ], - case 'm4': - material.uniforms[name].value = new Matrix4().fromArray(uniform.value); - break; + 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 ]; - 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.extensions !== undefined) { - for (const key in json.extensions) { - material.extensions[key] = json.extensions[key]; - } - } // Deprecated + _lendBinding( binding ) { + const bindings = this._bindings, + prevIndex = binding._cacheIndex, - if (json.shading !== undefined) material.flatShading = json.shading === 1; // THREE.FlatShading - // for PointsMaterial + lastActiveIndex = this._nActiveBindings ++, - if (json.size !== undefined) material.size = json.size; - if (json.sizeAttenuation !== undefined) material.sizeAttenuation = json.sizeAttenuation; // maps + firstInactiveBinding = bindings[ lastActiveIndex ]; - if (json.map !== undefined) material.map = getTexture(json.map); - if (json.matcap !== undefined) material.matcap = getTexture(json.matcap); - if (json.alphaMap !== undefined) material.alphaMap = getTexture(json.alphaMap); - if (json.bumpMap !== undefined) material.bumpMap = getTexture(json.bumpMap); - if (json.bumpScale !== undefined) material.bumpScale = json.bumpScale; - if (json.normalMap !== undefined) material.normalMap = getTexture(json.normalMap); - if (json.normalMapType !== undefined) material.normalMapType = json.normalMapType; + binding._cacheIndex = lastActiveIndex; + bindings[ lastActiveIndex ] = binding; - if (json.normalScale !== undefined) { - let normalScale = json.normalScale; + firstInactiveBinding._cacheIndex = prevIndex; + bindings[ prevIndex ] = firstInactiveBinding; - 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; - if (json.roughnessMap !== undefined) material.roughnessMap = getTexture(json.roughnessMap); - if (json.metalnessMap !== undefined) material.metalnessMap = getTexture(json.metalnessMap); - if (json.emissiveMap !== undefined) material.emissiveMap = getTexture(json.emissiveMap); - if (json.emissiveIntensity !== undefined) material.emissiveIntensity = json.emissiveIntensity; - if (json.specularMap !== undefined) material.specularMap = getTexture(json.specularMap); - if (json.specularIntensityMap !== undefined) material.specularIntensityMap = getTexture(json.specularIntensityMap); - if (json.specularColorMap !== undefined) material.specularColorMap = getTexture(json.specularColorMap); - if (json.envMap !== undefined) material.envMap = getTexture(json.envMap); - if (json.envMapIntensity !== undefined) material.envMapIntensity = json.envMapIntensity; - if (json.reflectivity !== undefined) material.reflectivity = json.reflectivity; - if (json.refractionRatio !== undefined) material.refractionRatio = json.refractionRatio; - if (json.lightMap !== undefined) material.lightMap = getTexture(json.lightMap); - if (json.lightMapIntensity !== undefined) material.lightMapIntensity = json.lightMapIntensity; - if (json.aoMap !== undefined) material.aoMap = getTexture(json.aoMap); - if (json.aoMapIntensity !== undefined) material.aoMapIntensity = json.aoMapIntensity; - if (json.gradientMap !== undefined) material.gradientMap = getTexture(json.gradientMap); - if (json.clearcoatMap !== undefined) material.clearcoatMap = getTexture(json.clearcoatMap); - if (json.clearcoatRoughnessMap !== undefined) material.clearcoatRoughnessMap = getTexture(json.clearcoatRoughnessMap); - if (json.clearcoatNormalMap !== undefined) material.clearcoatNormalMap = getTexture(json.clearcoatNormalMap); - if (json.clearcoatNormalScale !== undefined) material.clearcoatNormalScale = new Vector2().fromArray(json.clearcoatNormalScale); - if (json.iridescenceMap !== undefined) material.iridescenceMap = getTexture(json.iridescenceMap); - if (json.iridescenceThicknessMap !== undefined) material.iridescenceThicknessMap = getTexture(json.iridescenceThicknessMap); - if (json.transmissionMap !== undefined) material.transmissionMap = getTexture(json.transmissionMap); - if (json.thicknessMap !== undefined) material.thicknessMap = getTexture(json.thicknessMap); - if (json.sheenColorMap !== undefined) material.sheenColorMap = getTexture(json.sheenColorMap); - if (json.sheenRoughnessMap !== undefined) material.sheenRoughnessMap = getTexture(json.sheenRoughnessMap); - return material; } - setTextures(value) { - this.textures = value; - return this; - } + _takeBackBinding( binding ) { - } + const bindings = this._bindings, + prevIndex = binding._cacheIndex, - 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. + firstInactiveIndex = -- this._nActiveBindings, + lastActiveBinding = bindings[ firstInactiveIndex ]; - let s = ''; + binding._cacheIndex = firstInactiveIndex; + bindings[ firstInactiveIndex ] = binding; - for (let i = 0, il = array.length; i < il; i++) { - // Implicitly assumes little-endian. - s += String.fromCharCode(array[i]); - } + lastActiveBinding._cacheIndex = prevIndex; + bindings[ prevIndex ] = lastActiveBinding; - 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 + // Memory management of Interpolants for weight and time scale - if (/^https?:\/\//i.test(path) && /^\//.test(url)) { - path = path.replace(/(^https?:\/\/[^\/]+).*/i, '$1'); - } // Absolute URL http://,https://,// + _lendControlInterpolant() { + const interpolants = this._controlInterpolants, + lastActiveIndex = this._nActiveControlInterpolants ++; - if (/^(https?:)?\/\//i.test(url)) return url; // Data URI + let interpolant = interpolants[ lastActiveIndex ]; - if (/^data:.*,.*$/i.test(url)) return url; // Blob URL + if ( interpolant === undefined ) { - if (/^blob:.*$/i.test(url)) return url; // Relative URL + interpolant = new LinearInterpolant( + new Float32Array( 2 ), new Float32Array( 2 ), + 1, _controlInterpolantsResultBuffer ); - return path + url; - } + interpolant.__cacheIndex = lastActiveIndex; + interpolants[ lastActiveIndex ] = interpolant; - } + } - class InstancedBufferGeometry extends BufferGeometry { - constructor() { - super(); - this.isInstancedBufferGeometry = true; - this.type = 'InstancedBufferGeometry'; - this.instanceCount = Infinity; - } + return interpolant; - copy(source) { - super.copy(source); - this.instanceCount = source.instanceCount; - return this; } - clone() { - return new this.constructor().copy(this); - } + _takeBackControlInterpolant( interpolant ) { - toJSON() { - const data = super.toJSON(this); - data.instanceCount = this.instanceCount; - data.isInstancedBufferGeometry = true; - return data; - } + const interpolants = this._controlInterpolants, + prevIndex = interpolant.__cacheIndex, - } + firstInactiveIndex = -- this._nActiveControlInterpolants, - class BufferGeometryLoader extends Loader { - constructor(manager) { - super(manager); - } + lastActiveInterpolant = interpolants[ firstInactiveIndex ]; - load(url, onLoad, onProgress, onError) { - const scope = this; - const loader = new FileLoader(scope.manager); - loader.setPath(scope.path); - loader.setRequestHeader(scope.requestHeader); - loader.setWithCredentials(scope.withCredentials); - loader.load(url, function (text) { - try { - onLoad(scope.parse(JSON.parse(text))); - } catch (e) { - if (onError) { - onError(e); - } else { - console.error(e); - } + interpolant.__cacheIndex = firstInactiveIndex; + interpolants[ firstInactiveIndex ] = interpolant; + + lastActiveInterpolant.__cacheIndex = prevIndex; + interpolants[ prevIndex ] = lastActiveInterpolant; - scope.manager.itemError(url); - } - }, onProgress, onError); } - parse(json) { - const interleavedBufferMap = {}; - const arrayBufferMap = {}; + // 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 ) { - function getInterleavedBuffer(json, uuid) { - if (interleavedBufferMap[uuid] !== undefined) return interleavedBufferMap[uuid]; - const interleavedBuffers = json.interleavedBuffers; - const interleavedBuffer = interleavedBuffers[uuid]; - const buffer = getArrayBuffer(json, interleavedBuffer.buffer); - const array = getTypedArray(interleavedBuffer.type, buffer); - const ib = new InterleavedBuffer(array, interleavedBuffer.stride); - ib.uuid = interleavedBuffer.uuid; - interleavedBufferMap[uuid] = ib; - return ib; - } + const root = optionalRoot || this._root, + rootUuid = root.uuid; - function getArrayBuffer(json, uuid) { - if (arrayBufferMap[uuid] !== undefined) return arrayBufferMap[uuid]; - const arrayBuffers = json.arrayBuffers; - const arrayBuffer = arrayBuffers[uuid]; - const ab = new Uint32Array(arrayBuffer).buffer; - arrayBufferMap[uuid] = ab; - return ab; - } + let clipObject = typeof clip === 'string' ? AnimationClip.findByName( root, clip ) : clip; - const geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry(); - const index = json.data.index; + const clipUuid = clipObject !== null ? clipObject.uuid : clip; - if (index !== undefined) { - const typedArray = getTypedArray(index.type, index.array); - geometry.setIndex(new BufferAttribute(typedArray, 1)); - } + const actionsForClip = this._actionsByClip[ clipUuid ]; + let prototypeAction = null; - const attributes = json.data.attributes; + if ( blendMode === undefined ) { - for (const key in attributes) { - const attribute = attributes[key]; - let bufferAttribute; + if ( clipObject !== null ) { + + blendMode = clipObject.blendMode; - if (attribute.isInterleavedBufferAttribute) { - const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data); - bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized); } else { - const typedArray = getTypedArray(attribute.type, attribute.array); - 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); + blendMode = NormalAnimationBlendMode; - 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 = []; + if ( actionsForClip !== undefined ) { - for (let i = 0, il = attributeArray.length; i < il; i++) { - const attribute = attributeArray[i]; - let bufferAttribute; + const existingAction = actionsForClip.actionByRoot[ rootUuid ]; - if (attribute.isInterleavedBufferAttribute) { - const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data); - bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized); - } else { - const typedArray = getTypedArray(attribute.type, attribute.array); - bufferAttribute = new BufferAttribute(typedArray, attribute.itemSize, attribute.normalized); - } + if ( existingAction !== undefined && existingAction.blendMode === blendMode ) { - if (attribute.name !== undefined) bufferAttribute.name = attribute.name; - array.push(bufferAttribute); - } + return existingAction; - geometry.morphAttributes[key] = array; } - } - - const morphTargetsRelative = json.data.morphTargetsRelative; - if (morphTargetsRelative) { - geometry.morphTargetsRelative = true; - } + // we know the clip, so we don't have to parse all + // the bindings again but can just copy + prototypeAction = actionsForClip.knownActions[ 0 ]; - const groups = json.data.groups || json.data.drawcalls || json.data.offsets; + // also, take the clip from the prototype action + if ( clipObject === null ) + clipObject = prototypeAction._clip; - 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; + // clip must be known when specified via string + if ( clipObject === null ) return null; - if (boundingSphere !== undefined) { - const center = new Vector3(); + // allocate all resources required to run it + const newAction = new AnimationAction( this, clipObject, optionalRoot, blendMode ); - if (boundingSphere.center !== undefined) { - center.fromArray(boundingSphere.center); - } + this._bindAction( newAction, prototypeAction ); - geometry.boundingSphere = new Sphere(center, boundingSphere.radius); - } + // and make the action known to the memory manager + this._addInactiveAction( newAction, clipUuid, rootUuid ); + + return newAction; - if (json.name) geometry.name = json.name; - if (json.userData) geometry.userData = json.userData; - return geometry; } - } + // get an existing action + existingAction( clip, optionalRoot ) { - class ObjectLoader extends Loader { - constructor(manager) { - super(manager); - } + const root = optionalRoot || this._root, + rootUuid = root.uuid, - load(url, onLoad, onProgress, onError) { - const scope = this; - const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path; - this.resourcePath = this.resourcePath || path; - const loader = new FileLoader(this.manager); - loader.setPath(this.path); - loader.setRequestHeader(this.requestHeader); - loader.setWithCredentials(this.withCredentials); - loader.load(url, function (text) { - let json = null; + clipObject = typeof clip === 'string' ? + AnimationClip.findByName( root, clip ) : clip, - try { - json = JSON.parse(text); - } catch (error) { - if (onError !== undefined) onError(error); - console.error('THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message); - return; - } + clipUuid = clipObject ? clipObject.uuid : clip, - const metadata = json.metadata; + actionsForClip = this._actionsByClip[ clipUuid ]; + + if ( actionsForClip !== undefined ) { + + return actionsForClip.actionByRoot[ rootUuid ] || null; + + } - if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') { - console.error('THREE.ObjectLoader: Can\'t load ' + url); - return; - } + return null; - scope.parse(json, onLoad); - }, onProgress, onError); } - async loadAsync(url, onProgress) { - const scope = this; - const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path; - this.resourcePath = this.resourcePath || path; - const loader = new FileLoader(this.manager); - loader.setPath(this.path); - loader.setRequestHeader(this.requestHeader); - loader.setWithCredentials(this.withCredentials); - const text = await loader.loadAsync(url, onProgress); - const json = JSON.parse(text); - const metadata = json.metadata; + // deactivates all previously scheduled actions + stopAllAction() { + + const actions = this._actions, + nActions = this._nActiveActions; + + for ( let i = nActions - 1; i >= 0; -- i ) { + + actions[ i ].stop(); - if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') { - throw new Error('THREE.ObjectLoader: Can\'t load ' + url); } - return await scope.parseAsync(json); + return this; + } - parse(json, onLoad) { - const animations = this.parseAnimations(json.animations); - const shapes = this.parseShapes(json.shapes); - const geometries = this.parseGeometries(json.geometries, shapes); - const images = this.parseImages(json.images, function () { - if (onLoad !== undefined) onLoad(object); - }); - const textures = this.parseTextures(json.textures, images); - 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); // + // advance the time and update apply the animation + update( deltaTime ) { - if (onLoad !== undefined) { - let hasImages = false; + deltaTime *= this.timeScale; - for (const uuid in images) { - if (images[uuid].data instanceof HTMLImageElement) { - hasImages = true; - break; - } - } + const actions = this._actions, + nActions = this._nActiveActions, - if (hasImages === false) onLoad(object); - } + time = this.time += deltaTime, + timeDirection = Math.sign( deltaTime ), - return object; - } + accuIndex = this._accuIndex ^= 1; - async parseAsync(json) { - const animations = this.parseAnimations(json.animations); - const shapes = this.parseShapes(json.shapes); - const geometries = this.parseGeometries(json.geometries, shapes); - const images = await this.parseImagesAsync(json.images); - const textures = this.parseTextures(json.textures, images); - 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); - return object; - } + // run active actions - parseShapes(json) { - const shapes = {}; + for ( let i = 0; i !== nActions; ++ i ) { + + const action = actions[ i ]; + + action._update( time, deltaTime, timeDirection, accuIndex ); - 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; - } + // update scene graph - parseSkeletons(json, object) { - const skeletons = {}; - const bones = {}; // generate bone lookup table + const bindings = this._bindings, + nBindings = this._nActiveBindings; - object.traverse(function (child) { - if (child.isBone) bones[child.uuid] = child; - }); // create skeletons + for ( let i = 0; i !== nBindings; ++ i ) { + + bindings[ i ].apply( accuIndex ); - if (json !== undefined) { - for (let i = 0, l = json.length; i < l; i++) { - const skeleton = new Skeleton().fromJSON(json[i], bones); - skeletons[skeleton.uuid] = skeleton; - } } - return skeletons; + return this; + } - parseGeometries(json, shapes) { - const geometries = {}; + // Allows you to seek to a specific time in an animation. + setTime( timeInSeconds ) { - if (json !== undefined) { - const bufferGeometryLoader = new BufferGeometryLoader(); + this.time = 0; // Zero out time attribute for AnimationMixer object; + for ( let i = 0; i < this._actions.length; i ++ ) { - for (let i = 0, l = json.length; i < l; i++) { - let geometry; - const data = json[i]; + this._actions[ i ].time = 0; // Zero out time attribute for all associated AnimationAction objects. - 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; + return this.update( timeInSeconds ); // Update used to set exact time. Returns "this" AnimationMixer object. - default: - if (data.type in Geometries) { - geometry = Geometries[data.type].fromJSON(data, shapes); - } else { - console.warn(`THREE.ObjectLoader: Unsupported geometry type "${data.type}"`); - } + } - } + // return this mixer's root target object + getRoot() { - 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 this._root; - return geometries; } - parseMaterials(json, textures) { - const cache = {}; // MultiMaterial + // free all resources specific to a particular clip + uncacheClip( clip ) { - const materials = {}; + const actions = this._actions, + clipUuid = clip.uuid, + actionsByClip = this._actionsByClip, + actionsForClip = actionsByClip[ clipUuid ]; - if (json !== undefined) { - const loader = new MaterialLoader(); - loader.setTextures(textures); + if ( actionsForClip !== undefined ) { - for (let i = 0, l = json.length; i < l; i++) { - const data = json[i]; + // note: just calling _removeInactiveAction would mess up the + // iteration state and also require updating the state we can + // just throw away - if (data.type === 'MultiMaterial') { - // Deprecated - const array = []; + const actionsToRemove = actionsForClip.knownActions; - for (let j = 0; j < data.materials.length; j++) { - const material = data.materials[j]; + for ( let i = 0, n = actionsToRemove.length; i !== n; ++ i ) { - if (cache[material.uuid] === undefined) { - cache[material.uuid] = loader.parse(material); - } + const action = actionsToRemove[ i ]; - array.push(cache[material.uuid]); - } + this._deactivateAction( action ); - materials[data.uuid] = array; - } else { - if (cache[data.uuid] === undefined) { - cache[data.uuid] = loader.parse(data); - } + const cacheIndex = action._cacheIndex, + lastInactiveAction = actions[ actions.length - 1 ]; - materials[data.uuid] = cache[data.uuid]; - } - } - } + action._cacheIndex = null; + action._byClipCacheIndex = null; - return materials; - } + lastInactiveAction._cacheIndex = cacheIndex; + actions[ cacheIndex ] = lastInactiveAction; + actions.pop(); - parseAnimations(json) { - const animations = {}; + this._removeInactiveBindingsForAction( action ); - if (json !== undefined) { - for (let i = 0; i < json.length; i++) { - const data = json[i]; - const clip = AnimationClip.parse(data); - animations[clip.uuid] = clip; } - } - - return animations; - } - parseImages(json, onLoad) { - const scope = this; - const images = {}; - let loader; + delete actionsByClip[ clipUuid ]; - function loadImage(url) { - scope.manager.itemStart(url); - return loader.load(url, function () { - scope.manager.itemEnd(url); - }, undefined, function () { - scope.manager.itemError(url); - scope.manager.itemEnd(url); - }); } - function deserializeImage(image) { - if (typeof image === 'string') { - const url = image; - const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test(url) ? url : scope.resourcePath + url; - return loadImage(path); - } else { - if (image.data) { - return { - data: getTypedArray(image.type, image.data), - width: image.width, - height: image.height - }; - } else { - return null; - } - } - } + } - if (json !== undefined && json.length > 0) { - const manager = new LoadingManager(onLoad); - loader = new ImageLoader(manager); - loader.setCrossOrigin(this.crossOrigin); + // free all resources specific to a particular root target object + uncacheRoot( root ) { - for (let i = 0, il = json.length; i < il; i++) { - const image = json[i]; - const url = image.url; + const rootUuid = root.uuid, + actionsByClip = this._actionsByClip; - if (Array.isArray(url)) { - // load array of images e.g CubeTexture - const imageArray = []; + for ( const clipUuid in actionsByClip ) { - for (let j = 0, jl = url.length; j < jl; j++) { - const currentUrl = url[j]; - const deserializedImage = deserializeImage(currentUrl); + const actionByRoot = actionsByClip[ clipUuid ].actionByRoot, + action = actionByRoot[ rootUuid ]; - 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)); - } - } - } + if ( action !== undefined ) { + + this._deactivateAction( action ); + this._removeInactiveAction( action ); - images[image.uuid] = new Source(imageArray); - } else { - // load single image - const deserializedImage = deserializeImage(image.url); - images[image.uuid] = new Source(deserializedImage); - } } + } - return images; - } + const bindingsByRoot = this._bindingsByRootAndName, + bindingByName = bindingsByRoot[ rootUuid ]; - async parseImagesAsync(json) { - const scope = this; - const images = {}; - let loader; + if ( bindingByName !== undefined ) { + + for ( const trackName in bindingByName ) { + + const binding = bindingByName[ trackName ]; + binding.restoreOriginalState(); + this._removeInactiveBinding( binding ); - async function deserializeImage(image) { - if (typeof image === 'string') { - const url = image; - const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test(url) ? url : scope.resourcePath + url; - return await loader.loadAsync(path); - } else { - if (image.data) { - return { - data: getTypedArray(image.type, image.data), - width: image.width, - height: image.height - }; - } else { - return null; - } } + } - 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; + // remove a targeted clip from the cache + uncacheAction( clip, optionalRoot ) { - if (Array.isArray(url)) { - // load array of images e.g CubeTexture - const imageArray = []; + const action = this.existingAction( clip, optionalRoot ); - for (let j = 0, jl = url.length; j < jl; j++) { - const currentUrl = url[j]; - const deserializedImage = await deserializeImage(currentUrl); + if ( action !== null ) { - 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)); - } - } - } + this._deactivateAction( action ); + this._removeInactiveAction( action ); - 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 = {}; + class Uniform { - if (json !== undefined) { - for (let i = 0, l = json.length; i < l; i++) { - const data = json[i]; + constructor( value ) { - if (data.image === undefined) { - console.warn('THREE.ObjectLoader: No "image" specified for', data.uuid); - } + this.value = value; - if (images[data.image] === undefined) { - console.warn('THREE.ObjectLoader: Undefined image', data.image); - } + } - const source = images[data.image]; - const image = source.data; - let texture; + clone() { - if (Array.isArray(image)) { - texture = new CubeTexture(); - if (image.length === 6) texture.needsUpdate = true; - } else { - if (image && image.data) { - texture = new DataTexture(); - } else { - texture = new Texture(); - } + return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() ); - if (image) texture.needsUpdate = true; // textures can have undefined image data - } + } - texture.source = source; - texture.uuid = data.uuid; - if (data.name !== undefined) texture.name = data.name; - if (data.mapping !== undefined) texture.mapping = parseConstant(data.mapping, TEXTURE_MAPPING); - if (data.offset !== undefined) texture.offset.fromArray(data.offset); - if (data.repeat !== undefined) texture.repeat.fromArray(data.repeat); - if (data.center !== undefined) texture.center.fromArray(data.center); - if (data.rotation !== undefined) texture.rotation = data.rotation; + } - if (data.wrap !== undefined) { - texture.wrapS = parseConstant(data.wrap[0], TEXTURE_WRAPPING); - texture.wrapT = parseConstant(data.wrap[1], TEXTURE_WRAPPING); - } + let id = 0; - if (data.format !== undefined) texture.format = data.format; - if (data.type !== undefined) texture.type = data.type; - if (data.encoding !== undefined) texture.encoding = data.encoding; - if (data.minFilter !== undefined) texture.minFilter = parseConstant(data.minFilter, TEXTURE_FILTER); - if (data.magFilter !== undefined) texture.magFilter = parseConstant(data.magFilter, TEXTURE_FILTER); - if (data.anisotropy !== undefined) texture.anisotropy = data.anisotropy; - if (data.flipY !== undefined) texture.flipY = data.flipY; - if (data.premultiplyAlpha !== undefined) texture.premultiplyAlpha = data.premultiplyAlpha; - if (data.unpackAlignment !== undefined) texture.unpackAlignment = data.unpackAlignment; - if (data.userData !== undefined) texture.userData = data.userData; - textures[data.uuid] = texture; - } - } + class UniformsGroup extends EventDispatcher { - return textures; - } + constructor() { - parseObject(data, geometries, materials, textures, animations) { - let object; + super(); - function getGeometry(name) { - if (geometries[name] === undefined) { - console.warn('THREE.ObjectLoader: Undefined geometry', name); - } + this.isUniformsGroup = true; - return geometries[name]; - } + Object.defineProperty( this, 'id', { value: id ++ } ); - function getMaterial(name) { - if (name === undefined) return undefined; + this.name = ''; - if (Array.isArray(name)) { - const array = []; + this.usage = StaticDrawUsage; + this.uniforms = []; - 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); - } + add( uniform ) { - array.push(materials[uuid]); - } + this.uniforms.push( uniform ); - return array; - } + return this; - if (materials[name] === undefined) { - console.warn('THREE.ObjectLoader: Undefined material', name); - } + } - return materials[name]; - } + remove( uniform ) { - function getTexture(uuid) { - if (textures[uuid] === undefined) { - console.warn('THREE.ObjectLoader: Undefined texture', uuid); - } + const index = this.uniforms.indexOf( uniform ); - return textures[uuid]; - } + if ( index !== - 1 ) this.uniforms.splice( index, 1 ); - let geometry, material; + return this; - switch (data.type) { - case 'Scene': - object = new Scene(); + } - if (data.background !== undefined) { - if (Number.isInteger(data.background)) { - object.background = new Color(data.background); - } else { - object.background = getTexture(data.background); - } - } + setName( name ) { - if (data.environment !== undefined) { - object.environment = getTexture(data.environment); - } + this.name = name; - if (data.fog !== undefined) { - if (data.fog.type === 'Fog') { - object.fog = new Fog(data.fog.color, data.fog.near, data.fog.far); - } else if (data.fog.type === 'FogExp2') { - object.fog = new FogExp2(data.fog.color, data.fog.density); - } - } + return this; - break; + } - case 'PerspectiveCamera': - object = new PerspectiveCamera(data.fov, data.aspect, data.near, data.far); - if (data.focus !== undefined) object.focus = data.focus; - if (data.zoom !== undefined) object.zoom = data.zoom; - if (data.filmGauge !== undefined) object.filmGauge = data.filmGauge; - if (data.filmOffset !== undefined) object.filmOffset = data.filmOffset; - if (data.view !== undefined) object.view = Object.assign({}, data.view); - break; + setUsage( value ) { - case 'OrthographicCamera': - object = new OrthographicCamera(data.left, data.right, data.top, data.bottom, data.near, data.far); - if (data.zoom !== undefined) object.zoom = data.zoom; - if (data.view !== undefined) object.view = Object.assign({}, data.view); - break; + this.usage = value; - case 'AmbientLight': - object = new AmbientLight(data.color, data.intensity); - break; + return this; - case 'DirectionalLight': - object = new DirectionalLight(data.color, data.intensity); - break; + } - case 'PointLight': - object = new PointLight(data.color, data.intensity, data.distance, data.decay); - break; + dispose() { - case 'RectAreaLight': - object = new RectAreaLight(data.color, data.intensity, data.width, data.height); - break; + this.dispatchEvent( { type: 'dispose' } ); - case 'SpotLight': - object = new SpotLight(data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay); - break; + return this; - case 'HemisphereLight': - object = new HemisphereLight(data.color, data.groundColor, data.intensity); - break; + } - case 'LightProbe': - object = new LightProbe().fromJSON(data); - break; + copy( source ) { - case 'SkinnedMesh': - geometry = getGeometry(data.geometry); - material = getMaterial(data.material); - object = new SkinnedMesh(geometry, material); - if (data.bindMode !== undefined) object.bindMode = data.bindMode; - if (data.bindMatrix !== undefined) object.bindMatrix.fromArray(data.bindMatrix); - if (data.skeleton !== undefined) object.skeleton = data.skeleton; - break; + this.name = source.name; + this.usage = source.usage; - case 'Mesh': - geometry = getGeometry(data.geometry); - material = getMaterial(data.material); - object = new Mesh(geometry, material); - break; + const uniformsSource = source.uniforms; - case 'InstancedMesh': - geometry = getGeometry(data.geometry); - material = getMaterial(data.material); - const count = data.count; - const instanceMatrix = data.instanceMatrix; - const instanceColor = data.instanceColor; - object = new InstancedMesh(geometry, material, count); - object.instanceMatrix = new InstancedBufferAttribute(new Float32Array(instanceMatrix.array), 16); - if (instanceColor !== undefined) object.instanceColor = new InstancedBufferAttribute(new Float32Array(instanceColor.array), instanceColor.itemSize); - break; + this.uniforms.length = 0; - case 'LOD': - object = new LOD(); - break; + for ( let i = 0, l = uniformsSource.length; i < l; i ++ ) { - case 'Line': - object = new Line(getGeometry(data.geometry), getMaterial(data.material)); - break; + this.uniforms.push( uniformsSource[ i ].clone() ); - case 'LineLoop': - object = new LineLoop(getGeometry(data.geometry), getMaterial(data.material)); - break; + } + + return this; + + } - case 'LineSegments': - object = new LineSegments(getGeometry(data.geometry), getMaterial(data.material)); - break; + clone() { - case 'PointCloud': - case 'Points': - object = new Points(getGeometry(data.geometry), getMaterial(data.material)); - break; + return new this.constructor().copy( this ); - case 'Sprite': - object = new Sprite(getMaterial(data.material)); - break; + } - case 'Group': - object = new Group(); - break; + } - case 'Bone': - object = new Bone(); - break; + class InstancedInterleavedBuffer extends InterleavedBuffer { - default: - object = new Object3D(); - } + constructor( array, stride, meshPerAttribute = 1 ) { - object.uuid = data.uuid; - if (data.name !== undefined) object.name = data.name; + super( array, stride ); - if (data.matrix !== undefined) { - object.matrix.fromArray(data.matrix); - if (data.matrixAutoUpdate !== undefined) object.matrixAutoUpdate = data.matrixAutoUpdate; - if (object.matrixAutoUpdate) object.matrix.decompose(object.position, object.quaternion, object.scale); - } else { - if (data.position !== undefined) object.position.fromArray(data.position); - if (data.rotation !== undefined) object.rotation.fromArray(data.rotation); - if (data.quaternion !== undefined) object.quaternion.fromArray(data.quaternion); - if (data.scale !== undefined) object.scale.fromArray(data.scale); - } + this.isInstancedInterleavedBuffer = true; - if (data.castShadow !== undefined) object.castShadow = data.castShadow; - if (data.receiveShadow !== undefined) object.receiveShadow = data.receiveShadow; + this.meshPerAttribute = meshPerAttribute; - if (data.shadow) { - if (data.shadow.bias !== undefined) object.shadow.bias = data.shadow.bias; - if (data.shadow.normalBias !== undefined) object.shadow.normalBias = data.shadow.normalBias; - if (data.shadow.radius !== undefined) object.shadow.radius = data.shadow.radius; - if (data.shadow.mapSize !== undefined) object.shadow.mapSize.fromArray(data.shadow.mapSize); - if (data.shadow.camera !== undefined) object.shadow.camera = this.parseObject(data.shadow.camera); - } + } - 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; + copy( source ) { - if (data.children !== undefined) { - const children = data.children; + super.copy( source ); - for (let i = 0; i < children.length; i++) { - object.add(this.parseObject(children[i], geometries, materials, textures, animations)); - } - } + this.meshPerAttribute = source.meshPerAttribute; - if (data.animations !== undefined) { - const objectAnimations = data.animations; + return this; - 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; + clone( data ) { - for (let l = 0; l < levels.length; l++) { - const level = levels[l]; - const child = object.getObjectByProperty('uuid', level.object); + const ib = super.clone( data ); - if (child !== undefined) { - object.addLevel(child, level.distance); - } - } - } + ib.meshPerAttribute = this.meshPerAttribute; + + return ib; - 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]; + toJSON( data ) { - if (skeleton === undefined) { - console.warn('THREE.ObjectLoader: No skeleton found with UUID:', child.skeleton); - } else { - child.bind(skeleton, child.bindMatrix); - } - } - }); - } - /* DEPRECATED */ + const json = super.toJSON( data ); + json.isInstancedInterleavedBuffer = true; + json.meshPerAttribute = this.meshPerAttribute; + + return json; - setTexturePath(value) { - console.warn('THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().'); - return this.setResourcePath(value); } } - const TEXTURE_MAPPING = { - UVMapping: UVMapping, - CubeReflectionMapping: CubeReflectionMapping, - CubeRefractionMapping: CubeRefractionMapping, - EquirectangularReflectionMapping: EquirectangularReflectionMapping, - EquirectangularRefractionMapping: EquirectangularRefractionMapping, - CubeUVReflectionMapping: CubeUVReflectionMapping - }; - const TEXTURE_WRAPPING = { - RepeatWrapping: RepeatWrapping, - ClampToEdgeWrapping: ClampToEdgeWrapping, - MirroredRepeatWrapping: MirroredRepeatWrapping - }; - const TEXTURE_FILTER = { - NearestFilter: NearestFilter, - NearestMipmapNearestFilter: NearestMipmapNearestFilter, - NearestMipmapLinearFilter: NearestMipmapLinearFilter, - LinearFilter: LinearFilter, - LinearMipmapNearestFilter: LinearMipmapNearestFilter, - LinearMipmapLinearFilter: LinearMipmapLinearFilter - }; + class GLBufferAttribute { - class ImageBitmapLoader extends Loader { - constructor(manager) { - super(manager); - this.isImageBitmapLoader = true; + constructor( buffer, type, itemSize, elementSize, count ) { - if (typeof createImageBitmap === 'undefined') { - console.warn('THREE.ImageBitmapLoader: createImageBitmap() not supported.'); - } + this.isGLBufferAttribute = true; - if (typeof fetch === 'undefined') { - console.warn('THREE.ImageBitmapLoader: fetch() not supported.'); - } + this.name = ''; - this.options = { - premultiplyAlpha: 'none' - }; - } + this.buffer = buffer; + this.type = type; + this.itemSize = itemSize; + this.elementSize = elementSize; + this.count = count; + + this.version = 0; - 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 () { - if (onLoad) onLoad(cached); - scope.manager.itemEnd(url); - }, 0); - return cached; - } + set needsUpdate( value ) { + + if ( value === true ) this.version ++; - const fetchOptions = {}; - fetchOptions.credentials = this.crossOrigin === 'anonymous' ? 'same-origin' : 'include'; - fetchOptions.headers = this.requestHeader; - fetch(url, fetchOptions).then(function (res) { - return res.blob(); - }).then(function (blob) { - return createImageBitmap(blob, Object.assign(scope.options, { - colorSpaceConversion: 'none' - })); - }).then(function (imageBitmap) { - Cache.add(url, imageBitmap); - if (onLoad) onLoad(imageBitmap); - scope.manager.itemEnd(url); - }).catch(function (e) { - if (onError) onError(e); - scope.manager.itemError(url); - scope.manager.itemEnd(url); - }); - scope.manager.itemStart(url); } - } + setBuffer( buffer ) { - let _context; + this.buffer = buffer; - const AudioContext = { - getContext: function () { - if (_context === undefined) { - _context = new (window.AudioContext || window.webkitAudioContext)(); - } + return this; - return _context; - }, - setContext: function (value) { - _context = value; } - }; - class AudioLoader extends Loader { - constructor(manager) { - super(manager); - } + setType( type, elementSize ) { - load(url, onLoad, onProgress, onError) { - const scope = this; - const loader = new FileLoader(this.manager); - loader.setResponseType('arraybuffer'); - loader.setPath(this.path); - loader.setRequestHeader(this.requestHeader); - loader.setWithCredentials(this.withCredentials); - loader.load(url, function (buffer) { - try { - // Create a copy of the buffer. The `decodeAudioData` method - // detaches the buffer when complete, preventing reuse. - const bufferCopy = buffer.slice(0); - const context = AudioContext.getContext(); - context.decodeAudioData(bufferCopy, function (audioBuffer) { - onLoad(audioBuffer); - }); - } catch (e) { - if (onError) { - onError(e); - } else { - console.error(e); - } + this.type = type; + this.elementSize = elementSize; + + return this; - scope.manager.itemError(url); - } - }, onProgress, onError); } - } + setItemSize( itemSize ) { - class HemisphereLightProbe extends LightProbe { - constructor(skyColor, groundColor, intensity = 1) { - super(undefined, intensity); - this.isHemisphereLightProbe = true; - 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 ); + this.itemSize = itemSize; + + return this; - 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); } - } + setCount( count ) { - 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 ); + this.count = count; + + return this; - this.sh.coefficients[0].set(color1.r, color1.g, color1.b).multiplyScalar(2 * Math.sqrt(Math.PI)); } } - const _eyeRight = /*@__PURE__*/new Matrix4(); + class Raycaster { - const _eyeLeft = /*@__PURE__*/new Matrix4(); + constructor( origin, direction, near = 0, far = Infinity ) { - const _projectionMatrix = /*@__PURE__*/new Matrix4(); + this.ray = new Ray( origin, direction ); + // direction is assumed to be normalized (for accurate distance calculations) - class StereoCamera { - constructor() { - this.type = 'StereoCamera'; - this.aspect = 1; - this.eyeSep = 0.064; - this.cameraL = new PerspectiveCamera(); - this.cameraL.layers.enable(1); - this.cameraL.matrixAutoUpdate = false; - this.cameraR = new PerspectiveCamera(); - this.cameraR.layers.enable(2); - this.cameraR.matrixAutoUpdate = false; - this._cache = { - focus: null, - fov: null, - aspect: null, - near: null, - far: null, - zoom: null, - eyeSep: null + this.near = near; + this.far = far; + this.camera = null; + this.layers = new Layers(); + + this.params = { + Mesh: {}, + Line: { threshold: 1 }, + LOD: {}, + Points: { threshold: 1 }, + Sprite: {} }; + } - 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; + set( origin, direction ) { - if (needsUpdate) { - cache.focus = camera.focus; - cache.fov = camera.fov; - cache.aspect = camera.aspect * this.aspect; - cache.near = camera.near; - cache.far = camera.far; - cache.zoom = camera.zoom; - cache.eyeSep = this.eyeSep; // Off-axis stereoscopic effect based on - // http://paulbourke.net/stereographics/stereorender/ + // direction is assumed to be normalized (for accurate distance calculations) - _projectionMatrix.copy(camera.projectionMatrix); + this.ray.set( origin, direction ); - 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 + } - _eyeLeft.elements[12] = -eyeSepHalf; - _eyeRight.elements[12] = eyeSepHalf; // for left eye + setFromCamera( coords, camera ) { - 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 + if ( camera.isPerspectiveCamera ) { + + this.ray.origin.setFromMatrixPosition( camera.matrixWorld ); + this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize(); + this.camera = camera; + + } else if ( camera.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 ); - xmin = -ymax * cache.aspect - eyeSepOnProjection; - xmax = ymax * cache.aspect - eyeSepOnProjection; - _projectionMatrix.elements[0] = 2 * cache.near / (xmax - xmin); - _projectionMatrix.elements[8] = (xmax + xmin) / (xmax - xmin); - this.cameraR.projectionMatrix.copy(_projectionMatrix); } - this.cameraL.matrixWorld.copy(camera.matrixWorld).multiply(_eyeLeft); - this.cameraR.matrixWorld.copy(camera.matrixWorld).multiply(_eyeRight); } - } + intersectObject( object, recursive = true, intersects = [] ) { - class Clock { - constructor(autoStart = true) { - this.autoStart = autoStart; - this.startTime = 0; - this.oldTime = 0; - this.elapsedTime = 0; - this.running = false; - } + intersectObject( object, this, intersects, recursive ); - start() { - this.startTime = now(); - this.oldTime = this.startTime; - this.elapsedTime = 0; - this.running = true; - } + intersects.sort( ascSort ); - stop() { - this.getElapsedTime(); - this.running = false; - this.autoStart = false; - } + return intersects; - getElapsedTime() { - this.getDelta(); - return this.elapsedTime; } - getDelta() { - let diff = 0; + intersectObjects( objects, recursive = true, intersects = [] ) { - if (this.autoStart && !this.running) { - this.start(); - return 0; - } + for ( let i = 0, l = objects.length; i < l; i ++ ) { + + intersectObject( objects[ i ], this, intersects, recursive ); - if (this.running) { - const newTime = now(); - diff = (newTime - this.oldTime) / 1000; - this.oldTime = newTime; - this.elapsedTime += diff; } - return diff; + intersects.sort( ascSort ); + + return intersects; + } } - function now() { - return (typeof performance === 'undefined' ? Date : performance).now(); // see #10732 + function ascSort( a, b ) { + + return a.distance - b.distance; + } - const _position$1 = /*@__PURE__*/new Vector3(); + function intersectObject( object, raycaster, intersects, recursive ) { - const _quaternion$1 = /*@__PURE__*/new Quaternion(); + if ( object.layers.test( raycaster.layers ) ) { - const _scale$1 = /*@__PURE__*/new Vector3(); + object.raycast( raycaster, intersects ); - const _orientation$1 = /*@__PURE__*/new Vector3(); + } - class AudioListener extends Object3D { - constructor() { - super(); - this.type = 'AudioListener'; - this.context = AudioContext.getContext(); - this.gain = this.context.createGain(); - this.gain.connect(this.context.destination); - this.filter = null; - this.timeDelta = 0; // private + if ( recursive === true ) { + + const children = object.children; + + for ( let i = 0, l = children.length; i < l; i ++ ) { + + intersectObject( children[ i ], raycaster, intersects, true ); + + } + + } + + } + + /** + * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system + * + * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up. + * The azimuthal angle (theta) is measured from the positive z-axis. + */ + + class Spherical { + + constructor( radius = 1, phi = 0, theta = 0 ) { + + this.radius = radius; + this.phi = phi; // polar angle + this.theta = theta; // azimuthal angle - this._clock = new Clock(); - } + return this; - getInput() { - return this.gain; } - removeFilter() { - if (this.filter !== null) { - this.gain.disconnect(this.filter); - this.filter.disconnect(this.context.destination); - this.gain.connect(this.context.destination); - this.filter = null; - } + set( radius, phi, theta ) { + + this.radius = radius; + this.phi = phi; + this.theta = theta; return this; - } - getFilter() { - return this.filter; } - setFilter(value) { - if (this.filter !== null) { - this.gain.disconnect(this.filter); - this.filter.disconnect(this.context.destination); - } else { - this.gain.disconnect(this.context.destination); - } + copy( other ) { + + this.radius = other.radius; + this.phi = other.phi; + this.theta = other.theta; - 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); + // 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; + } - 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); + setFromVector3( v ) { - _orientation$1.set(0, 0, -1).applyQuaternion(_quaternion$1); + return this.setFromCartesianCoords( v.x, v.y, v.z ); - 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); - listener.positionZ.linearRampToValueAtTime(_position$1.z, endTime); - listener.forwardX.linearRampToValueAtTime(_orientation$1.x, endTime); - listener.forwardY.linearRampToValueAtTime(_orientation$1.y, endTime); - listener.forwardZ.linearRampToValueAtTime(_orientation$1.z, endTime); - listener.upX.linearRampToValueAtTime(up.x, endTime); - listener.upY.linearRampToValueAtTime(up.y, endTime); - listener.upZ.linearRampToValueAtTime(up.z, endTime); - } else { - listener.setPosition(_position$1.x, _position$1.y, _position$1.z); - listener.setOrientation(_orientation$1.x, _orientation$1.y, _orientation$1.z, up.x, up.y, up.z); - } } - } + setFromCartesianCoords( x, y, z ) { - class Audio extends Object3D { - constructor(listener) { - super(); - this.type = 'Audio'; - this.listener = listener; - this.context = listener.context; - this.gain = this.context.createGain(); - this.gain.connect(listener.getInput()); - this.autoplay = false; - this.buffer = null; - this.detune = 0; - this.loop = false; - this.loopStart = 0; - this.loopEnd = 0; - this.offset = 0; - this.duration = undefined; - this.playbackRate = 1; - this.isPlaying = false; - this.hasPlaybackControl = true; - this.source = null; - this.sourceType = 'empty'; - this._startedAt = 0; - this._progress = 0; - this._connected = false; - this.filters = []; - } + this.radius = Math.sqrt( x * x + y * y + z * z ); - getOutput() { - return this.gain; - } + if ( this.radius === 0 ) { - setNodeSource(audioNode) { - this.hasPlaybackControl = false; - this.sourceType = 'audioNode'; - this.source = audioNode; - this.connect(); - return this; - } + this.theta = 0; + this.phi = 0; - setMediaElementSource(mediaElement) { - this.hasPlaybackControl = false; - this.sourceType = 'mediaNode'; - this.source = this.context.createMediaElementSource(mediaElement); - this.connect(); - return this; - } + } else { - setMediaStreamSource(mediaStream) { - this.hasPlaybackControl = false; - this.sourceType = 'mediaStreamNode'; - this.source = this.context.createMediaStreamSource(mediaStream); - this.connect(); - return this; - } + this.theta = Math.atan2( x, z ); + this.phi = Math.acos( clamp( y / this.radius, - 1, 1 ) ); + + } - 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; - } + clone() { - if (this.hasPlaybackControl === false) { - console.warn('THREE.Audio: this Audio has no playback control.'); - return; - } + return new this.constructor().copy( this ); - this._startedAt = this.context.currentTime + delay; - const source = this.context.createBufferSource(); - source.buffer = this.buffer; - source.loop = this.loop; - source.loopStart = this.loopStart; - source.loopEnd = this.loopEnd; - source.onended = this.onEnded.bind(this); - source.start(this._startedAt, this._progress + this.offset, this.duration); - this.isPlaying = true; - this.source = source; - this.setDetune(this.detune); - this.setPlaybackRate(this.playbackRate); - return this.connect(); } - 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; + } - if (this.loop === true) { - // ensure _progress does not exceed duration with looped audios - this._progress = this._progress % (this.duration || this.buffer.duration); - } + /** + * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system + */ - this.source.stop(); - this.source.onended = null; - this.isPlaying = false; - } + class Cylindrical { - return this; - } + constructor( radius = 1, theta = 0, y = 0 ) { - stop() { - if (this.hasPlaybackControl === false) { - console.warn('THREE.Audio: this Audio has no playback control.'); - return; - } + 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 - 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]); - } + set( radius, theta, y ) { - this.filters[this.filters.length - 1].connect(this.getOutput()); - } else { - this.source.connect(this.getOutput()); - } + this.radius = radius; + this.theta = theta; + this.y = y; - 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]); - } + copy( other ) { - this.filters[this.filters.length - 1].disconnect(this.getOutput()); - } else { - this.source.disconnect(this.getOutput()); - } + this.radius = other.radius; + this.theta = other.theta; + this.y = other.y; - this._connected = false; return this; - } - getFilters() { - return this.filters; } - setFilters(value) { - if (!value) value = []; + setFromVector3( v ) { - if (this._connected === true) { - this.disconnect(); - this.filters = value.slice(); - this.connect(); - } else { - this.filters = value.slice(); - } + return this.setFromCartesianCoords( v.x, v.y, v.z ); - return this; } - setDetune(value) { - this.detune = value; - if (this.source.detune === undefined) return; // only set detune when available + setFromCartesianCoords( x, y, z ) { - if (this.isPlaying === true) { - this.source.detune.setTargetAtTime(this.detune, this.context.currentTime, 0.01); - } + this.radius = Math.sqrt( x * x + z * z ); + this.theta = Math.atan2( x, z ); + this.y = y; return this; - } - getDetune() { - return this.detune; } - getFilter() { - return this.getFilters()[0]; - } + clone() { + + return new this.constructor().copy( this ); - 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; + const _vector$4 = /*@__PURE__*/ new Vector2(); - if (this.isPlaying === true) { - this.source.playbackRate.setTargetAtTime(this.playbackRate, this.context.currentTime, 0.01); - } + class Box2 { - return this; - } + constructor( min = new Vector2( + Infinity, + Infinity ), max = new Vector2( - Infinity, - Infinity ) ) { - getPlaybackRate() { - return this.playbackRate; - } + this.isBox2 = true; + + this.min = min; + this.max = max; - onEnded() { - this.isPlaying = false; } - getLoop() { - if (this.hasPlaybackControl === false) { - console.warn('THREE.Audio: this Audio has no playback control.'); - return false; - } + set( min, max ) { + + this.min.copy( min ); + this.max.copy( max ); + + return this; - return this.loop; } - setLoop(value) { - if (this.hasPlaybackControl === false) { - console.warn('THREE.Audio: this Audio has no playback control.'); - return; - } + setFromPoints( points ) { - this.loop = value; + this.makeEmpty(); + + for ( let i = 0, il = points.length; i < il; i ++ ) { + + this.expandByPoint( points[ i ] ); - 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; - } + setFromCenterAndSize( center, size ) { - getVolume() { - return this.gain.gain.value; - } + const halfSize = _vector$4.copy( size ).multiplyScalar( 0.5 ); + this.min.copy( center ).sub( halfSize ); + this.max.copy( center ).add( halfSize ); - setVolume(value) { - this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01); return this; + } - } + clone() { - const _position = /*@__PURE__*/new Vector3(); + return new this.constructor().copy( this ); - const _quaternion = /*@__PURE__*/new Quaternion(); + } - const _scale = /*@__PURE__*/new Vector3(); + copy( box ) { - const _orientation = /*@__PURE__*/new Vector3(); + this.min.copy( box.min ); + this.max.copy( box.max ); - class PositionalAudio extends Audio { - constructor(listener) { - super(listener); - this.panner = this.context.createPanner(); - this.panner.panningModel = 'HRTF'; - this.panner.connect(this.gain); - } + return this; - disconnect() { - super.disconnect(); - this.panner.disconnect(this.gain); } - getOutput() { - return this.panner; - } + makeEmpty() { - getRefDistance() { - return this.panner.refDistance; - } + this.min.x = this.min.y = + Infinity; + this.max.x = this.max.y = - Infinity; - setRefDistance(value) { - this.panner.refDistance = value; return this; - } - getRolloffFactor() { - return this.panner.rolloffFactor; } - setRolloffFactor(value) { - this.panner.rolloffFactor = value; - 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 ); - getDistanceModel() { - return this.panner.distanceModel; } - setDistanceModel(value) { - this.panner.distanceModel = value; - return this; + getCenter( target ) { + + return this.isEmpty() ? target.set( 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); + } - getMaxDistance() { - return this.panner.maxDistance; + getSize( target ) { + + return this.isEmpty() ? target.set( 0, 0 ) : target.subVectors( this.max, this.min ); + } - setMaxDistance(value) { - this.panner.maxDistance = value; + expandByPoint( point ) { + + this.min.min( point ); + this.max.max( point ); + return this; + } - setDirectionalCone(coneInnerAngle, coneOuterAngle, coneOuterGain) { - this.panner.coneInnerAngle = coneInnerAngle; - this.panner.coneOuterAngle = coneOuterAngle; - this.panner.coneOuterGain = coneOuterGain; + expandByVector( vector ) { + + this.min.sub( vector ); + this.max.add( vector ); + return this; + } - updateMatrixWorld(force) { - super.updateMatrixWorld(force); - if (this.hasPlaybackControl === true && this.isPlaying === false) return; - this.matrixWorld.decompose(_position, _quaternion, _scale); + expandByScalar( scalar ) { - _orientation.set(0, 0, 1).applyQuaternion(_quaternion); + this.min.addScalar( - scalar ); + this.max.addScalar( scalar ); - const panner = this.panner; + return this; - 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); - panner.positionZ.linearRampToValueAtTime(_position.z, endTime); - panner.orientationX.linearRampToValueAtTime(_orientation.x, endTime); - panner.orientationY.linearRampToValueAtTime(_orientation.y, endTime); - panner.orientationZ.linearRampToValueAtTime(_orientation.z, endTime); - } else { - panner.setPosition(_position.x, _position.y, _position.z); - panner.setOrientation(_orientation.x, _orientation.y, _orientation.z); - } } - } + containsPoint( point ) { - class AudioAnalyser { - constructor(audio, fftSize = 2048) { - this.analyser = audio.context.createAnalyser(); - this.analyser.fftSize = fftSize; - this.data = new Uint8Array(this.analyser.frequencyBinCount); - audio.getOutput().connect(this.analyser); - } + return point.x < this.min.x || point.x > this.max.x || + point.y < this.min.y || point.y > this.max.y ? false : true; - getFrequencyData() { - this.analyser.getByteFrequencyData(this.data); - return this.data; } - getAverageFrequency() { - let value = 0; - const data = this.getFrequencyData(); + containsBox( box ) { - for (let i = 0; i < data.length; i++) { - value += data[i]; - } + 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; - return value / data.length; } - } + getParameter( point, target ) { - 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) ] - // - // interpolators can use .buffer as their .result - // the data then goes to 'incoming' - // - // 'accu0' and 'accu1' are used frame-interleaved for - // the cumulative result and are compared to detect - // changes - // - // 'orig' stores the original state of the property - // - // 'add' is used for additive cumulative results - // - // 'work' is optional and is only present for quaternion types. It is used - // to store intermediate quaternion multiplication results + // This can potentially have a divide by zero if the box + // has a size dimension of 0. - switch (typeName) { - case 'quaternion': - mixFunction = this._slerp; - mixFunctionAdditive = this._slerpAdditive; - setIdentity = this._setAdditiveIdentityQuaternion; - this.buffer = new Float64Array(valueSize * 6); - this._workIndex = 5; - break; + 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 ) + ); - 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 + } - mixFunctionAdditive = this._select; - setIdentity = this._setAdditiveIdentityOther; - this.buffer = new Array(valueSize * 5); - break; + intersectsBox( box ) { - default: - mixFunction = this._lerp; - mixFunctionAdditive = this._lerpAdditive; - setIdentity = this._setAdditiveIdentityNumeric; - this.buffer = new Float64Array(valueSize * 5); - } + // using 4 splitting planes to rule out intersections - this._mixBufferRegion = mixFunction; - this._mixBufferRegionAdditive = mixFunctionAdditive; - this._setIdentity = setIdentity; - this._origIndex = 3; - this._addIndex = 4; - this.cumulativeWeight = 0; - this.cumulativeWeightAdditive = 0; - this.useCount = 0; - this.referenceCount = 0; - } // accumulate data in the 'incoming' region into 'accu' + 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; + } - 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; - let currentWeight = this.cumulativeWeight; + clampPoint( point, target ) { - if (currentWeight === 0) { - // accuN := incoming * weight - for (let i = 0; i !== stride; ++i) { - buffer[offset + i] = buffer[i]; - } + return target.copy( point ).clamp( this.min, this.max ); - currentWeight = weight; - } else { - // accuN := accuN + incoming * weight - currentWeight += weight; - const mix = weight / currentWeight; + } - this._mixBufferRegion(buffer, offset, 0, mix, stride); - } + distanceToPoint( point ) { - this.cumulativeWeight = currentWeight; - } // accumulate data in the 'incoming' region into 'add' + const clampedPoint = _vector$4.copy( point ).clamp( this.min, this.max ); + return clampedPoint.sub( point ).length(); + } - accumulateAdditive(weight) { - const buffer = this.buffer, - stride = this.valueSize, - offset = stride * this._addIndex; + intersect( box ) { - if (this.cumulativeWeightAdditive === 0) { - // add = identity - this._setIdentity(); - } // add := add + incoming * weight + this.min.max( box.min ); + this.max.min( box.max ); + return this; - this._mixBufferRegionAdditive(buffer, offset, 0, weight, stride); + } - this.cumulativeWeightAdditive += weight; - } // apply the state of 'accu' to the binding when accus differ + union( box ) { + this.min.min( box.min ); + this.max.max( box.max ); - apply(accuIndex) { - const stride = this.valueSize, - buffer = this.buffer, - offset = accuIndex * stride + stride, - weight = this.cumulativeWeight, - weightAdditive = this.cumulativeWeightAdditive, - binding = this.binding; - this.cumulativeWeight = 0; - this.cumulativeWeightAdditive = 0; + return this; - if (weight < 1) { - // accuN := accuN + original * ( 1 - cumulativeWeight ) - const originalValueOffset = stride * this._origIndex; + } - this._mixBufferRegion(buffer, offset, originalValueOffset, 1 - weight, stride); - } + translate( offset ) { - if (weightAdditive > 0) { - // accuN := accuN + additive accuN - this._mixBufferRegionAdditive(buffer, offset, this._addIndex * stride, 1, stride); - } + this.min.add( offset ); + this.max.add( offset ); - 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 + return this; + } - 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 + equals( box ) { - for (let i = stride, e = originalValueOffset; i !== e; ++i) { - buffer[i] = buffer[originalValueOffset + i % stride]; - } // Add to identity for additive + return box.min.equals( this.min ) && box.max.equals( this.max ); + } - this._setIdentity(); + } - this.cumulativeWeight = 0; - this.cumulativeWeightAdditive = 0; - } // apply the state previously taken via 'saveOriginalState' to the binding + const _startP = /*@__PURE__*/ new Vector3(); + const _startEnd = /*@__PURE__*/ new Vector3(); + class Line3 { - restoreOriginalState() { - const originalValueOffset = this.valueSize * 3; - this.binding.setValue(this.buffer, originalValueOffset); - } + constructor( start = new Vector3(), end = new Vector3() ) { - _setAdditiveIdentityNumeric() { - const startIndex = this._addIndex * this.valueSize; - const endIndex = startIndex + this.valueSize; + this.start = start; + this.end = end; - for (let i = startIndex; i < endIndex; i++) { - this.buffer[i] = 0; - } } - _setAdditiveIdentityQuaternion() { - this._setAdditiveIdentityNumeric(); + set( start, end ) { + + this.start.copy( start ); + this.end.copy( end ); + + return this; - this.buffer[this._addIndex * this.valueSize + 3] = 1; } - _setAdditiveIdentityOther() { - const startIndex = this._origIndex * this.valueSize; - const targetIndex = this._addIndex * this.valueSize; + copy( line ) { - for (let i = 0; i < this.valueSize; i++) { - this.buffer[targetIndex + i] = this.buffer[startIndex + i]; - } - } // mix functions + this.start.copy( line.start ); + this.end.copy( line.end ); + return this; - _select(buffer, dstOffset, srcOffset, t, stride) { - if (t >= 0.5) { - for (let i = 0; i !== stride; ++i) { - buffer[dstOffset + i] = buffer[srcOffset + i]; - } - } } - _slerp(buffer, dstOffset, srcOffset, t) { - Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t); + getCenter( target ) { + + return target.addVectors( this.start, this.end ).multiplyScalar( 0.5 ); + } - _slerpAdditive(buffer, dstOffset, srcOffset, t, stride) { - const workOffset = this._workIndex * stride; // Store result in intermediate buffer offset + delta( target ) { - Quaternion.multiplyQuaternionsFlat(buffer, workOffset, buffer, dstOffset, buffer, srcOffset); // Slerp to the intermediate result + return target.subVectors( this.end, this.start ); - Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t); } - _lerp(buffer, dstOffset, srcOffset, t, stride) { - const s = 1 - t; + distanceSq() { - for (let i = 0; i !== stride; ++i) { - const j = dstOffset + i; - buffer[j] = buffer[j] * s + buffer[srcOffset + i] * t; - } - } + return this.start.distanceToSquared( this.end ); - _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; - } } - } + distance() { - // Characters [].:/ are reserved for track binding syntax. - const _RESERVED_CHARS_RE = '\\[\\]\\.:\\/'; + return this.start.distanceTo( this.end ); - const _reservedRe = new RegExp('[' + _RESERVED_CHARS_RE + ']', 'g'); // Attempts to allow node names from any language. ES5's `\w` regexp matches - // only latin characters, and the unicode \p{L} is not yet supported. So - // instead, we exclude reserved characters and match everything else. + } + at( t, target ) { - const _wordChar = '[^' + _RESERVED_CHARS_RE + ']'; + return this.delta( target ).multiplyScalar( t ).add( this.start ); - const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace('\\.', '') + ']'; // Parent directories, delimited by '/' or ':'. Currently unused, but must - // be matched to parse the rest of the track name. + } + closestPointToPointParameter( point, clampToLine ) { - const _directoryRe = /((?:WC+[\/:])*)/.source.replace('WC', _wordChar); // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. + _startP.subVectors( point, this.start ); + _startEnd.subVectors( this.end, this.start ); + const startEnd2 = _startEnd.dot( _startEnd ); + const startEnd_startP = _startEnd.dot( _startP ); - const _nodeRe = /(WCOD+)?/.source.replace('WCOD', _wordCharOrDot); // Object on target node, and accessor. May not contain reserved - // characters. Accessor may contain any character except closing bracket. + let t = startEnd_startP / startEnd2; + if ( clampToLine ) { - const _objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace('WC', _wordChar); // Property and accessor. May not contain reserved characters. Accessor may - // contain any non-bracket characters. + t = clamp( t, 0, 1 ); + + } + return t; - const _propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace('WC', _wordChar); + } - const _trackRe = new RegExp('' + '^' + _directoryRe + _nodeRe + _objectRe + _propertyRe + '$'); + closestPointToPoint( point, clampToLine, target ) { - const _supportedObjectNames = ['material', 'materials', 'bones']; + const t = this.closestPointToPointParameter( point, clampToLine ); + + return this.delta( target ).multiplyScalar( t ).add( this.start ); - 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 + applyMatrix4( matrix ) { - const firstValidIndex = this._targetGroup.nCachedObjects_, - binding = this._bindings[firstValidIndex]; // and only call .getValue on the first + this.start.applyMatrix4( matrix ); + this.end.applyMatrix4( matrix ); + + return this; - if (binding !== undefined) binding.getValue(array, offset); } - setValue(array, offset) { - const bindings = this._bindings; + equals( line ) { + + return line.start.equals( this.start ) && line.end.equals( this.end ); - for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { - bindings[i].setValue(array, offset); - } } - bind() { - const bindings = this._bindings; + clone() { + + return new this.constructor().copy( this ); - 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(); - } - } + const _vector$3 = /*@__PURE__*/ new Vector3(); - } // 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 SpotLightHelper extends Object3D { + constructor( light, color ) { - 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' + super(); - this.getValue = this._getValue_unbound; - this.setValue = this._setValue_unbound; - } + this.light = light; - static create(root, path, parsedPath) { - if (!(root && root.isAnimationObjectGroup)) { - return new PropertyBinding(root, path, parsedPath); - } else { - return new PropertyBinding.Composite(root, path, parsedPath); - } - } - /** - * Replaces spaces with underscores and removes unsupported characters from - * node names, to ensure compatibility with parseTrackName(). - * - * @param {string} name Node name to be sanitized. - * @return {string} - */ + this.matrix = light.matrixWorld; + this.matrixAutoUpdate = false; + this.color = color; - static sanitizeNodeName(name) { - return name.replace(/\s/g, '_').replace(_reservedRe, ''); - } + this.type = 'SpotLightHelper'; - static parseTrackName(trackName) { - const matches = _trackRe.exec(trackName); + const geometry = new BufferGeometry(); - if (matches === null) { - throw new Error('PropertyBinding: Cannot parse trackName: ' + trackName); - } + 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 + ]; - const results = { - // directoryName: matches[ 1 ], // (tschw) currently unused - nodeName: matches[2], - objectName: matches[3], - objectIndex: matches[4], - propertyName: matches[5], - // required - propertyIndex: matches[6] - }; - const lastDot = results.nodeName && results.nodeName.lastIndexOf('.'); + for ( let i = 0, j = 1, l = 32; i < l; i ++, j ++ ) { - if (lastDot !== undefined && lastDot !== -1) { - 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). + const p1 = ( i / l ) * Math.PI * 2; + const p2 = ( j / l ) * Math.PI * 2; - if (_supportedObjectNames.indexOf(objectName) !== -1) { - results.nodeName = results.nodeName.substring(0, lastDot); - results.objectName = objectName; - } - } + positions.push( + Math.cos( p1 ), Math.sin( p1 ), 1, + Math.cos( p2 ), Math.sin( p2 ), 1 + ); - if (results.propertyName === null || results.propertyName.length === 0) { - throw new Error('PropertyBinding: can not parse propertyName from trackName: ' + trackName); } - return results; + geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + + const material = new LineBasicMaterial( { fog: false, toneMapped: false } ); + + this.cone = new LineSegments( geometry, material ); + this.add( this.cone ); + + this.update(); + } - static findNode(root, nodeName) { - if (nodeName === undefined || nodeName === '' || nodeName === '.' || nodeName === -1 || nodeName === root.name || nodeName === root.uuid) { - return root; - } // search into skeleton bones. + dispose() { + this.cone.geometry.dispose(); + this.cone.material.dispose(); - if (root.skeleton) { - const bone = root.skeleton.getBoneByName(nodeName); + } - if (bone !== undefined) { - return bone; - } - } // search into node subtree. + update() { + this.light.updateWorldMatrix( true, false ); + this.light.target.updateWorldMatrix( true, false ); - if (root.children) { - const searchNodeSubtree = function (children) { - for (let i = 0; i < children.length; i++) { - const childNode = children[i]; + const coneLength = this.light.distance ? this.light.distance : 1000; + const coneWidth = coneLength * Math.tan( this.light.angle ); - if (childNode.name === nodeName || childNode.uuid === nodeName) { - return childNode; - } + this.cone.scale.set( coneWidth, coneWidth, coneLength ); - const result = searchNodeSubtree(childNode.children); - if (result) return result; - } + _vector$3.setFromMatrixPosition( this.light.target.matrixWorld ); - return null; - }; + this.cone.lookAt( _vector$3 ); - const subTreeNode = searchNodeSubtree(root.children); + if ( this.color !== undefined ) { + + this.cone.material.color.set( this.color ); + + } else { + + this.cone.material.color.copy( this.light.color ); - if (subTreeNode) { - return subTreeNode; - } } - return null; - } // these are used to "bind" a nonexistent property + } + + } + + 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 ); + + const geometry = new BufferGeometry(); + + const vertices = []; + const colors = []; + const color1 = new Color( 0, 0, 1 ); + const color2 = new Color( 0, 1, 0 ); - _getValue_unavailable() {} + for ( let i = 0; i < bones.length; i ++ ) { - _setValue_unavailable() {} // Getters + const bone = bones[ i ]; + if ( bone.parent && bone.parent.isBone ) { - _getValue_direct(buffer, offset) { - buffer[offset] = this.targetObject[this.propertyName]; - } + vertices.push( 0, 0, 0 ); + vertices.push( 0, 0, 0 ); + colors.push( color1.r, color1.g, color1.b ); + colors.push( color2.r, color2.g, color2.b ); - _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 + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + const material = new LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, toneMapped: false, transparent: true } ); - _setValue_direct(buffer, offset) { - this.targetObject[this.propertyName] = buffer[offset]; - } + super( geometry, material ); - _setValue_direct_setNeedsUpdate(buffer, offset) { - this.targetObject[this.propertyName] = buffer[offset]; - this.targetObject.needsUpdate = true; - } + this.isSkeletonHelper = true; - _setValue_direct_setMatrixWorldNeedsUpdate(buffer, offset) { - this.targetObject[this.propertyName] = buffer[offset]; - this.targetObject.matrixWorldNeedsUpdate = true; - } // EntireArray + this.type = 'SkeletonHelper'; + this.root = object; + this.bones = bones; - _setValue_array(buffer, offset) { - const dest = this.resolvedProperty; + this.matrix = object.matrixWorld; + this.matrixAutoUpdate = false; - for (let i = 0, n = dest.length; i !== n; ++i) { - dest[i] = buffer[offset++]; - } } - _setValue_array_setNeedsUpdate(buffer, offset) { - const dest = this.resolvedProperty; + updateMatrixWorld( force ) { - for (let i = 0, n = dest.length; i !== n; ++i) { - dest[i] = buffer[offset++]; - } + const bones = this.bones; - this.targetObject.needsUpdate = true; - } + const geometry = this.geometry; + const position = geometry.getAttribute( 'position' ); - _setValue_array_setMatrixWorldNeedsUpdate(buffer, offset) { - const dest = this.resolvedProperty; + _matrixWorldInv.copy( this.root.matrixWorld ).invert(); - for (let i = 0, n = dest.length; i !== n; ++i) { - dest[i] = buffer[offset++]; - } + for ( let i = 0, j = 0; i < bones.length; i ++ ) { - this.targetObject.matrixWorldNeedsUpdate = true; - } // ArrayElement + const bone = bones[ i ]; + if ( bone.parent && bone.parent.isBone ) { - _setValue_arrayElement(buffer, offset) { - this.resolvedProperty[this.propertyIndex] = buffer[offset]; - } + _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld ); + _vector$2.setFromMatrixPosition( _boneMatrix ); + position.setXYZ( j, _vector$2.x, _vector$2.y, _vector$2.z ); - _setValue_arrayElement_setNeedsUpdate(buffer, offset) { - this.resolvedProperty[this.propertyIndex] = buffer[offset]; - this.targetObject.needsUpdate = true; - } + _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld ); + _vector$2.setFromMatrixPosition( _boneMatrix ); + position.setXYZ( j + 1, _vector$2.x, _vector$2.y, _vector$2.z ); - _setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer, offset) { - this.resolvedProperty[this.propertyIndex] = buffer[offset]; - this.targetObject.matrixWorldNeedsUpdate = true; - } // HasToFromArray + j += 2; + } - _setValue_fromArray(buffer, offset) { - this.resolvedProperty.fromArray(buffer, offset); - } + } - _setValue_fromArray_setNeedsUpdate(buffer, offset) { - this.resolvedProperty.fromArray(buffer, offset); - this.targetObject.needsUpdate = true; - } + geometry.getAttribute( 'position' ).needsUpdate = true; - _setValue_fromArray_setMatrixWorldNeedsUpdate(buffer, offset) { - this.resolvedProperty.fromArray(buffer, offset); - this.targetObject.matrixWorldNeedsUpdate = true; - } + super.updateMatrixWorld( force ); - _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 - + dispose() { - bind() { - let targetObject = this.node; - const parsedPath = this.parsedPath; - const objectName = parsedPath.objectName; - const propertyName = parsedPath.propertyName; - let propertyIndex = parsedPath.propertyIndex; + this.geometry.dispose(); + this.material.dispose(); - if (!targetObject) { - targetObject = PropertyBinding.findNode(this.rootNode, parsedPath.nodeName) || this.rootNode; - this.node = targetObject; - } // 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 - if (!targetObject) { - console.error('THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.'); - return; - } + function getBoneList( object ) { - if (objectName) { - let objectIndex = parsedPath.objectIndex; // special cases were we need to reach deeper into the hierarchy to get the face materials.... + const boneList = []; - 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 ( object.isBone === true ) { - 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; - } + boneList.push( object ); - 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. + for ( let i = 0; i < object.children.length; i ++ ) { + boneList.push.apply( boneList, getBoneList( object.children[ i ] ) ); - 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; - } - } + return boneList; - break; + } - default: - if (targetObject[objectName] === undefined) { - console.error('THREE.PropertyBinding: Can not bind to objectName of node undefined.', this); - return; - } + class PointLightHelper extends Mesh { - targetObject = targetObject[objectName]; - } + constructor( light, sphereSize, color ) { - if (objectIndex !== undefined) { - if (targetObject[objectIndex] === undefined) { - console.error('THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject); - return; - } + const geometry = new SphereGeometry( sphereSize, 4, 2 ); + const material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } ); - targetObject = targetObject[objectIndex]; - } - } // resolve property + super( geometry, material ); + this.light = light; - const nodeProperty = targetObject[propertyName]; + this.color = color; - 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 + this.type = 'PointLightHelper'; + this.matrix = this.light.matrixWorld; + this.matrixAutoUpdate = false; - let versioning = this.Versioning.None; - this.targetObject = targetObject; + this.update(); - 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 + /* + // TODO: delete this comment? + const distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 ); + const distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } ); - let bindingType = this.BindingType.Direct; + this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial ); + this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial ); - 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; - } + const d = light.distance; - if (!targetObject.geometry.morphAttributes) { - console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this); - return; - } + if ( d === 0.0 ) { - if (targetObject.morphTargetDictionary[propertyIndex] !== undefined) { - propertyIndex = targetObject.morphTargetDictionary[propertyIndex]; - } - } + this.lightDistance.visible = false; - bindingType = this.BindingType.ArrayElement; - this.resolvedProperty = nodeProperty; - this.propertyIndex = propertyIndex; - } else if (nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined) { - // must use copy for Object3D.Euler/Quaternion - bindingType = this.BindingType.HasFromToArray; - this.resolvedProperty = nodeProperty; - } else if (Array.isArray(nodeProperty)) { - bindingType = this.BindingType.EntireArray; - this.resolvedProperty = nodeProperty; - } else { - this.propertyName = propertyName; - } // select getter / setter + } else { + this.lightDistance.scale.set( d, d, d ); - 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.add( this.lightDistance ); + */ - this.getValue = this._getValue_unbound; - this.setValue = this._setValue_unbound; } - } - - PropertyBinding.Composite = Composite; - PropertyBinding.prototype.BindingType = { - Direct: 0, - EntireArray: 1, - ArrayElement: 2, - HasFromToArray: 3 - }; - PropertyBinding.prototype.Versioning = { - None: 0, - NeedsUpdate: 1, - 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._setValue_fromArray, PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate, PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate]]; + dispose() { - /** - * - * A group of objects that receives a shared animation state. - * - * Usage: - * - * - Add objects you would otherwise pass as 'root' to the - * constructor or the .clipAction method of AnimationMixer. - * - * - Instead pass this object as 'root'. - * - * - You can also add and remove objects later when the mixer - * is running. - * - * Note: - * - * Objects of this class appear as one object to the mixer, - * so cache control of the individual objects must be done - * on the group. - * - * Limitation: - * - * - The animated properties must be compatible among the - * all objects in the group. - * - * - A single property can either be controlled through a - * target group or directly, but not both. - */ + this.geometry.dispose(); + this.material.dispose(); - class AnimationObjectGroup { - constructor() { - this.isAnimationObjectGroup = true; - 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 + update() { - const indices = {}; - this._indicesByUUID = indices; // for bookkeeping + this.light.updateWorldMatrix( true, false ); - for (let i = 0, n = arguments.length; i !== n; ++i) { - indices[arguments[i].uuid] = i; - } + if ( this.color !== undefined ) { - this._paths = []; // inside: string + this.material.color.set( this.color ); - this._parsedPaths = []; // inside: { we don't care, here } + } else { - this._bindings = []; // inside: Array< PropertyBinding > + this.material.color.copy( this.light.color ); - this._bindingsIndicesByPath = {}; // inside: indices in these arrays + } - const scope = this; - this.stats = { - objects: { - get total() { - return scope._objects.length; - }, + /* + const d = this.light.distance; - get inUse() { - return this.total - scope.nCachedObjects_; - } + if ( d === 0.0 ) { - }, + this.lightDistance.visible = false; - get bindingsPerObject() { - return scope._bindings.length; - } + } else { - }; - } + this.lightDistance.visible = true; + this.lightDistance.scale.set( d, d, d ); - add() { - const objects = this._objects, - indicesByUUID = this._indicesByUUID, - paths = this._paths, - parsedPaths = this._parsedPaths, - bindings = this._bindings, - nBindings = bindings.length; - let knownObject = undefined, - nObjects = objects.length, - nCachedObjects = this.nCachedObjects_; + } + */ - for (let i = 0, n = arguments.length; i !== n; ++i) { - const object = arguments[i], - 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 - - 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 - - const firstActiveIndex = --nCachedObjects, - lastCachedObject = objects[firstActiveIndex]; - indicesByUUID[lastCachedObject.uuid] = index; - objects[index] = lastCachedObject; - indicesByUUID[uuid] = firstActiveIndex; - objects[firstActiveIndex] = object; // accounting is done, now do the same for all bindings - - for (let j = 0, m = nBindings; j !== m; ++j) { - const bindingsForPath = bindings[j], - 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 + const _vector$1 = /*@__PURE__*/ new Vector3(); + const _color1 = /*@__PURE__*/ new Color(); + const _color2 = /*@__PURE__*/ new Color(); - } // for arguments + class HemisphereLightHelper extends Object3D { + constructor( light, size, color ) { - this.nCachedObjects_ = nCachedObjects; - } + super(); - remove() { - const objects = this._objects, - indicesByUUID = this._indicesByUUID, - bindings = this._bindings, - nBindings = bindings.length; - let nCachedObjects = this.nCachedObjects_; + this.light = light; - for (let i = 0, n = arguments.length; i !== n; ++i) { - const object = arguments[i], - uuid = object.uuid, - index = indicesByUUID[uuid]; + this.matrix = light.matrixWorld; + this.matrixAutoUpdate = false; - if (index !== undefined && index >= nCachedObjects) { - // move existing object into the CACHED region - const lastCachedIndex = nCachedObjects++, - firstActiveObject = objects[lastCachedIndex]; - indicesByUUID[firstActiveObject.uuid] = index; - objects[index] = firstActiveObject; - indicesByUUID[uuid] = lastCachedIndex; - objects[lastCachedIndex] = object; // accounting is done, now do the same for all bindings + this.color = color; - for (let j = 0, m = nBindings; j !== m; ++j) { - const bindingsForPath = bindings[j], - firstActive = bindingsForPath[lastCachedIndex], - binding = bindingsForPath[index]; - bindingsForPath[index] = firstActive; - bindingsForPath[lastCachedIndex] = binding; - } - } - } // for arguments + this.type = 'HemisphereLightHelper'; + const geometry = new OctahedronGeometry( size ); + geometry.rotateY( Math.PI * 0.5 ); - this.nCachedObjects_ = nCachedObjects; - } // remove & forget + this.material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } ); + if ( this.color === undefined ) this.material.vertexColors = true; + const position = geometry.getAttribute( 'position' ); + const colors = new Float32Array( position.count * 3 ); - uncache() { - const objects = this._objects, - indicesByUUID = this._indicesByUUID, - bindings = this._bindings, - nBindings = bindings.length; - let nCachedObjects = this.nCachedObjects_, - nObjects = objects.length; + geometry.setAttribute( 'color', new BufferAttribute( colors, 3 ) ); - for (let i = 0, n = arguments.length; i !== n; ++i) { - const object = arguments[i], - uuid = object.uuid, - index = indicesByUUID[uuid]; + this.add( new Mesh( geometry, this.material ) ); - if (index !== undefined) { - delete indicesByUUID[uuid]; + this.update(); - 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 - - indicesByUUID[lastCachedObject.uuid] = index; - objects[index] = lastCachedObject; // last object goes to the activated slot and pop - - indicesByUUID[lastObject.uuid] = firstActiveIndex; - objects[firstActiveIndex] = lastObject; - objects.pop(); // accounting is done, now do the same for all bindings - - for (let j = 0, m = nBindings; j !== m; ++j) { - const bindingsForPath = bindings[j], - lastCached = bindingsForPath[firstActiveIndex], - last = bindingsForPath[lastIndex]; - bindingsForPath[index] = lastCached; - bindingsForPath[firstActiveIndex] = last; - bindingsForPath.pop(); - } - } else { - // object is active, just swap with the last and pop - const lastIndex = --nObjects, - lastObject = objects[lastIndex]; + } - if (lastIndex > 0) { - indicesByUUID[lastObject.uuid] = index; - } + dispose() { - objects[index] = lastObject; - objects.pop(); // accounting is done, now do the same for all bindings + this.children[ 0 ].geometry.dispose(); + this.children[ 0 ].material.dispose(); - for (let j = 0, m = nBindings; j !== m; ++j) { - const bindingsForPath = bindings[j]; - bindingsForPath[index] = bindingsForPath[lastIndex]; - bindingsForPath.pop(); - } - } // cached or active + } - } // if object is known + update() { - } // for arguments + const mesh = this.children[ 0 ]; + if ( this.color !== undefined ) { - this.nCachedObjects_ = nCachedObjects; - } // Internal interface used by befriended PropertyBinding.Composite: + this.material.color.set( this.color ); + } else { - 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); - index = bindings.length; - indicesByPath[path] = index; - paths.push(path); - parsedPaths.push(parsedPath); - bindings.push(bindingsForPath); + const colors = mesh.geometry.getAttribute( 'color' ); - for (let i = nCachedObjects, n = objects.length; i !== n; ++i) { - const object = objects[i]; - bindingsForPath[i] = new PropertyBinding(object, path, parsedPath); - } + _color1.copy( this.light.color ); + _color2.copy( this.light.groundColor ); - return bindingsForPath; - } + for ( let i = 0, l = colors.count; i < l; i ++ ) { - 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 color = ( i < ( l / 2 ) ) ? _color1 : _color2; - if (index !== undefined) { - const paths = this._paths, - parsedPaths = this._parsedPaths, - bindings = this._bindings, - lastBindingsIndex = bindings.length - 1, - lastBindings = bindings[lastBindingsIndex], - lastBindingsPath = path[lastBindingsIndex]; - indicesByPath[lastBindingsPath] = index; - bindings[index] = lastBindings; - bindings.pop(); - parsedPaths[index] = parsedPaths[lastBindingsIndex]; - parsedPaths.pop(); - paths[index] = paths[lastBindingsIndex]; - paths.pop(); - } - } + colors.setXYZ( i, color.r, color.g, color.b ); - } + } - class AnimationAction { - constructor(mixer, clip, localRoot = null, blendMode = clip.blendMode) { - this._mixer = mixer; - this._clip = clip; - this._localRoot = localRoot; - this.blendMode = blendMode; - const tracks = clip.tracks, - nTracks = tracks.length, - interpolants = new Array(nTracks); - const interpolantSettings = { - endingStart: ZeroCurvatureEnding, - endingEnd: ZeroCurvatureEnding - }; + colors.needsUpdate = true; - 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) - - this._propertyBindings = new Array(nTracks); - this._cacheIndex = null; // for the memory manager + this.light.updateWorldMatrix( true, false ); - this._byClipCacheIndex = null; // for the memory manager + mesh.lookAt( _vector$1.setFromMatrixPosition( this.light.matrixWorld ).negate() ); - this._timeScaleInterpolant = null; - this._weightInterpolant = null; - this.loop = LoopRepeat; - this._loopCount = -1; // global mixer time when the action is to be started - // it's set back to 'null' upon start of the action + } - this._startTime = null; // 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; - this.weight = 1; - this._effectiveWeight = 1; - this.repetitions = Infinity; // no. of repetitions when looping + class GridHelper extends LineSegments { - this.paused = false; // true -> zero effective time scale + constructor( size = 10, divisions = 10, color1 = 0x444444, color2 = 0x888888 ) { - this.enabled = true; // false -> zero effective weight + color1 = new Color( color1 ); + color2 = new Color( color2 ); - this.clampWhenFinished = false; // keep feeding the last frame? + const center = divisions / 2; + const step = size / divisions; + const halfSize = size / 2; - this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate + const vertices = [], colors = []; - this.zeroSlopeAtEnd = true; // clips for start, loop and end - } // State & Scheduling + 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 ); - play() { - this._mixer._activateAction(this); + const color = i === center ? color1 : color2; - return this; - } + color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; - stop() { - this._mixer._deactivateAction(this); + } - return this.reset(); - } + const geometry = new BufferGeometry(); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - reset() { - this.paused = false; - this.enabled = true; - this.time = 0; // restart clip + const material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } ); - this._loopCount = -1; // forget previous loops + super( geometry, material ); - this._startTime = null; // forget scheduling + this.type = 'GridHelper'; - 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 - + dispose() { - isScheduled() { - return this._mixer._isActiveAction(this); - } + this.geometry.dispose(); + this.material.dispose(); - startAt(time) { - this._startTime = time; - return this; } - setLoop(mode, repetitions) { - this.loop = mode; - this.repetitions = repetitions; - return this; - } // Weight - // set the weight stopping any scheduled fading - // although .enabled = false yields an effective weight of zero, this - // method does *not* change .enabled, because it would be confusing + } + class PolarGridHelper extends LineSegments { - setEffectiveWeight(weight) { - this.weight = weight; // note: same logic as when updated at runtime + constructor( radius = 10, sectors = 16, rings = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888 ) { - this._effectiveWeight = this.enabled ? weight : 0; - return this.stopFading(); - } // return the weight considering fading and .enabled + color1 = new Color( color1 ); + color2 = new Color( color2 ); + const vertices = []; + const colors = []; - getEffectiveWeight() { - return this._effectiveWeight; - } + // create the sectors - fadeIn(duration) { - return this._scheduleFading(duration, 0, 1); - } + if ( sectors > 1 ) { - fadeOut(duration) { - return this._scheduleFading(duration, 1, 0); - } + for ( let i = 0; i < sectors; i ++ ) { - crossFadeFrom(fadeOutAction, duration, warp) { - fadeOutAction.fadeOut(duration); - this.fadeIn(duration); + const v = ( i / sectors ) * ( Math.PI * 2 ); - if (warp) { - const fadeInDuration = this._clip.duration, - fadeOutDuration = fadeOutAction._clip.duration, - startEndRatio = fadeOutDuration / fadeInDuration, - endStartRatio = fadeInDuration / fadeOutDuration; - fadeOutAction.warp(1.0, startEndRatio, duration); - this.warp(endStartRatio, 1.0, duration); - } + const x = Math.sin( v ) * radius; + const z = Math.cos( v ) * radius; - return this; - } + vertices.push( 0, 0, 0 ); + vertices.push( x, 0, z ); - crossFadeTo(fadeInAction, duration, warp) { - return fadeInAction.crossFadeFrom(this, duration, warp); - } + const color = ( i & 1 ) ? color1 : color2; - stopFading() { - const weightInterpolant = this._weightInterpolant; + colors.push( color.r, color.g, color.b ); + colors.push( color.r, color.g, color.b ); - if (weightInterpolant !== null) { - this._weightInterpolant = null; + } - this._mixer._takeBackControlInterpolant(weightInterpolant); } - return this; - } // Time Scale Control - // set the time scale stopping any scheduled warping - // although .paused = true yields an effective time scale of zero, this - // method does *not* change .paused, because it would be confusing + // create the rings + for ( let i = 0; i < rings; i ++ ) { - setEffectiveTimeScale(timeScale) { - this.timeScale = timeScale; - this._effectiveTimeScale = this.paused ? 0 : timeScale; - return this.stopWarping(); - } // return the time scale considering warping and .paused + const color = ( i & 1 ) ? color1 : color2; + const r = radius - ( radius / rings * i ); - getEffectiveTimeScale() { - return this._effectiveTimeScale; - } + for ( let j = 0; j < divisions; j ++ ) { - setDuration(duration) { - this.timeScale = this._clip.duration / duration; - return this.stopWarping(); - } + // first vertex - syncWith(action) { - this.time = action.time; - this.timeScale = action.timeScale; - return this.stopWarping(); - } + let v = ( j / divisions ) * ( Math.PI * 2 ); - halt(duration) { - return this.warp(this._effectiveTimeScale, 0, duration); - } + let x = Math.sin( v ) * r; + let z = Math.cos( v ) * r; - warp(startTimeScale, endTimeScale, duration) { - const mixer = this._mixer, - now = mixer.time, - timeScale = this.timeScale; - let interpolant = this._timeScaleInterpolant; + vertices.push( x, 0, z ); + colors.push( color.r, color.g, color.b ); - if (interpolant === null) { - interpolant = mixer._lendControlInterpolant(); - this._timeScaleInterpolant = interpolant; - } + // second vertex - const times = interpolant.parameterPositions, - values = interpolant.sampleValues; - times[0] = now; - times[1] = now + duration; - values[0] = startTimeScale / timeScale; - values[1] = endTimeScale / timeScale; - return this; - } + v = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 ); - stopWarping() { - const timeScaleInterpolant = this._timeScaleInterpolant; + x = Math.sin( v ) * r; + z = Math.cos( v ) * r; - if (timeScaleInterpolant !== null) { - this._timeScaleInterpolant = null; + vertices.push( x, 0, z ); + colors.push( color.r, color.g, color.b ); + + } - this._mixer._takeBackControlInterpolant(timeScaleInterpolant); } - return this; - } // Object Accessors + const geometry = new BufferGeometry(); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + const material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } ); + + super( geometry, material ); + + this.type = 'PolarGridHelper'; - getMixer() { - return this._mixer; } - getClip() { - return this._clip; + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + } - getRoot() { - return this._localRoot || this._mixer._root; - } // Interna + } + const _v1 = /*@__PURE__*/ new Vector3(); + const _v2 = /*@__PURE__*/ new Vector3(); + const _v3 = /*@__PURE__*/ new Vector3(); - _update(time, deltaTime, timeDirection, accuIndex) { - // called by the mixer - if (!this.enabled) { - // call ._updateWeight() to update ._effectiveWeight - this._updateWeight(time); + class DirectionalLightHelper extends Object3D { - return; - } + constructor( light, size, color ) { - const startTime = this._startTime; + super(); - if (startTime !== null) { - // check for scheduled start of action - const timeRunning = (time - startTime) * timeDirection; + this.light = light; - if (timeRunning < 0 || timeDirection === 0) { - return; // yet to come / don't decide when delta = 0 - } // start + this.matrix = light.matrixWorld; + this.matrixAutoUpdate = false; + this.color = color; - this._startTime = null; // unschedule + this.type = 'DirectionalLightHelper'; - deltaTime = timeDirection * timeRunning; - } // apply time scale and advance time + 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 ) ); - deltaTime *= this._updateTimeScale(time); + const material = new LineBasicMaterial( { fog: false, toneMapped: false } ); - const clipTime = this._updateTime(deltaTime); // note: _updateTime may disable the action resulting in - // an effective weight of 0 + this.lightPlane = new Line( geometry, material ); + this.add( this.lightPlane ); + geometry = new BufferGeometry(); + geometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) ); - const weight = this._updateWeight(time); + this.targetLine = new Line( geometry, material ); + this.add( this.targetLine ); - if (weight > 0) { - const interpolants = this._interpolants; - const propertyMixers = this._propertyBindings; + this.update(); - switch (this.blendMode) { - case AdditiveAnimationBlendMode: - for (let j = 0, m = interpolants.length; j !== m; ++j) { - interpolants[j].evaluate(clipTime); - propertyMixers[j].accumulateAdditive(weight); - } + } - break; + dispose() { - case NormalAnimationBlendMode: - default: - for (let j = 0, m = interpolants.length; j !== m; ++j) { - interpolants[j].evaluate(clipTime); - propertyMixers[j].accumulate(accuIndex, weight); - } + this.lightPlane.geometry.dispose(); + this.lightPlane.material.dispose(); + this.targetLine.geometry.dispose(); + this.targetLine.material.dispose(); - } - } } - _updateWeight(time) { - let weight = 0; + update() { - if (this.enabled) { - weight = this.weight; - const interpolant = this._weightInterpolant; + this.light.updateWorldMatrix( true, false ); + this.light.target.updateWorldMatrix( true, false ); - if (interpolant !== null) { - const interpolantValue = interpolant.evaluate(time)[0]; - weight *= interpolantValue; + _v1.setFromMatrixPosition( this.light.matrixWorld ); + _v2.setFromMatrixPosition( this.light.target.matrixWorld ); + _v3.subVectors( _v2, _v1 ); - if (time > interpolant.parameterPositions[1]) { - this.stopFading(); + this.lightPlane.lookAt( _v2 ); + + if ( this.color !== undefined ) { + + this.lightPlane.material.color.set( this.color ); + this.targetLine.material.color.set( this.color ); + + } else { + + this.lightPlane.material.color.copy( this.light.color ); + this.targetLine.material.color.copy( this.light.color ); - if (interpolantValue === 0) { - // faded out, disable - this.enabled = false; - } - } - } } - this._effectiveWeight = weight; - return weight; + this.targetLine.lookAt( _v2 ); + this.targetLine.scale.z = _v3.length(); + } - _updateTimeScale(time) { - let timeScale = 0; + } - if (!this.paused) { - timeScale = this.timeScale; - const interpolant = this._timeScaleInterpolant; + const _vector = /*@__PURE__*/ new Vector3(); + const _camera = /*@__PURE__*/ new Camera(); - if (interpolant !== null) { - const interpolantValue = interpolant.evaluate(time)[0]; - timeScale *= interpolantValue; + /** + * - shows frustum, line of sight and up of the camera + * - suitable for fast updates + * - based on frustum visualization in lightgl.js shadowmap example + * https://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html + */ - if (time > interpolant.parameterPositions[1]) { - this.stopWarping(); + class CameraHelper extends LineSegments { - if (timeScale === 0) { - // motion has halted, pause - this.paused = true; - } else { - // warp done - apply final time scale - this.timeScale = timeScale; - } - } - } - } + constructor( camera ) { - this._effectiveTimeScale = timeScale; - return timeScale; - } + const geometry = new BufferGeometry(); + const material = new LineBasicMaterial( { color: 0xffffff, vertexColors: true, toneMapped: false } ); - _updateTime(deltaTime) { - const duration = this._clip.duration; - const loop = this.loop; - let time = this.time + deltaTime; - let loopCount = this._loopCount; - const pingPong = loop === LoopPingPong; + const vertices = []; + const colors = []; - if (deltaTime === 0) { - if (loopCount === -1) return time; - return pingPong && (loopCount & 1) === 1 ? duration - time : time; - } + const pointMap = {}; - if (loop === LoopOnce) { - if (loopCount === -1) { - // just started - this._loopCount = 0; + // near - this._setEndings(true, true, false); - } + addLine( 'n1', 'n2' ); + addLine( 'n2', 'n4' ); + addLine( 'n4', 'n3' ); + addLine( 'n3', 'n1' ); - handle_stop: { - if (time >= duration) { - time = duration; - } else if (time < 0) { - time = 0; - } else { - this.time = time; - break handle_stop; - } + // far - if (this.clampWhenFinished) this.paused = true;else this.enabled = false; - this.time = time; + addLine( 'f1', 'f2' ); + addLine( 'f2', 'f4' ); + addLine( 'f4', 'f3' ); + addLine( 'f3', 'f1' ); - this._mixer.dispatchEvent({ - type: 'finished', - action: this, - direction: deltaTime < 0 ? -1 : 1 - }); - } - } else { - // repetitive Repeat or PingPong - if (loopCount === -1) { - // just started - if (deltaTime >= 0) { - loopCount = 0; + // sides - 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); - } - } + addLine( 'n1', 'f1' ); + addLine( 'n2', 'f2' ); + addLine( 'n3', 'f3' ); + addLine( 'n4', 'f4' ); - if (time >= duration || time < 0) { - // wrap around - const loopDelta = Math.floor(time / duration); // signed + // cone - time -= duration * loopDelta; - loopCount += Math.abs(loopDelta); - const pending = this.repetitions - loopCount; + addLine( 'p', 'n1' ); + addLine( 'p', 'n2' ); + addLine( 'p', 'n3' ); + addLine( 'p', 'n4' ); - 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; + // up - this._mixer.dispatchEvent({ - type: 'finished', - action: this, - direction: deltaTime > 0 ? 1 : -1 - }); - } else { - // keep running - if (pending === 1) { - // entering the last round - const atStart = deltaTime < 0; + addLine( 'u1', 'u2' ); + addLine( 'u2', 'u3' ); + addLine( 'u3', 'u1' ); - this._setEndings(atStart, !atStart, pingPong); - } else { - this._setEndings(false, false, pingPong); - } + // target - this._loopCount = loopCount; - this.time = time; + addLine( 'c', 't' ); + addLine( 'p', 'c' ); - this._mixer.dispatchEvent({ - type: 'loop', - action: this, - loopDelta: loopDelta - }); - } - } else { - this.time = time; - } + // cross + + addLine( 'cn1', 'cn2' ); + addLine( 'cn3', 'cn4' ); + + addLine( 'cf1', 'cf2' ); + addLine( 'cf3', 'cf4' ); + + function addLine( a, b ) { + + addPoint( a ); + addPoint( b ); - if (pingPong && (loopCount & 1) === 1) { - // invert time for the "pong round" - return duration - time; - } } - return time; - } + function addPoint( id ) { - _setEndings(atStart, atEnd, pingPong) { - const settings = this._interpolantSettings; + vertices.push( 0, 0, 0 ); + colors.push( 0, 0, 0 ); - 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 ( pointMap[ id ] === undefined ) { + + pointMap[ id ] = []; - if (atEnd) { - settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; - } else { - settings.endingEnd = WrapAroundEnding; } - } - } - _scheduleFading(duration, weightNow, weightThen) { - const mixer = this._mixer, - now = mixer.time; - let interpolant = this._weightInterpolant; + pointMap[ id ].push( ( vertices.length / 3 ) - 1 ); - if (interpolant === null) { - interpolant = mixer._lendControlInterpolant(); - this._weightInterpolant = interpolant; } - const times = interpolant.parameterPositions, - values = interpolant.sampleValues; - times[0] = now; - values[0] = weightNow; - times[1] = now + duration; - values[1] = weightThen; - return this; - } + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - } + super( geometry, material ); - const _controlInterpolantsResultBuffer = /*@__PURE__*/new Float32Array(1); + this.type = 'CameraHelper'; - class AnimationMixer extends EventDispatcher { - constructor(root) { - super(); - this._root = root; + this.camera = camera; + if ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix(); - this._initMemoryManager(); + this.matrix = camera.matrixWorld; + this.matrixAutoUpdate = false; + + this.pointMap = pointMap; + + this.update(); + + // colors + + const colorFrustum = new Color( 0xffaa00 ); + const colorCone = new Color( 0xff0000 ); + const colorUp = new Color( 0x00aaff ); + const colorTarget = new Color( 0xffffff ); + const colorCross = new Color( 0x333333 ); + + this.setColors( colorFrustum, colorCone, colorUp, colorTarget, colorCross ); - 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; - let bindingsByName = bindingsByRoot[rootUuid]; - - if (bindingsByName === undefined) { - bindingsByName = {}; - bindingsByRoot[rootUuid] = bindingsByName; - } + setColors( frustum, cone, up, target, cross ) { - for (let i = 0; i !== nTracks; ++i) { - const track = tracks[i], - trackName = track.name; - let binding = bindingsByName[trackName]; + const geometry = this.geometry; - if (binding !== undefined) { - ++binding.referenceCount; - bindings[i] = binding; - } else { - binding = bindings[i]; + const colorAttribute = geometry.getAttribute( 'color' ); - if (binding !== undefined) { - // existing binding, make sure the cache knows - if (binding._cacheIndex === null) { - ++binding.referenceCount; + // near - this._addInactiveBinding(binding, rootUuid, trackName); - } + 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 - continue; - } + // far - const path = prototypeAction && prototypeAction._propertyBindings[i].binding.parsedPath; - binding = new PropertyMixer(PropertyBinding.create(root, trackName, path), track.ValueTypeName, track.getValueSize()); - ++binding.referenceCount; + 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 - this._addInactiveBinding(binding, rootUuid, trackName); + // sides - bindings[i] = binding; - } + 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 - interpolants[i].resultBuffer = binding.buffer; - } - } + // cone - _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]; + 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 - this._bindAction(action, actionsForClip && actionsForClip.knownActions[0]); + // up - this._addInactiveAction(action, clipUuid, rootUuid); - } + 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 - const bindings = action._propertyBindings; // increment reference counts / sort out state + // target - for (let i = 0, n = bindings.length; i !== n; ++i) { - const binding = bindings[i]; + 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 - if (binding.useCount++ === 0) { - this._lendBinding(binding); + // cross - binding.saveOriginalState(); - } - } + 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 - this._lendAction(action); - } - } + 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 - _deactivateAction(action) { - if (this._isActiveAction(action)) { - const bindings = action._propertyBindings; // decrement reference counts / sort out state + colorAttribute.needsUpdate = true; - for (let i = 0, n = bindings.length; i !== n; ++i) { - const binding = bindings[i]; + } - if (--binding.useCount === 0) { - binding.restoreOriginalState(); + update() { - this._takeBackBinding(binding); - } - } + const geometry = this.geometry; + const pointMap = this.pointMap; - this._takeBackAction(action); - } - } // Memory manager + const w = 1, h = 1; + // we need just camera projection matrix inverse + // world matrix must be identity - _initMemoryManager() { - this._actions = []; // 'nActiveActions' followed by inactive ones + _camera.projectionMatrixInverse.copy( this.camera.projectionMatrixInverse ); - this._nActiveActions = 0; - this._actionsByClip = {}; // inside: - // { - // knownActions: Array< AnimationAction > - used as prototypes - // actionByRoot: AnimationAction - lookup - // } + // center / target - this._bindings = []; // 'nActiveBindings' followed by inactive ones + setPoint( 'c', pointMap, geometry, _camera, 0, 0, - 1 ); + setPoint( 't', pointMap, geometry, _camera, 0, 0, 1 ); - this._nActiveBindings = 0; - this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer > + // near - this._controlInterpolants = []; // same game as above + 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 ); - this._nActiveControlInterpolants = 0; - const scope = this; - this.stats = { - actions: { - get total() { - return scope._actions.length; - }, + // far - get inUse() { - return scope._nActiveActions; - } + 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 ); - }, - bindings: { - get total() { - return scope._bindings.length; - }, + // up - get inUse() { - return scope._nActiveBindings; - } + 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 ); - }, - controlInterpolants: { - get total() { - return scope._controlInterpolants.length; - }, + // cross - get inUse() { - return scope._nActiveControlInterpolants; - } + setPoint( 'cf1', pointMap, geometry, _camera, - w, 0, 1 ); + setPoint( 'cf2', pointMap, geometry, _camera, w, 0, 1 ); + setPoint( 'cf3', pointMap, geometry, _camera, 0, - h, 1 ); + setPoint( 'cf4', pointMap, geometry, _camera, 0, h, 1 ); - } - }; - } // Memory management for AnimationAction objects + setPoint( 'cn1', pointMap, geometry, _camera, - w, 0, - 1 ); + setPoint( 'cn2', pointMap, geometry, _camera, w, 0, - 1 ); + setPoint( 'cn3', pointMap, geometry, _camera, 0, - h, - 1 ); + setPoint( 'cn4', pointMap, geometry, _camera, 0, h, - 1 ); + geometry.getAttribute( 'position' ).needsUpdate = true; - _isActiveAction(action) { - const index = action._cacheIndex; - return index !== null && index < this._nActiveActions; } - _addInactiveAction(action, clipUuid, rootUuid) { - const actions = this._actions, - actionsByClip = this._actionsByClip; - let actionsForClip = actionsByClip[clipUuid]; + dispose() { - if (actionsForClip === undefined) { - actionsForClip = { - knownActions: [action], - actionByRoot: {} - }; - action._byClipCacheIndex = 0; - actionsByClip[clipUuid] = actionsForClip; - } else { - const knownActions = actionsForClip.knownActions; - action._byClipCacheIndex = knownActions.length; - knownActions.push(action); - } + this.geometry.dispose(); + this.material.dispose(); - 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._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; - lastKnownAction._byClipCacheIndex = byClipCacheIndex; - knownActionsForClip[byClipCacheIndex] = lastKnownAction; - knownActionsForClip.pop(); - action._byClipCacheIndex = null; - const actionByRoot = actionsForClip.actionByRoot, - rootUuid = (action._localRoot || this._root).uuid; - delete actionByRoot[rootUuid]; + } - if (knownActionsForClip.length === 0) { - delete actionsByClip[clipUuid]; - } - this._removeInactiveBindingsForAction(action); - } + function setPoint( point, pointMap, geometry, camera, x, y, z ) { - _removeInactiveBindingsForAction(action) { - const bindings = action._propertyBindings; + _vector.set( x, y, z ).unproject( camera ); - for (let i = 0, n = bindings.length; i !== n; ++i) { - const binding = bindings[i]; + 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 ); - 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]; - action._cacheIndex = lastActiveIndex; - actions[lastActiveIndex] = action; - firstInactiveAction._cacheIndex = prevIndex; - actions[prevIndex] = firstInactiveAction; + } + + 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 ] ); + const positions = new Float32Array( 8 * 3 ); + + const geometry = new BufferGeometry(); + geometry.setIndex( new BufferAttribute( indices, 1 ) ); + geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) ); + + super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); + + this.object = object; + this.type = 'BoxHelper'; + + this.matrixAutoUpdate = false; + + this.update(); + } - _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]; - action._cacheIndex = firstInactiveIndex; - actions[firstInactiveIndex] = action; - lastActiveAction._cacheIndex = prevIndex; - actions[prevIndex] = lastActiveAction; - } // Memory management for PropertyMixer objects + update( object ) { + if ( object !== undefined ) { - _addInactiveBinding(binding, rootUuid, trackName) { - const bindingsByRoot = this._bindingsByRootAndName, - bindings = this._bindings; - let bindingByName = bindingsByRoot[rootUuid]; + console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' ); - if (bindingByName === undefined) { - bindingByName = {}; - bindingsByRoot[rootUuid] = bindingByName; } - bindingByName[trackName] = binding; - binding._cacheIndex = bindings.length; - bindings.push(binding); - } + if ( this.object !== undefined ) { - _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; - lastInactiveBinding._cacheIndex = cacheIndex; - bindings[cacheIndex] = lastInactiveBinding; - bindings.pop(); - delete bindingByName[trackName]; + _box.setFromObject( this.object ); - if (Object.keys(bindingByName).length === 0) { - delete bindingsByRoot[rootUuid]; } - } - _lendBinding(binding) { - const bindings = this._bindings, - prevIndex = binding._cacheIndex, - lastActiveIndex = this._nActiveBindings++, - firstInactiveBinding = bindings[lastActiveIndex]; - binding._cacheIndex = lastActiveIndex; - bindings[lastActiveIndex] = binding; - firstInactiveBinding._cacheIndex = prevIndex; - bindings[prevIndex] = firstInactiveBinding; - } + if ( _box.isEmpty() ) return; - _takeBackBinding(binding) { - const bindings = this._bindings, - prevIndex = binding._cacheIndex, - firstInactiveIndex = --this._nActiveBindings, - lastActiveBinding = bindings[firstInactiveIndex]; - binding._cacheIndex = firstInactiveIndex; - bindings[firstInactiveIndex] = binding; - lastActiveBinding._cacheIndex = prevIndex; - bindings[prevIndex] = lastActiveBinding; - } // Memory management of Interpolants for weight and time scale + const min = _box.min; + const max = _box.max; + /* + 5____4 + 1/___0/| + | 6__|_7 + 2/___3/ - _lendControlInterpolant() { - const interpolants = this._controlInterpolants, - lastActiveIndex = this._nActiveControlInterpolants++; - let interpolant = interpolants[lastActiveIndex]; + 0: max.x, max.y, max.z + 1: min.x, max.y, max.z + 2: min.x, min.y, max.z + 3: max.x, min.y, max.z + 4: max.x, max.y, min.z + 5: min.x, max.y, min.z + 6: min.x, min.y, min.z + 7: max.x, min.y, min.z + */ - if (interpolant === undefined) { - interpolant = new LinearInterpolant(new Float32Array(2), new Float32Array(2), 1, _controlInterpolantsResultBuffer); - interpolant.__cacheIndex = lastActiveIndex; - interpolants[lastActiveIndex] = interpolant; - } + const position = this.geometry.attributes.position; + const array = position.array; + + array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z; + array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z; + array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z; + array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z; + array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z; + array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z; + array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z; + array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z; + + position.needsUpdate = true; + + this.geometry.computeBoundingSphere(); - return interpolant; } - _takeBackControlInterpolant(interpolant) { - const interpolants = this._controlInterpolants, - 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 - // object (this method allocates a lot of dynamic memory in case a - // previously unknown clip/root combination is specified) + setFromObject( object ) { + + this.object = object; + this.update(); + return this; - clipAction(clip, optionalRoot, blendMode) { - const root = optionalRoot || this._root, - 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; - } else { - blendMode = NormalAnimationBlendMode; - } - } + copy( source, recursive ) { - if (actionsForClip !== undefined) { - const existingAction = actionsForClip.actionByRoot[rootUuid]; + super.copy( source, recursive ); - 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 + this.object = source.object; + + return this; + } - prototypeAction = actionsForClip.knownActions[0]; // also, take the clip from the prototype action + dispose() { - if (clipObject === null) clipObject = prototypeAction._clip; - } // clip must be known when specified via string + this.geometry.dispose(); + this.material.dispose(); + } - if (clipObject === null) return null; // allocate all resources required to run it + } - const newAction = new AnimationAction(this, clipObject, optionalRoot, blendMode); + class Box3Helper extends LineSegments { - this._bindAction(newAction, prototypeAction); // and make the action known to the memory manager + constructor( box, 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 ] ); - this._addInactiveAction(newAction, clipUuid, rootUuid); + const positions = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 1, - 1, 1, - 1, - 1 ]; - return newAction; - } // get an existing action + const geometry = new BufferGeometry(); + geometry.setIndex( new BufferAttribute( indices, 1 ) ); - 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]; + geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); - if (actionsForClip !== undefined) { - return actionsForClip.actionByRoot[rootUuid] || null; - } + super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); - return null; - } // deactivates all previously scheduled actions + this.box = box; + this.type = 'Box3Helper'; - stopAllAction() { - const actions = this._actions, - nActions = this._nActiveActions; + this.geometry.computeBoundingSphere(); - for (let i = nActions - 1; i >= 0; --i) { - actions[i].stop(); - } + } - return this; - } // advance the time and update apply the animation + updateMatrixWorld( force ) { + const box = this.box; - 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 + if ( box.isEmpty() ) return; - for (let i = 0; i !== nActions; ++i) { - const action = actions[i]; + box.getCenter( this.position ); - action._update(time, deltaTime, timeDirection, accuIndex); - } // update scene graph + box.getSize( this.scale ); + this.scale.multiplyScalar( 0.5 ); - const bindings = this._bindings, - nBindings = this._nActiveBindings; + super.updateMatrixWorld( force ); - for (let i = 0; i !== nBindings; ++i) { - bindings[i].apply(accuIndex); - } + } - return this; - } // Allows you to seek to a specific time in an animation. + dispose() { + this.geometry.dispose(); + this.material.dispose(); - 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 + class PlaneHelper extends Line { + constructor( plane, size = 1, hex = 0xffff00 ) { - getRoot() { - return this._root; - } // free all resources specific to a particular clip + const color = hex; + const positions = [ 1, - 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, - 1, 0, 1, 1, 0 ]; - uncacheClip(clip) { - const actions = this._actions, - clipUuid = clip.uuid, - actionsByClip = this._actionsByClip, - actionsForClip = actionsByClip[clipUuid]; + const geometry = new BufferGeometry(); + geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + geometry.computeBoundingSphere(); - 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; + super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); - for (let i = 0, n = actionsToRemove.length; i !== n; ++i) { - const action = actionsToRemove[i]; + this.type = 'PlaneHelper'; - this._deactivateAction(action); + this.plane = plane; - const cacheIndex = action._cacheIndex, - lastInactiveAction = actions[actions.length - 1]; - action._cacheIndex = null; - action._byClipCacheIndex = null; - lastInactiveAction._cacheIndex = cacheIndex; - actions[cacheIndex] = lastInactiveAction; - actions.pop(); + this.size = size; - this._removeInactiveBindingsForAction(action); - } + const positions2 = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ]; - delete actionsByClip[clipUuid]; - } - } // free all resources specific to a particular root target object + const geometry2 = new BufferGeometry(); + geometry2.setAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); + geometry2.computeBoundingSphere(); + this.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false, toneMapped: false } ) ) ); - uncacheRoot(root) { - const rootUuid = root.uuid, - actionsByClip = this._actionsByClip; + } - for (const clipUuid in actionsByClip) { - const actionByRoot = actionsByClip[clipUuid].actionByRoot, - action = actionByRoot[rootUuid]; + updateMatrixWorld( force ) { - if (action !== undefined) { - this._deactivateAction(action); + this.position.set( 0, 0, 0 ); - this._removeInactiveAction(action); - } - } + this.scale.set( 0.5 * this.size, 0.5 * this.size, 1 ); - const bindingsByRoot = this._bindingsByRootAndName, - bindingByName = bindingsByRoot[rootUuid]; + this.lookAt( this.plane.normal ); - if (bindingByName !== undefined) { - for (const trackName in bindingByName) { - const binding = bindingByName[trackName]; - binding.restoreOriginalState(); + this.translateZ( - this.plane.constant ); - this._removeInactiveBinding(binding); - } - } - } // remove a targeted clip from the cache + super.updateMatrixWorld( force ); + } - uncacheAction(clip, optionalRoot) { - const action = this.existingAction(clip, optionalRoot); + dispose() { - if (action !== null) { - this._deactivateAction(action); + this.geometry.dispose(); + this.material.dispose(); + this.children[ 0 ].geometry.dispose(); + this.children[ 0 ].material.dispose(); - this._removeInactiveAction(action); - } } } - class Uniform { - constructor(value) { - if (typeof value === 'string') { - console.warn('THREE.Uniform: Type parameter is no longer needed.'); - value = arguments[1]; - } + const _axis = /*@__PURE__*/ new Vector3(); + let _lineGeometry, _coneGeometry; - this.value = value; - } + class ArrowHelper extends Object3D { - clone() { - return new Uniform(this.value.clone === undefined ? this.value : this.value.clone()); - } + // 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 ) { - class InstancedInterleavedBuffer extends InterleavedBuffer { - constructor(array, stride, meshPerAttribute = 1) { - super(array, stride); - this.isInstancedInterleavedBuffer = true; - this.meshPerAttribute = meshPerAttribute; - } + super(); - copy(source) { - super.copy(source); - this.meshPerAttribute = source.meshPerAttribute; - return this; - } + this.type = 'ArrowHelper'; - clone(data) { - const ib = super.clone(data); - ib.meshPerAttribute = this.meshPerAttribute; - return ib; - } + if ( _lineGeometry === undefined ) { - toJSON(data) { - const json = super.toJSON(data); - json.isInstancedInterleavedBuffer = true; - json.meshPerAttribute = this.meshPerAttribute; - return json; - } + _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 ); - class GLBufferAttribute { - constructor(buffer, type, itemSize, elementSize, count) { - this.isGLBufferAttribute = true; - this.buffer = buffer; - this.type = type; - this.itemSize = itemSize; - this.elementSize = elementSize; - this.count = count; - this.version = 0; - } + } - set needsUpdate(value) { - if (value === true) this.version++; - } + this.position.copy( origin ); - setBuffer(buffer) { - this.buffer = buffer; - return this; - } + this.line = new Line( _lineGeometry, new LineBasicMaterial( { color: color, toneMapped: false } ) ); + this.line.matrixAutoUpdate = false; + this.add( this.line ); - setType(type, elementSize) { - this.type = type; - this.elementSize = elementSize; - return this; - } + this.cone = new Mesh( _coneGeometry, new MeshBasicMaterial( { color: color, toneMapped: false } ) ); + this.cone.matrixAutoUpdate = false; + this.add( this.cone ); - setItemSize(itemSize) { - this.itemSize = itemSize; - return this; - } + this.setDirection( dir ); + this.setLength( length, headLength, headWidth ); - setCount(count) { - this.count = count; - return this; } - } + setDirection( dir ) { - 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) + // dir is assumed to be normalized - this.near = near; - this.far = far; - this.camera = null; - this.layers = new Layers(); - this.params = { - Mesh: {}, - Line: { - threshold: 1 - }, - LOD: {}, - Points: { - threshold: 1 - }, - Sprite: {} - }; - } + if ( dir.y > 0.99999 ) { - set(origin, direction) { - // direction is assumed to be normalized (for accurate distance calculations) - this.ray.set(origin, direction); - } + this.quaternion.set( 0, 0, 0, 1 ); - setFromCamera(coords, camera) { - if (camera.isPerspectiveCamera) { - this.ray.origin.setFromMatrixPosition(camera.matrixWorld); - this.ray.direction.set(coords.x, coords.y, 0.5).unproject(camera).sub(this.ray.origin).normalize(); - this.camera = camera; - } else if (camera.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 + } else if ( dir.y < - 0.99999 ) { + + this.quaternion.set( 1, 0, 0, 0 ); - 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; - } + _axis.set( dir.z, 0, - dir.x ).normalize(); + + const radians = Math.acos( dir.y ); + + this.quaternion.setFromAxisAngle( _axis, radians ); - 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; } - } + setLength( length, headLength = length * 0.2, headWidth = headLength * 0.2 ) { - function ascSort(a, b) { - return a.distance - b.distance; - } + 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(); - function intersectObject(object, raycaster, intersects, recursive) { - if (object.layers.test(raycaster.layers)) { - object.raycast(raycaster, intersects); } - if (recursive === true) { - const children = object.children; + setColor( color ) { + + this.line.material.color.set( color ); + this.cone.material.color.set( color ); - for (let i = 0, l = children.length; i < l; i++) { - intersectObject(children[i], raycaster, intersects, true); - } } - } - /** - * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system - * - * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up. - * The azimuthal angle (theta) is measured from the positive z-axis. - */ + copy( source ) { - class Spherical { - constructor(radius = 1, phi = 0, theta = 0) { - this.radius = radius; - this.phi = phi; // polar angle + super.copy( source, false ); - this.theta = theta; // azimuthal angle + this.line.copy( source.line ); + this.cone.copy( source.cone ); 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 + dispose() { + this.line.geometry.dispose(); + this.line.material.dispose(); + this.cone.geometry.dispose(); + this.cone.material.dispose(); - 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); + class AxesHelper extends LineSegments { - if (this.radius === 0) { - this.theta = 0; - this.phi = 0; - } else { - this.theta = Math.atan2(x, z); - this.phi = Math.acos(clamp(y / this.radius, -1, 1)); - } + constructor( size = 1 ) { - return this; - } + const vertices = [ + 0, 0, 0, size, 0, 0, + 0, 0, 0, 0, size, 0, + 0, 0, 0, 0, 0, size + ]; - clone() { - return new this.constructor().copy(this); - } + const colors = [ + 1, 0, 0, 1, 0.6, 0, + 0, 1, 0, 0.6, 1, 0, + 0, 0, 1, 0, 0.6, 1 + ]; - } + const geometry = new BufferGeometry(); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - /** - * 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 + const material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } ); - this.theta = theta; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis + super( geometry, material ); - this.y = y; // height above the x-z plane + this.type = 'AxesHelper'; - return this; } - set(radius, theta, y) { - this.radius = radius; - this.theta = theta; - this.y = y; - return this; - } + setColors( xAxisColor, yAxisColor, zAxisColor ) { - copy(other) { - this.radius = other.radius; - this.theta = other.theta; - this.y = other.y; - return this; - } + const color = new Color(); + const array = this.geometry.attributes.color.array; - setFromVector3(v) { - return this.setFromCartesianCoords(v.x, v.y, v.z); - } + color.set( xAxisColor ); + color.toArray( array, 0 ); + color.toArray( array, 3 ); - setFromCartesianCoords(x, y, z) { - this.radius = Math.sqrt(x * x + z * z); - this.theta = Math.atan2(x, z); - this.y = y; - return this; - } + color.set( yAxisColor ); + color.toArray( array, 6 ); + color.toArray( array, 9 ); - clone() { - return new this.constructor().copy(this); - } + color.set( zAxisColor ); + color.toArray( array, 12 ); + color.toArray( array, 15 ); - } + this.geometry.attributes.color.needsUpdate = true; - const _vector$4 = /*@__PURE__*/new Vector2(); + return this; - 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; + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + } - setFromPoints(points) { - this.makeEmpty(); + } - for (let i = 0, il = points.length; i < il; i++) { - this.expandByPoint(points[i]); - } + class ShapePath { - return this; - } + constructor() { - setFromCenterAndSize(center, size) { - const halfSize = _vector$4.copy(size).multiplyScalar(0.5); + this.type = 'ShapePath'; - this.min.copy(center).sub(halfSize); - this.max.copy(center).add(halfSize); - return this; - } + this.color = new Color(); - clone() { - return new this.constructor().copy(this); - } + this.subPaths = []; + this.currentPath = null; - 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; + moveTo( x, y ) { + + this.currentPath = new Path(); + this.subPaths.push( this.currentPath ); + this.currentPath.moveTo( x, y ); + 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); - } + lineTo( x, y ) { - getSize(target) { - return this.isEmpty() ? target.set(0, 0) : target.subVectors(this.max, this.min); - } + this.currentPath.lineTo( x, y ); - 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); + quadraticCurveTo( aCPx, aCPy, aX, aY ) { + + this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY ); + 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; - } + bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { - 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)); - } + this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ); - 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; - } + return this; - 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); + splineThru( pts ) { - return clampedPoint.sub(point).length(); - } + this.currentPath.splineThru( pts ); - 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; - } + toShapes( isCCW ) { - equals(box) { - return box.min.equals(this.min) && box.max.equals(this.max); - } + function toShapesNoHoles( inSubpaths ) { - } + const shapes = []; - const _startP = /*@__PURE__*/new Vector3(); + for ( let i = 0, l = inSubpaths.length; i < l; i ++ ) { - const _startEnd = /*@__PURE__*/new Vector3(); + const tmpPath = inSubpaths[ i ]; - class Line3 { - constructor(start = new Vector3(), end = new Vector3()) { - this.start = start; - this.end = end; - } + const tmpShape = new Shape(); + tmpShape.curves = tmpPath.curves; - set(start, end) { - this.start.copy(start); - this.end.copy(end); - return this; - } + shapes.push( tmpShape ); - 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); - } + return shapes; - delta(target) { - return target.subVectors(this.end, this.start); - } + } - distanceSq() { - return this.start.distanceToSquared(this.end); - } + function isPointInsidePolygon( inPt, inPolygon ) { - distance() { - return this.start.distanceTo(this.end); - } + const polyLen = inPolygon.length; - at(t, target) { - return this.delta(target).multiplyScalar(t).add(this.start); - } + // 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 ++ ) { - closestPointToPointParameter(point, clampToLine) { - _startP.subVectors(point, this.start); + let edgeLowPt = inPolygon[ p ]; + let edgeHighPt = inPolygon[ q ]; - _startEnd.subVectors(this.end, this.start); + let edgeDx = edgeHighPt.x - edgeLowPt.x; + let edgeDy = edgeHighPt.y - edgeLowPt.y; - const startEnd2 = _startEnd.dot(_startEnd); + if ( Math.abs( edgeDy ) > Number.EPSILON ) { - const startEnd_startP = _startEnd.dot(_startP); + // not parallel + if ( edgeDy < 0 ) { - let t = startEnd_startP / startEnd2; + edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx; + edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy; - if (clampToLine) { - t = clamp(t, 0, 1); - } + } - return t; - } + if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue; - closestPointToPoint(point, clampToLine, target) { - const t = this.closestPointToPointParameter(point, clampToLine); - return this.delta(target).multiplyScalar(t).add(this.start); - } + if ( inPt.y === edgeLowPt.y ) { - applyMatrix4(matrix) { - this.start.applyMatrix4(matrix); - this.end.applyMatrix4(matrix); - return this; - } + if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ? + // continue; // no intersection or edgeLowPt => doesn't count !!! - equals(line) { - return line.start.equals(this.start) && line.end.equals(this.end); - } + } else { - clone() { - return new this.constructor().copy(this); - } + 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 - } + } - const _vector$3 = /*@__PURE__*/new Vector3(); + } else { - class SpotLightHelper extends Object3D { - constructor(light, color) { - super(); - this.light = light; - this.light.updateMatrixWorld(); - this.matrix = light.matrixWorld; - this.matrixAutoUpdate = false; - this.color = color; - 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]; + // 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; - 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, - toneMapped: false - }); - this.cone = new LineSegments(geometry, material); - this.add(this.cone); - this.update(); - } + } - dispose() { - this.cone.geometry.dispose(); - this.cone.material.dispose(); - } + return inside; - update() { - this.light.updateMatrixWorld(); - 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); + const isClockWise = ShapeUtils.isClockWise; - this.cone.lookAt(_vector$3); + const subPaths = this.subPaths; + if ( subPaths.length === 0 ) return []; - if (this.color !== undefined) { - this.cone.material.color.set(this.color); - } else { - this.cone.material.color.copy(this.light.color); - } - } + let solid, tmpPath, tmpShape; + const shapes = []; - } + if ( subPaths.length === 1 ) { + + tmpPath = subPaths[ 0 ]; + tmpShape = new Shape(); + tmpShape.curves = tmpPath.curves; + shapes.push( tmpShape ); + return shapes; - const _vector$2 = /*@__PURE__*/new Vector3(); + } - const _boneMatrix = /*@__PURE__*/new Matrix4(); + let holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() ); + holesFirst = isCCW ? ! holesFirst : holesFirst; - const _matrixWorldInv = /*@__PURE__*/new Matrix4(); + // console.log("Holes first", holesFirst); - class SkeletonHelper extends LineSegments { - constructor(object) { - const bones = getBoneList(object); - const geometry = new BufferGeometry(); - const vertices = []; - const colors = []; - const color1 = new Color(0, 0, 1); - const color2 = new Color(0, 1, 0); + const betterShapeHoles = []; + const newShapes = []; + let newShapeHoles = []; + let mainIdx = 0; + let tmpPoints; - for (let i = 0; i < bones.length; i++) { - const bone = bones[i]; + newShapes[ mainIdx ] = undefined; + newShapeHoles[ mainIdx ] = []; - if (bone.parent && bone.parent.isBone) { - vertices.push(0, 0, 0); - vertices.push(0, 0, 0); - colors.push(color1.r, color1.g, color1.b); - colors.push(color2.r, color2.g, color2.b); - } - } + for ( let i = 0, l = subPaths.length; i < l; i ++ ) { - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); - const material = new LineBasicMaterial({ - vertexColors: true, - depthTest: false, - depthWrite: false, - toneMapped: false, - transparent: true - }); - super(geometry, material); - this.isSkeletonHelper = true; - this.type = 'SkeletonHelper'; - this.root = object; - this.bones = bones; - this.matrix = object.matrixWorld; - this.matrixAutoUpdate = false; - } + tmpPath = subPaths[ i ]; + tmpPoints = tmpPath.getPoints(); + solid = isClockWise( tmpPoints ); + solid = isCCW ? ! solid : solid; - updateMatrixWorld(force) { - const bones = this.bones; - const geometry = this.geometry; - const position = geometry.getAttribute('position'); + if ( solid ) { - _matrixWorldInv.copy(this.root.matrixWorld).invert(); + if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++; - for (let i = 0, j = 0; i < bones.length; i++) { - const bone = bones[i]; + newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints }; + newShapes[ mainIdx ].s.curves = tmpPath.curves; - if (bone.parent && bone.parent.isBone) { - _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.matrixWorld); + if ( holesFirst ) mainIdx ++; + newShapeHoles[ mainIdx ] = []; - _vector$2.setFromMatrixPosition(_boneMatrix); + //console.log('cw', i); - position.setXYZ(j, _vector$2.x, _vector$2.y, _vector$2.z); + } else { - _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.parent.matrixWorld); + newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } ); - _vector$2.setFromMatrixPosition(_boneMatrix); + //console.log('ccw', i); - position.setXYZ(j + 1, _vector$2.x, _vector$2.y, _vector$2.z); - j += 2; } + } - geometry.getAttribute('position').needsUpdate = true; - super.updateMatrixWorld(force); - } + // only Holes? -> probably all Shapes with wrong orientation + if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths ); - } - function getBoneList(object) { - const boneList = []; + if ( newShapes.length > 1 ) { - if (object.isBone === true) { - boneList.push(object); - } + let ambiguous = false; + let toChange = 0; - for (let i = 0; i < object.children.length; i++) { - boneList.push.apply(boneList, getBoneList(object.children[i])); - } + for ( let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { - return boneList; - } + betterShapeHoles[ sIdx ] = []; - class PointLightHelper extends Mesh { - constructor(light, sphereSize, color) { - const geometry = new SphereGeometry(sphereSize, 4, 2); - const material = new MeshBasicMaterial({ - wireframe: true, - fog: false, - toneMapped: false - }); - 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 ); - const distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } ); - this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial ); - this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial ); - const d = light.distance; - if ( d === 0.0 ) { - this.lightDistance.visible = false; - } else { - this.lightDistance.scale.set( d, d, d ); - } - this.add( this.lightDistance ); - */ - } + } - dispose() { - this.geometry.dispose(); - this.material.dispose(); - } + for ( let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { - update() { - if (this.color !== undefined) { - this.material.color.set(this.color); - } else { - this.material.color.copy(this.light.color); - } - /* - const d = this.light.distance; - if ( d === 0.0 ) { - this.lightDistance.visible = false; - } else { - this.lightDistance.visible = true; - this.lightDistance.scale.set( d, d, d ); - } - */ + const sho = newShapeHoles[ sIdx ]; - } + for ( let hIdx = 0; hIdx < sho.length; hIdx ++ ) { - } + const ho = sho[ hIdx ]; + let hole_unassigned = true; - const _vector$1 = /*@__PURE__*/new Vector3(); + for ( let s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) { - const _color1 = /*@__PURE__*/new Color(); + if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) { - const _color2 = /*@__PURE__*/new Color(); + if ( sIdx !== s2Idx ) toChange ++; - 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; - const geometry = new OctahedronGeometry(size); - geometry.rotateY(Math.PI * 0.5); - this.material = new MeshBasicMaterial({ - wireframe: true, - fog: false, - toneMapped: false - }); - if (this.color === undefined) this.material.vertexColors = true; - const position = geometry.getAttribute('position'); - const colors = new Float32Array(position.count * 3); - geometry.setAttribute('color', new BufferAttribute(colors, 3)); - this.add(new Mesh(geometry, this.material)); - this.update(); - } + if ( hole_unassigned ) { - dispose() { - this.children[0].geometry.dispose(); - this.children[0].material.dispose(); - } + hole_unassigned = false; + betterShapeHoles[ s2Idx ].push( ho ); - update() { - const mesh = this.children[0]; + } else { - if (this.color !== undefined) { - this.material.color.set(this.color); - } else { - const colors = mesh.geometry.getAttribute('color'); + ambiguous = true; - _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; - } + if ( hole_unassigned ) { - mesh.lookAt(_vector$1.setFromMatrixPosition(this.light.matrixWorld).negate()); - } + betterShapeHoles[ sIdx ].push( ho ); - } + } - class GridHelper extends LineSegments { - constructor(size = 10, divisions = 10, color1 = 0x444444, color2 = 0x888888) { - color1 = new Color(color1); - color2 = new Color(color2); - const center = divisions / 2; - const step = size / divisions; - const halfSize = size / 2; - const vertices = [], - 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); - const color = i === center ? color1 : color2; - color.toArray(colors, j); - j += 3; - color.toArray(colors, j); - j += 3; - color.toArray(colors, j); - j += 3; - color.toArray(colors, j); - j += 3; - } + } - const geometry = new BufferGeometry(); - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); - const material = new LineBasicMaterial({ - vertexColors: true, - toneMapped: false - }); - super(geometry, material); - this.type = 'GridHelper'; - } + if ( toChange > 0 && ambiguous === false ) { - } + newShapeHoles = betterShapeHoles; - class PolarGridHelper extends LineSegments { - constructor(radius = 10, radials = 16, circles = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888) { - color1 = new Color(color1); - color2 = new Color(color2); - const vertices = []; - const colors = []; // create the radials + } - 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 + } + + let tmpHoles; + for ( let i = 0, il = newShapes.length; i < il; i ++ ) { - for (let i = 0; i <= circles; i++) { - const color = i & 1 ? color1 : color2; - const r = radius - radius / circles * i; + tmpShape = newShapes[ i ].s; + shapes.push( tmpShape ); + tmpHoles = newShapeHoles[ 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 + for ( let j = 0, jl = tmpHoles.length; j < jl; j ++ ) { + + tmpShape.holes.push( tmpHoles[ j ].h ); - v = (j + 1) / divisions * (Math.PI * 2); - x = Math.sin(v) * r; - z = Math.cos(v) * r; - vertices.push(x, 0, z); - colors.push(color.r, color.g, color.b); } + } - const geometry = new BufferGeometry(); - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); - const material = new LineBasicMaterial({ - vertexColors: true, - toneMapped: false - }); - super(geometry, material); - this.type = 'PolarGridHelper'; + //console.log("shape", shapes); + + return shapes; + } } - const _v1 = /*@__PURE__*/new Vector3(); - - const _v2 = /*@__PURE__*/new Vector3(); + // Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf - const _v3 = /*@__PURE__*/new Vector3(); + const _tables = /*@__PURE__*/ _generateTables(); - 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; - 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)); - const material = new LineBasicMaterial({ - fog: false, - toneMapped: false - }); - this.lightPlane = new Line(geometry, material); - this.add(this.lightPlane); - geometry = new BufferGeometry(); - geometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 0, 1], 3)); - this.targetLine = new Line(geometry, material); - this.add(this.targetLine); - this.update(); - } + function _generateTables() { - dispose() { - this.lightPlane.geometry.dispose(); - this.lightPlane.material.dispose(); - this.targetLine.geometry.dispose(); - this.targetLine.material.dispose(); - } + // float32 to float16 helpers - update() { - _v1.setFromMatrixPosition(this.light.matrixWorld); + const buffer = new ArrayBuffer( 4 ); + const floatView = new Float32Array( buffer ); + const uint32View = new Uint32Array( buffer ); - _v2.setFromMatrixPosition(this.light.target.matrixWorld); + const baseTable = new Uint32Array( 512 ); + const shiftTable = new Uint32Array( 512 ); - _v3.subVectors(_v2, _v1); + for ( let i = 0; i < 256; ++ i ) { - this.lightPlane.lookAt(_v2); + const e = i - 127; - if (this.color !== undefined) { - this.lightPlane.material.color.set(this.color); - this.targetLine.material.color.set(this.color); - } else { - this.lightPlane.material.color.copy(this.light.color); - this.targetLine.material.color.copy(this.light.color); - } + // very small number (0, -0) - this.targetLine.lookAt(_v2); - this.targetLine.scale.z = _v3.length(); - } + if ( e < - 27 ) { - } + baseTable[ i ] = 0x0000; + baseTable[ i | 0x100 ] = 0x8000; + shiftTable[ i ] = 24; + shiftTable[ i | 0x100 ] = 24; - const _vector = /*@__PURE__*/new Vector3(); + // small number (denorm) - const _camera = /*@__PURE__*/new Camera(); - /** - * - shows frustum, line of sight and up of the camera - * - suitable for fast updates - * - based on frustum visualization in lightgl.js shadowmap example - * https://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html - */ + } 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; - class CameraHelper extends LineSegments { - constructor(camera) { - const geometry = new BufferGeometry(); - const material = new LineBasicMaterial({ - color: 0xffffff, - vertexColors: true, - toneMapped: false - }); - const vertices = []; - const colors = []; - const pointMap = {}; // colors + // normal number - const colorFrustum = new Color(0xffaa00); - const colorCone = new Color(0xff0000); - const colorUp = new Color(0x00aaff); - const colorTarget = new Color(0xffffff); - const colorCross = new Color(0x333333); // near + } else if ( e <= 15 ) { - addLine('n1', 'n2', colorFrustum); - addLine('n2', 'n4', colorFrustum); - addLine('n4', 'n3', colorFrustum); - addLine('n3', 'n1', colorFrustum); // far + baseTable[ i ] = ( e + 15 ) << 10; + baseTable[ i | 0x100 ] = ( ( e + 15 ) << 10 ) | 0x8000; + shiftTable[ i ] = 13; + shiftTable[ i | 0x100 ] = 13; - addLine('f1', 'f2', colorFrustum); - addLine('f2', 'f4', colorFrustum); - addLine('f4', 'f3', colorFrustum); - addLine('f3', 'f1', colorFrustum); // sides + // large number (Infinity, -Infinity) - addLine('n1', 'f1', colorFrustum); - addLine('n2', 'f2', colorFrustum); - addLine('n3', 'f3', colorFrustum); - addLine('n4', 'f4', colorFrustum); // cone + } else if ( e < 128 ) { - addLine('p', 'n1', colorCone); - addLine('p', 'n2', colorCone); - addLine('p', 'n3', colorCone); - addLine('p', 'n4', colorCone); // up + baseTable[ i ] = 0x7c00; + baseTable[ i | 0x100 ] = 0xfc00; + shiftTable[ i ] = 24; + shiftTable[ i | 0x100 ] = 24; - addLine('u1', 'u2', colorUp); - addLine('u2', 'u3', colorUp); - addLine('u3', 'u1', colorUp); // target + // stay (NaN, Infinity, -Infinity) - addLine('c', 't', colorTarget); - addLine('p', 'c', colorCross); // cross + } else { - addLine('cn1', 'cn2', colorCross); - addLine('cn3', 'cn4', colorCross); - addLine('cf1', 'cf2', colorCross); - addLine('cf3', 'cf4', colorCross); + baseTable[ i ] = 0x7c00; + baseTable[ i | 0x100 ] = 0xfc00; + shiftTable[ i ] = 13; + shiftTable[ i | 0x100 ] = 13; - function addLine(a, b, color) { - addPoint(a, color); - addPoint(b, color); } - function addPoint(id, color) { - vertices.push(0, 0, 0); - colors.push(color.r, color.g, color.b); + } + + // float16 to float32 helpers - if (pointMap[id] === undefined) { - pointMap[id] = []; - } + 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 + while ( ( m & 0x00800000 ) === 0 ) { + + m <<= 1; + e -= 0x00800000; // decrement exponent - pointMap[id].push(vertices.length / 3 - 1); } - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); - super(geometry, material); - this.type = 'CameraHelper'; - this.camera = camera; - if (this.camera.updateProjectionMatrix) this.camera.updateProjectionMatrix(); - this.matrix = camera.matrixWorld; - this.matrixAutoUpdate = false; - this.pointMap = pointMap; - this.update(); - } + m &= ~ 0x00800000; // clear leading 1 bit + e += 0x38800000; // adjust bias - update() { - const geometry = this.geometry; - const pointMap = this.pointMap; - const w = 1, - h = 1; // we need just camera projection matrix inverse - // world matrix must be identity + mantissaTable[ i ] = m | e; - _camera.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse); // center / target + } + for ( let i = 1024; i < 2048; ++ i ) { - setPoint('c', pointMap, geometry, _camera, 0, 0, -1); - setPoint('t', pointMap, geometry, _camera, 0, 0, 1); // near + mantissaTable[ i ] = 0x38000000 + ( ( i - 1024 ) << 13 ); - setPoint('n1', pointMap, geometry, _camera, -w, -h, -1); - setPoint('n2', pointMap, geometry, _camera, w, -h, -1); - setPoint('n3', pointMap, geometry, _camera, -w, h, -1); - setPoint('n4', pointMap, geometry, _camera, w, h, -1); // far + } - setPoint('f1', pointMap, geometry, _camera, -w, -h, 1); - setPoint('f2', pointMap, geometry, _camera, w, -h, 1); - setPoint('f3', pointMap, geometry, _camera, -w, h, 1); - setPoint('f4', pointMap, geometry, _camera, w, h, 1); // up + for ( let i = 1; i < 31; ++ i ) { - 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 + exponentTable[ i ] = i << 23; - setPoint('cf1', pointMap, geometry, _camera, -w, 0, 1); - setPoint('cf2', pointMap, geometry, _camera, w, 0, 1); - setPoint('cf3', pointMap, geometry, _camera, 0, -h, 1); - setPoint('cf4', pointMap, geometry, _camera, 0, h, 1); - setPoint('cn1', pointMap, geometry, _camera, -w, 0, -1); - setPoint('cn2', pointMap, geometry, _camera, w, 0, -1); - setPoint('cn3', pointMap, geometry, _camera, 0, -h, -1); - setPoint('cn4', pointMap, geometry, _camera, 0, h, -1); - geometry.getAttribute('position').needsUpdate = true; } - dispose() { - this.geometry.dispose(); - this.material.dispose(); + exponentTable[ 31 ] = 0x47800000; + exponentTable[ 32 ] = 0x80000000; + + for ( let i = 33; i < 63; ++ i ) { + + exponentTable[ i ] = 0x80000000 + ( ( i - 32 ) << 23 ); + } - } + exponentTable[ 63 ] = 0xc7800000; - function setPoint(point, pointMap, geometry, camera, x, y, z) { - _vector.set(x, y, z).unproject(camera); + for ( let i = 1; i < 64; ++ i ) { - const points = pointMap[point]; + if ( i !== 32 ) { - if (points !== undefined) { - const position = geometry.getAttribute('position'); + offsetTable[ i ] = 1024; - for (let i = 0, l = points.length; i < l; i++) { - position.setXYZ(points[i], _vector.x, _vector.y, _vector.z); } + } + + return { + floatView: floatView, + uint32View: uint32View, + baseTable: baseTable, + shiftTable: shiftTable, + mantissaTable: mantissaTable, + exponentTable: exponentTable, + offsetTable: offsetTable + }; + } - const _box = /*@__PURE__*/new Box3(); + // float32 to float16 - 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]); - const positions = new Float32Array(8 * 3); - const geometry = new BufferGeometry(); - geometry.setIndex(new BufferAttribute(indices, 1)); - geometry.setAttribute('position', new BufferAttribute(positions, 3)); - super(geometry, new LineBasicMaterial({ - color: color, - toneMapped: false - })); - this.object = object; - this.type = 'BoxHelper'; - this.matrixAutoUpdate = false; - this.update(); - } + function toHalfFloat( val ) { - update(object) { - if (object !== undefined) { - console.warn('THREE.BoxHelper: .update() has no longer arguments.'); - } + if ( Math.abs( val ) > 65504 ) console.warn( 'THREE.DataUtils.toHalfFloat(): Value out of range.' ); - if (this.object !== undefined) { - _box.setFromObject(this.object); - } + val = clamp( val, - 65504, 65504 ); - if (_box.isEmpty()) return; - const min = _box.min; - const max = _box.max; - /* - 5____4 - 1/___0/| - | 6__|_7 - 2/___3/ - 0: max.x, max.y, max.z - 1: min.x, max.y, max.z - 2: min.x, min.y, max.z - 3: max.x, min.y, max.z - 4: max.x, max.y, min.z - 5: min.x, max.y, min.z - 6: min.x, min.y, min.z - 7: max.x, min.y, min.z - */ + _tables.floatView[ 0 ] = val; + const f = _tables.uint32View[ 0 ]; + const e = ( f >> 23 ) & 0x1ff; + return _tables.baseTable[ e ] + ( ( f & 0x007fffff ) >> _tables.shiftTable[ e ] ); - const position = this.geometry.attributes.position; - const array = position.array; - array[0] = max.x; - array[1] = max.y; - array[2] = max.z; - array[3] = min.x; - array[4] = max.y; - array[5] = max.z; - array[6] = min.x; - array[7] = min.y; - array[8] = max.z; - array[9] = max.x; - array[10] = min.y; - array[11] = max.z; - array[12] = max.x; - array[13] = max.y; - array[14] = min.z; - array[15] = min.x; - array[16] = max.y; - array[17] = min.z; - array[18] = min.x; - array[19] = min.y; - array[20] = min.z; - array[21] = max.x; - array[22] = min.y; - array[23] = min.z; - position.needsUpdate = true; - this.geometry.computeBoundingSphere(); - } + } - setFromObject(object) { - this.object = object; - this.update(); - return this; - } + // float16 to float32 - copy(source, recursive) { - super.copy(source, recursive); - this.object = source.object; - return this; - } + function fromHalfFloat( val ) { + + const m = val >> 10; + _tables.uint32View[ 0 ] = _tables.mantissaTable[ _tables.offsetTable[ m ] + ( val & 0x3ff ) ] + _tables.exponentTable[ m ]; + return _tables.floatView[ 0 ]; } - class Box3Helper extends LineSegments { - constructor(box, 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]); - const positions = [1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1]; - const geometry = new BufferGeometry(); - geometry.setIndex(new BufferAttribute(indices, 1)); - geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); - super(geometry, new LineBasicMaterial({ - color: color, - toneMapped: false - })); - this.box = box; - this.type = 'Box3Helper'; - this.geometry.computeBoundingSphere(); - } + var DataUtils = /*#__PURE__*/Object.freeze({ + __proto__: null, + fromHalfFloat: fromHalfFloat, + toHalfFloat: toHalfFloat + }); - updateMatrixWorld(force) { - const box = this.box; - if (box.isEmpty()) return; - box.getCenter(this.position); - box.getSize(this.scale); - this.scale.multiplyScalar(0.5); - super.updateMatrixWorld(force); - } + // r144 - } + class BoxBufferGeometry extends BoxGeometry { - class PlaneHelper extends Line { - constructor(plane, size = 1, hex = 0xffff00) { - const color = hex; - const positions = [1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0]; - const geometry = new BufferGeometry(); - geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); - geometry.computeBoundingSphere(); - super(geometry, new LineBasicMaterial({ - color: color, - toneMapped: false - })); - this.type = 'PlaneHelper'; - this.plane = plane; - this.size = size; - const positions2 = [1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1]; - const geometry2 = new BufferGeometry(); - geometry2.setAttribute('position', new Float32BufferAttribute(positions2, 3)); - geometry2.computeBoundingSphere(); - this.add(new Mesh(geometry2, new MeshBasicMaterial({ - color: color, - opacity: 0.2, - transparent: true, - depthWrite: false, - toneMapped: false - }))); - } + constructor( width, height, depth, widthSegments, heightSegments, depthSegments ) { - updateMatrixWorld(force) { - let scale = -this.plane.constant; - if (Math.abs(scale) < 1e-8) scale = 1e-8; // sign does not matter + console.warn( 'THREE.BoxBufferGeometry has been renamed to THREE.BoxGeometry.' ); + super( width, height, depth, widthSegments, heightSegments, depthSegments ); - this.scale.set(0.5 * this.size, 0.5 * this.size, scale); - this.children[0].material.side = scale < 0 ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here - this.lookAt(this.plane.normal); - super.updateMatrixWorld(force); } } - const _axis = /*@__PURE__*/new Vector3(); + // r144 - let _lineGeometry, _coneGeometry; + class CapsuleBufferGeometry extends CapsuleGeometry { - 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'; + constructor( radius, length, capSegments, radialSegments ) { - if (_lineGeometry === undefined) { - _lineGeometry = new BufferGeometry(); + console.warn( 'THREE.CapsuleBufferGeometry has been renamed to THREE.CapsuleGeometry.' ); + super( radius, length, capSegments, radialSegments ); - _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); - } + // r144 - this.position.copy(origin); - this.line = new Line(_lineGeometry, new LineBasicMaterial({ - color: color, - toneMapped: false - })); - this.line.matrixAutoUpdate = false; - this.add(this.line); - this.cone = new Mesh(_coneGeometry, new MeshBasicMaterial({ - color: color, - toneMapped: false - })); - this.cone.matrixAutoUpdate = false; - this.add(this.cone); - this.setDirection(dir); - this.setLength(length, headLength, headWidth); - } + class CircleBufferGeometry extends CircleGeometry { - 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(); + constructor( radius, segments, thetaStart, thetaLength ) { + + console.warn( 'THREE.CircleBufferGeometry has been renamed to THREE.CircleGeometry.' ); + super( radius, segments, thetaStart, thetaLength ); - 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(); - } + // r144 - setColor(color) { - this.line.material.color.set(color); - this.cone.material.color.set(color); - } + 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 ); - copy(source) { - super.copy(source, false); - this.line.copy(source.line); - this.cone.copy(source.cone); - return this; } } - class AxesHelper extends LineSegments { - constructor(size = 1) { - const vertices = [0, 0, 0, size, 0, 0, 0, 0, 0, 0, size, 0, 0, 0, 0, 0, 0, size]; - const colors = [1, 0, 0, 1, 0.6, 0, 0, 1, 0, 0.6, 1, 0, 0, 0, 1, 0, 0.6, 1]; - const geometry = new BufferGeometry(); - geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); - const material = new LineBasicMaterial({ - vertexColors: true, - toneMapped: false - }); - super(geometry, material); - this.type = 'AxesHelper'; - } + // r144 - setColors(xAxisColor, yAxisColor, zAxisColor) { - const color = new Color(); - const array = this.geometry.attributes.color.array; - color.set(xAxisColor); - color.toArray(array, 0); - color.toArray(array, 3); - color.set(yAxisColor); - color.toArray(array, 6); - color.toArray(array, 9); - color.set(zAxisColor); - color.toArray(array, 12); - color.toArray(array, 15); - this.geometry.attributes.color.needsUpdate = true; - return this; - } + 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 ); - dispose() { - this.geometry.dispose(); - this.material.dispose(); } } - class ShapePath { - constructor() { - this.type = 'ShapePath'; - this.color = new Color(); - this.subPaths = []; - this.currentPath = null; - } + // r144 - moveTo(x, y) { - this.currentPath = new Path(); - this.subPaths.push(this.currentPath); - this.currentPath.moveTo(x, y); - return this; - } + class DodecahedronBufferGeometry extends DodecahedronGeometry { - lineTo(x, y) { - this.currentPath.lineTo(x, y); - return this; - } + constructor( radius, detail ) { - quadraticCurveTo(aCPx, aCPy, aX, aY) { - this.currentPath.quadraticCurveTo(aCPx, aCPy, aX, aY); - return this; - } + console.warn( 'THREE.DodecahedronBufferGeometry has been renamed to THREE.DodecahedronGeometry.' ); + super( radius, detail ); - 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) { - function toShapesNoHoles(inSubpaths) { - const shapes = []; + // r144 - 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); - } + class ExtrudeBufferGeometry extends ExtrudeGeometry { - return shapes; - } + constructor( shapes, options ) { - function isPointInsidePolygon(inPt, inPolygon) { - 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 + console.warn( 'THREE.ExtrudeBufferGeometry has been renamed to THREE.ExtrudeGeometry.' ); + super( shapes, options ); - 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) { - edgeLowPt = inPolygon[q]; - edgeDx = -edgeDx; - edgeHighPt = inPolygon[p]; - edgeDy = -edgeDy; - } + // r144 - if (inPt.y < edgeLowPt.y || inPt.y > edgeHighPt.y) continue; + class IcosahedronBufferGeometry extends IcosahedronGeometry { - 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 ? + constructor( radius, detail ) { - if (perpEdge < 0) continue; - inside = !inside; // true intersection left of inPt - } - } else { - // parallel or collinear - if (inPt.y !== edgeLowPt.y) continue; // parallel - // edge lies on the same horizontal line as inPt + console.warn( 'THREE.IcosahedronBufferGeometry has been renamed to THREE.IcosahedronGeometry.' ); + super( radius, detail ); - if (edgeHighPt.x <= inPt.x && inPt.x <= edgeLowPt.x || edgeLowPt.x <= inPt.x && inPt.x <= edgeHighPt.x) return true; // inPt: Point on contour ! - // continue; - } - } + } - return inside; - } + } - 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 = []; + // r144 - if (subPaths.length === 1) { - tmpPath = subPaths[0]; - tmpShape = new Shape(); - tmpShape.curves = tmpPath.curves; - shapes.push(tmpShape); - return shapes; - } + class LatheBufferGeometry extends LatheGeometry { - let holesFirst = !isClockWise(subPaths[0].getPoints()); - holesFirst = isCCW ? !holesFirst : holesFirst; // console.log("Holes first", holesFirst); + constructor( points, segments, phiStart, phiLength ) { - const betterShapeHoles = []; - const newShapes = []; - let newShapeHoles = []; - let mainIdx = 0; - let tmpPoints; - newShapes[mainIdx] = undefined; - newShapeHoles[mainIdx] = []; + console.warn( 'THREE.LatheBufferGeometry has been renamed to THREE.LatheGeometry.' ); + super( points, segments, phiStart, phiLength ); - 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] = { - s: new Shape(), - p: tmpPoints - }; - newShapes[mainIdx].s.curves = tmpPath.curves; - if (holesFirst) mainIdx++; - newShapeHoles[mainIdx] = []; //console.log('cw', i); - } else { - newShapeHoles[mainIdx].push({ - h: tmpPath, - p: tmpPoints[0] - }); //console.log('ccw', i); - } - } // only Holes? -> probably all Shapes with wrong orientation + } + } - if (!newShapes[0]) return toShapesNoHoles(subPaths); + // r144 - if (newShapes.length > 1) { - let ambiguous = false; - let toChange = 0; + class OctahedronBufferGeometry extends OctahedronGeometry { - for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { - betterShapeHoles[sIdx] = []; - } + constructor( radius, detail ) { - for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { - const sho = newShapeHoles[sIdx]; + console.warn( 'THREE.OctahedronBufferGeometry has been renamed to THREE.OctahedronGeometry.' ); + super( radius, detail ); - 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); - } else { - ambiguous = true; - } - } - } + // r144 - if (hole_unassigned) { - betterShapeHoles[sIdx].push(ho); - } - } - } + class PlaneBufferGeometry extends PlaneGeometry { - if (toChange > 0 && ambiguous === false) { - newShapeHoles = betterShapeHoles; - } - } + constructor( width, height, widthSegments, heightSegments ) { - let tmpHoles; + console.warn( 'THREE.PlaneBufferGeometry has been renamed to THREE.PlaneGeometry.' ); + super( width, height, widthSegments, heightSegments ); - 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); + } + // 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 ); - return shapes; } } - class DataUtils { - // float32 to float16 - static toHalfFloat(val) { - if (Math.abs(val) > 65504) console.warn('THREE.DataUtils.toHalfFloat(): Value out of range.'); - val = clamp(val, -65504, 65504); - _floatView[0] = val; - const f = _uint32View[0]; - const e = f >> 23 & 0x1ff; - return _baseTable[e] + ((f & 0x007fffff) >> _shiftTable[e]); - } // float16 to float32 - + // r144 - static fromHalfFloat(val) { - const m = val >> 10; - _uint32View[0] = _mantissaTable[_offsetTable[m] + (val & 0x3ff)] + _exponentTable[m]; - return _floatView[0]; - } + class RingBufferGeometry extends RingGeometry { - } // float32 to float16 helpers + constructor( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { + console.warn( 'THREE.RingBufferGeometry has been renamed to THREE.RingGeometry.' ); + super( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ); - const _buffer = new ArrayBuffer(4); + } - const _floatView = new Float32Array(_buffer); + } - const _uint32View = new Uint32Array(_buffer); + // r144 - const _baseTable = new Uint32Array(512); + class ShapeBufferGeometry extends ShapeGeometry { - const _shiftTable = new Uint32Array(512); + constructor( shapes, curveSegments ) { - for (let i = 0; i < 256; ++i) { - const e = i - 127; // very small number (0, -0) + console.warn( 'THREE.ShapeBufferGeometry has been renamed to THREE.ShapeGeometry.' ); + super( shapes, curveSegments ); - if (e < -27) { - _baseTable[i] = 0x0000; - _baseTable[i | 0x100] = 0x8000; - _shiftTable[i] = 24; - _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 - } 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) - } else if (e < 128) { - _baseTable[i] = 0x7c00; - _baseTable[i | 0x100] = 0xfc00; - _shiftTable[i] = 24; - _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 + } - const _mantissaTable = new Uint32Array(2048); - - const _exponentTable = new Uint32Array(64); + // r144 - const _offsetTable = new Uint32Array(64); + class SphereBufferGeometry extends SphereGeometry { - for (let i = 1; i < 1024; ++i) { - let m = i << 13; // zero pad mantissa bits + constructor( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { - let e = 0; // zero exponent - // normalized + console.warn( 'THREE.SphereBufferGeometry has been renamed to THREE.SphereGeometry.' ); + super( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ); - while ((m & 0x00800000) === 0) { - m <<= 1; - e -= 0x00800000; // decrement exponent } - m &= ~0x00800000; // clear leading 1 bit + } - e += 0x38800000; // adjust bias + // r144 - _mantissaTable[i] = m | e; - } + class TetrahedronBufferGeometry extends TetrahedronGeometry { - for (let i = 1024; i < 2048; ++i) { - _mantissaTable[i] = 0x38000000 + (i - 1024 << 13); - } + constructor( radius, detail ) { - for (let i = 1; i < 31; ++i) { - _exponentTable[i] = i << 23; - } + console.warn( 'THREE.TetrahedronBufferGeometry has been renamed to THREE.TetrahedronGeometry.' ); + super( radius, detail ); - _exponentTable[31] = 0x47800000; - _exponentTable[32] = 0x80000000; + } - for (let i = 33; i < 63; ++i) { - _exponentTable[i] = 0x80000000 + (i - 32 << 23); } - _exponentTable[63] = 0xc7800000; + // r144 - for (let i = 1; i < 64; ++i) { - if (i !== 32) { - _offsetTable[i] = 1024; - } - } + class TorusBufferGeometry extends TorusGeometry { - class ParametricGeometry extends BufferGeometry { - constructor() { - console.error('THREE.ParametricGeometry has been moved to /examples/jsm/geometries/ParametricGeometry.js'); - super(); - } + constructor( radius, tube, radialSegments, tubularSegments, arc ) { - } // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 + console.warn( 'THREE.TorusBufferGeometry has been renamed to THREE.TorusGeometry.' ); + super( radius, tube, radialSegments, tubularSegments, arc ); - class TextGeometry extends BufferGeometry { - constructor() { - console.error('THREE.TextGeometry has been moved to /examples/jsm/geometries/TextGeometry.js'); - super(); } - } // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 + } + + // r144 - function FontLoader() { - console.error('THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js'); - } // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 + class TorusKnotBufferGeometry extends TorusKnotGeometry { - function Font() { - console.error('THREE.Font has been moved to /examples/jsm/loaders/FontLoader.js'); - } // r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0 + constructor( radius, tube, tubularSegments, radialSegments, p, q ) { - function ImmediateRenderObject() { - console.error('THREE.ImmediateRenderObject has been removed.'); - } // r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17 + console.warn( 'THREE.TorusKnotBufferGeometry has been renamed to THREE.TorusKnotGeometry.' ); + super( radius, tube, tubularSegments, radialSegments, p, q ); - 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; } - } // 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); - } + // r144 - } // r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce + 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 ); - class DataTexture3D extends Data3DTexture { - constructor(data, width, height, depth) { - console.warn('THREE.DataTexture3D has been renamed to Data3DTexture.'); - super(data, width, height, depth); } } - if (typeof __THREE_DEVTOOLS__ !== 'undefined') { - __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('register', { - detail: { - revision: REVISION - } - })); + if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { + + __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'register', { detail: { + revision: REVISION, + } } ) ); + } - if (typeof window !== 'undefined') { - if (window.__THREE__) { - console.warn('WARNING: Multiple instances of Three.js being imported.'); + if ( typeof window !== 'undefined' ) { + + if ( window.__THREE__ ) { + + console.warn( 'WARNING: Multiple instances of Three.js being imported.' ); + } else { + window.__THREE__ = REVISION; + } + } exports.ACESFilmicToneMapping = ACESFilmicToneMapping; @@ -35166,7 +50609,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; @@ -35177,20 +50620,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; @@ -35209,14 +50653,12 @@ exports.CurvePath = CurvePath; exports.CustomBlending = CustomBlending; exports.CustomToneMapping = CustomToneMapping; - exports.CylinderBufferGeometry = CylinderGeometry; + exports.CylinderBufferGeometry = CylinderBufferGeometry; exports.CylinderGeometry = CylinderGeometry; exports.Cylindrical = Cylindrical; exports.Data3DTexture = Data3DTexture; exports.DataArrayTexture = DataArrayTexture; exports.DataTexture = DataTexture; - exports.DataTexture2DArray = DataTexture2DArray; - exports.DataTexture3D = DataTexture3D; exports.DataTextureLoader = DataTextureLoader; exports.DataUtils = DataUtils; exports.DecrementStencilOp = DecrementStencilOp; @@ -35228,7 +50670,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; @@ -35244,18 +50686,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; @@ -35272,12 +50711,11 @@ exports.HemisphereLight = HemisphereLight; exports.HemisphereLightHelper = HemisphereLightHelper; exports.HemisphereLightProbe = HemisphereLightProbe; - exports.IcosahedronBufferGeometry = IcosahedronGeometry; + exports.IcosahedronBufferGeometry = IcosahedronBufferGeometry; exports.IcosahedronGeometry = IcosahedronGeometry; exports.ImageBitmapLoader = ImageBitmapLoader; exports.ImageLoader = ImageLoader; exports.ImageUtils = ImageUtils; - exports.ImmediateRenderObject = ImmediateRenderObject; exports.IncrementStencilOp = IncrementStencilOp; exports.IncrementWrapStencilOp = IncrementWrapStencilOp; exports.InstancedBufferAttribute = InstancedBufferAttribute; @@ -35298,7 +50736,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; @@ -35373,7 +50811,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; @@ -35384,11 +50822,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; @@ -35396,7 +50833,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; @@ -35406,6 +50843,8 @@ exports.Quaternion = Quaternion; exports.QuaternionKeyframeTrack = QuaternionKeyframeTrack; exports.QuaternionLinearInterpolant = QuaternionLinearInterpolant; + exports.RED_GREEN_RGTC2_Format = RED_GREEN_RGTC2_Format; + exports.RED_RGTC1_Format = RED_RGTC1_Format; exports.REVISION = REVISION; exports.RGBADepthPacking = RGBADepthPacking; exports.RGBAFormat = RGBAFormat; @@ -35431,7 +50870,6 @@ exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format; exports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format; exports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format; - exports.RGBFormat = RGBFormat; exports.RGB_ETC1_Format = RGB_ETC1_Format; exports.RGB_ETC2_Format = RGB_ETC2_Format; exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format; @@ -35449,8 +50887,10 @@ exports.RepeatWrapping = RepeatWrapping; exports.ReplaceStencilOp = ReplaceStencilOp; exports.ReverseSubtractEquation = ReverseSubtractEquation; - exports.RingBufferGeometry = RingGeometry; + exports.RingBufferGeometry = RingBufferGeometry; exports.RingGeometry = RingGeometry; + exports.SIGNED_RED_GREEN_RGTC2_Format = SIGNED_RED_GREEN_RGTC2_Format; + exports.SIGNED_RED_RGTC1_Format = SIGNED_RED_RGTC1_Format; exports.SRGBColorSpace = SRGBColorSpace; exports.Scene = Scene; exports.ShaderChunk = ShaderChunk; @@ -35458,7 +50898,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; @@ -35466,10 +50906,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; @@ -35493,27 +50932,28 @@ 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.TwoPassDoubleSide = TwoPassDoubleSide; exports.UVMapping = UVMapping; exports.Uint16BufferAttribute = Uint16BufferAttribute; exports.Uint32BufferAttribute = Uint32BufferAttribute; exports.Uint8BufferAttribute = Uint8BufferAttribute; exports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute; exports.Uniform = Uniform; + exports.UniformsGroup = UniformsGroup; exports.UniformsLib = UniformsLib; exports.UniformsUtils = UniformsUtils; exports.UnsignedByteType = UnsignedByteType; @@ -35533,7 +50973,6 @@ exports.WebGLArrayRenderTarget = WebGLArrayRenderTarget; exports.WebGLCubeRenderTarget = WebGLCubeRenderTarget; exports.WebGLMultipleRenderTargets = WebGLMultipleRenderTargets; - exports.WebGLMultisampleRenderTarget = WebGLMultisampleRenderTarget; exports.WebGLRenderTarget = WebGLRenderTarget; exports.WebGLRenderer = WebGLRenderer; exports.WebGLUtils = WebGLUtils; @@ -35546,6 +50985,4 @@ exports._SRGBAFormat = _SRGBAFormat; exports.sRGBEncoding = sRGBEncoding; - Object.defineProperty(exports, '__esModule', { value: true }); - })); diff --git a/build/three.min.js b/build/three.min.js index bb56fc83643568..e28e6cdf3fc26e 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -1,6 +1,10 @@ /** * @license - * Copyright 2010-2022 Three.js Authors + * Copyright 2010-2023 Three.js Authors * SPDX-License-Identifier: MIT */ +<<<<<<< HEAD !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="141dev",i=100,n=300,r=301,s=302,a=303,o=304,l=306,c=1e3,h=1001,u=1002,d=1003,p=1004,m=1005,f=1006,g=1007,v=1008,x=1009,y=1012,_=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,z=37492,O=37496,F=37808,B=37809,U=37810,k=37811,G=37812,V=37813,H=37814,W=37815,j=37816,q=37817,X=37818,J=37819,Y=37820,Z=37821,K=36492,Q=2300,$=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 mt{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]+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 _t(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:yt,clamp:_t,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),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: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){this.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,e){return void 0!==e?(console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(t,e)):(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,e){return void 0!==e?(console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(t,e)):(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,i){return void 0!==i&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute()."),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(){this.isMatrix3=!0,this.elements=[1,0,0,0,1,0,0,0,1],arguments.length>0&&console.error("THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.")}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],y=n[7],_=n[2],M=n[5],b=n[8];return r[0]=s*m+a*v+o*_,r[3]=s*f+a*x+o*M,r[6]=s*g+a*y+o*b,r[1]=l*m+c*v+h*_,r[4]=l*f+c*x+h*M,r[7]=l*g+c*y+h*b,r[2]=u*m+d*v+p*_,r[5]=u*f+d*x+p*M,r[8]=u*g+d*y+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){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 zt={[lt]:{[ct]:Dt},[ct]:{[lt]:Nt}},Ot={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(zt[e]&&void 0!==zt[e][i]){const n=zt[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,Ot.toWorkingColorSpace(this,e),this}setRGB(t,e,i,n="srgb-linear"){return this.r=t,this.g=e,this.b=i,Ot.toWorkingColorSpace(this,n),this}setHSL(t,e,i,n="srgb-linear"){if(t=Mt(t,1),e=_t(e,0,1),i=_t(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 Ot.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,Ot.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,Ot.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,Ot.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,Ot.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 Ot.fromWorkingColorSpace(Vt(this,Bt),t),_t(255*Bt.r,0,255)<<16^_t(255*Bt.g,0,255)<<8^_t(255*Bt.b,0,255)<<0}getHexString(t="srgb"){return("000000"+this.getHex(t).toString(16)).slice(-6)}getHSL(t,e="srgb-linear"){Ot.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)}}Yt.DEFAULT_IMAGE=null,Yt.DEFAULT_MAPPING=n;class Zt{constructor(t=0,e=0,i=0,n=1){this.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,e){return void 0!==e?(console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(t,e)):(this.x+=t.x,this.y+=t.y,this.z+=t.z,this.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,e){return void 0!==e?(console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(t,e)):(this.x-=t.x,this.y-=t.y,this.z-=t.z,this.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){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(_t(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,e){return void 0!==e?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(t,e)):this.multiplyQuaternions(this,t)}premultiply(t){return this.multiplyQuaternions(t,this)}multiplyQuaternions(t,e){const i=t._x,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){this.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,e){return void 0!==e?(console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(t,e)):(this.x+=t.x,this.y+=t.y,this.z+=t.z,this)}addScalar(t){return this.x+=t,this.y+=t,this.z+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this}sub(t,e){return void 0!==e?(console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(t,e)):(this.x-=t.x,this.y-=t.y,this.z-=t.z,this)}subScalar(t){return this.x-=t,this.y-=t,this.z-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this}multiply(t,e){return void 0!==e?(console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(t,e)):(this.x*=t.x,this.y*=t.y,this.z*=t.z,this)}multiplyScalar(t){return this.x*=t,this.y*=t,this.z*=t,this}multiplyVectors(t,e){return this.x=t.x*e.x,this.y=t.y*e.y,this.z=t.z*e.z,this}applyEuler(t){return t&&t.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order."),this.applyQuaternion(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,e){return void 0!==e?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(t,e)):this.crossVectors(this,t)}crossVectors(t,e){const i=t.x,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(_t(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,i){return void 0!==i&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute()."),this.x=t.getX(e),this.y=t.getY(e),this.z=t.getZ(e),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this}randomDirection(){const t=2*(Math.random()-.5),e=Math.random()*Math.PI*2,i=Math.sqrt(1-t**2);return this.x=i*Math.cos(e),this.y=i*Math.sin(e),this.z=t,this}*[Symbol.iterator](){yield this.x,yield this.y,yield this.z}}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(me),fe.subVectors(this.max,me),le.subVectors(t.a,me),ce.subVectors(t.b,me),he.subVectors(t.c,me),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,fe)&&(e=[1,0,0,0,1,0,0,0,1],!!xe(e,le,ce,he,fe)&&(ge.crossVectors(ue,de),e=[ge.x,ge.y,ge.z],xe(e,le,ce,he,fe)))}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,me=new ee,fe=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 ye=new re,_e=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):ye.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(_e.copy(t.center).add(Me)),this.expandByPoint(_e.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(){this.isMatrix4=!0,this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],arguments.length>0&&console.error("THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.")}set(t,e,i,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 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){t&&t.isEuler||console.error("THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");const e=this.elements,i=t.x,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(ze,t,Oe)}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,e){return void 0!==e?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."),this.multiplyMatrices(t,e)):this.multiplyMatrices(this,t)}premultiply(t){return this.multiplyMatrices(t,this)}multiplyMatrices(t,e){const i=t.elements,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],y=i[11],_=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],z=n[11],O=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*z,r[12]=s*S+a*C+o*I+l*O,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*z,r[13]=c*S+h*C+u*I+d*O,r[2]=p*M+m*T+f*L+g*D,r[6]=p*b+m*A+f*R+g*N,r[10]=p*w+m*E+f*P+g*z,r[14]=p*S+m*C+f*I+g*O,r[3]=v*M+x*T+y*L+_*D,r[7]=v*b+x*A+y*R+_*N,r[11]=v*w+x*E+y*P+_*z,r[15]=v*S+x*C+y*I+_*O,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,y=c*m*l-p*h*l+p*a*d-s*m*d-c*a*g+s*h*g,_=p*h*o-c*m*o-p*a*u+s*m*u+c*a*f-s*h*f,M=e*v+i*x+n*y+r*_;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]=y*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]=_*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,y=o*h,_=i.x,M=i.y,b=i.z;return n[0]=(1-(m+g))*_,n[1]=(d+y)*_,n[2]=(p-x)*_,n[3]=0,n[4]=(d-y)*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=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){void 0===s&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.");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,ze=new ee(0,0,0),Oe=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(_t(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(-_t(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(_t(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(-_t(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(_t(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(-_t(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 mi.getNormal(this.a,this.b,this.c,t)}getPlane(t){return t.setFromCoplanarPoints(this.a,this.b,this.c)}getBarycoord(t,e){return mi.getBarycoord(t,this.a,this.b,this.c,e)}getUV(t,e,i,n,r){return mi.getUV(t,this.a,this.b,this.c,e,i,n,r)}containsPoint(t){return mi.containsPoint(t,this.a,this.b,this.c)}isFrontFacing(t){return mi.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 m=d*l-o*p;if(m<=0&&l>=0&&p<=0)return a=l/(l-p),e.copy(i).addScaledVector(ci,a);const f=c*p-d*h;if(f<=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/(f+m+u);return s=m*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 fi=0;class gi extends mt{constructor(){super(),this.isMaterial=!0,Object.defineProperty(this,"id",{value:fi++}),this.uuid=yt(),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++}get vertexTangents(){return console.warn("THREE."+this.type+": .vertexTangents has been removed."),!1}set vertexTangents(t){console.warn("THREE."+this.type+": .vertexTangents has been removed.")}}gi.fromType=function(){return null};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,yi=new Et;class _i{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,zi,Oi,Fi,Xi);if(p){o&&(Wi.fromBufferAttribute(o,c),ji.fromBufferAttribute(o,h),qi.fromBufferAttribute(o,u),p.uv=mi.getUV(Xi,zi,Oi,Fi,Wi,ji,qi,new Et)),l&&(Wi.fromBufferAttribute(l,c),ji.fromBufferAttribute(l,h),qi.fromBufferAttribute(l,u),p.uv2=mi.getUV(Xi,zi,Oi,Fi,Wi,ji,qi,new Et));const t={a:c,b:h,c:u,normal:new ee,materialIndex:0};mi.getNormal(zi,Oi,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,m,f,g,v){const x=s/f,y=p/g,_=s/2,M=p/2,b=m/2,w=f+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/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 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 Yt{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: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 Ki(5,5,5),r=new en({name:"CubemapFromEquirect",uniforms:Qi(i.uniforms),vertexShader:i.vertexShader,fragmentShader:i.fragmentShader,side:1,blending:0});r.uniforms.tEquirect.value=e;const s=new Yi(n,r),a=e.minFilter;e.minFilter===v&&(e.minFilter=f);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,mn=new ee;class fn{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],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(),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,mn.y=n.normal.y>0?t.max.y:t.min.y,mn.z=n.normal.z>0?t.max.z:t.min.z,n.distanceToPoint(mn)<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\nconst mat3 XYZ_TO_REC709 = mat3(\n\t\t3.2404542, -0.9692660,\t0.0556434,\n\t -1.5371385,\t1.8760108, -0.2040259,\n\t -0.4985314,\t0.0415560,\t1.0572252\n);\nvec3 Fresnel0ToIor( vec3 fresnel0 ) {\n\t vec3 sqrtF0 = sqrt( fresnel0 );\n\t return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n}\nvec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n\t return pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n}\nfloat IorToFresnel0( float transmittedIor, float incidentIor ) {\n\t return pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n}\nvec3 evalSensitivity( float OPD, vec3 shift ) {\n\t float phase = 2.0 * PI * OPD * 1.0e-9;\n\t vec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n\t vec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n\t vec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n\t vec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( -pow2( phase ) * var );\n\t xyz.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 xyz /= 1.0685e-7;\n\t vec3 srgb = XYZ_TO_REC709 * xyz;\n\t return srgb;\n}\nvec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n\t vec3 I;\n\t float iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n\t float sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n\t float cosTheta2Sq = 1.0 - sinTheta2Sq;\n\t if ( cosTheta2Sq < 0.0 ) {\n\t\t\t return vec3( 1.0 );\n\t }\n\t float cosTheta2 = sqrt( cosTheta2Sq );\n\t float R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\n\t float R12 = F_Schlick( R0, 1.0, cosTheta1 );\n\t float R21 = R12;\n\t float T121 = 1.0 - R12;\n\t float phi12 = 0.0;\n\t if ( iridescenceIOR < outsideIOR ) phi12 = PI;\n\t float phi21 = PI - phi12;\n\t vec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) );\t vec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n\t vec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n\t vec3 phi23 = vec3( 0.0 );\n\t if ( baseIOR[0] < iridescenceIOR ) phi23[0] = PI;\n\t if ( baseIOR[1] < iridescenceIOR ) phi23[1] = PI;\n\t if ( baseIOR[2] < iridescenceIOR ) phi23[2] = PI;\n\t float OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n\t vec3 phi = vec3( phi21 ) + phi23;\n\t vec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n\t vec3 r123 = sqrt( R123 );\n\t vec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n\t vec3 C0 = R12 + Rs;\n\t I = C0;\n\t vec3 Cm = Rs - T121;\n\t for ( int m = 1; m <= 2; ++m ) {\n\t\t\t Cm *= r123;\n\t\t\t vec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n\t\t\t I += Cm * Sm;\n\t }\n\t return max( I, vec3( 0.0 ) );\n}\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 = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 ) * 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 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat 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 linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}",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 ) || defined( ENVMAP_TYPE_CUBE )\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, worldNormal );\n\t\t\t#endif\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 ) || defined( ENVMAP_TYPE_CUBE )\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\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t\t#else\n\t\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec );\n\t\t\t#endif\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\nfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\nif ( material.iridescenceThickness == 0.0 ) {\n\tmaterial.iridescence = 0.0;\n} else {\n\tmaterial.iridescence = saturate( material.iridescence );\n}\nif ( material.iridescence > 0.0 ) {\n\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n}\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 ) || defined( ENVMAP_TYPE_CUBE ) )\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 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\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\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}"},_n={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:$i([_n.common,_n.specularmap,_n.envmap,_n.aomap,_n.lightmap,_n.fog]),vertexShader:yn.meshbasic_vert,fragmentShader:yn.meshbasic_frag},lambert:{uniforms:$i([_n.common,_n.specularmap,_n.envmap,_n.aomap,_n.lightmap,_n.emissivemap,_n.fog,_n.lights,{emissive:{value:new Ht(0)}}]),vertexShader:yn.meshlambert_vert,fragmentShader:yn.meshlambert_frag},phong:{uniforms:$i([_n.common,_n.specularmap,_n.envmap,_n.aomap,_n.lightmap,_n.emissivemap,_n.bumpmap,_n.normalmap,_n.displacementmap,_n.fog,_n.lights,{emissive:{value:new Ht(0)},specular:{value:new Ht(1118481)},shininess:{value:30}}]),vertexShader:yn.meshphong_vert,fragmentShader:yn.meshphong_frag},standard:{uniforms:$i([_n.common,_n.envmap,_n.aomap,_n.lightmap,_n.emissivemap,_n.bumpmap,_n.normalmap,_n.displacementmap,_n.roughnessmap,_n.metalnessmap,_n.fog,_n.lights,{emissive:{value:new Ht(0)},roughness:{value:1},metalness:{value:0},envMapIntensity:{value:1}}]),vertexShader:yn.meshphysical_vert,fragmentShader:yn.meshphysical_frag},toon:{uniforms:$i([_n.common,_n.aomap,_n.lightmap,_n.emissivemap,_n.bumpmap,_n.normalmap,_n.displacementmap,_n.gradientmap,_n.fog,_n.lights,{emissive:{value:new Ht(0)}}]),vertexShader:yn.meshtoon_vert,fragmentShader:yn.meshtoon_frag},matcap:{uniforms:$i([_n.common,_n.bumpmap,_n.normalmap,_n.displacementmap,_n.fog,{matcap:{value:null}}]),vertexShader:yn.meshmatcap_vert,fragmentShader:yn.meshmatcap_frag},points:{uniforms:$i([_n.points,_n.fog]),vertexShader:yn.points_vert,fragmentShader:yn.points_frag},dashed:{uniforms:$i([_n.common,_n.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:yn.linedashed_vert,fragmentShader:yn.linedashed_frag},depth:{uniforms:$i([_n.common,_n.displacementmap]),vertexShader:yn.depth_vert,fragmentShader:yn.depth_frag},normal:{uniforms:$i([_n.common,_n.bumpmap,_n.normalmap,_n.displacementmap,{opacity:{value:1}}]),vertexShader:yn.meshnormal_vert,fragmentShader:yn.meshnormal_frag},sprite:{uniforms:$i([_n.sprite,_n.fog]),vertexShader:yn.sprite_vert,fragmentShader:yn.sprite_frag},background:{uniforms:{uvTransform:{value:new Ct},t2D:{value:null}},vertexShader:yn.background_vert,fragmentShader:yn.background_frag},cube:{uniforms:$i([_n.envmap,{opacity:{value:1}}]),vertexShader:yn.cube_vert,fragmentShader:yn.cube_frag},equirect:{uniforms:{tEquirect:{value:null}},vertexShader:yn.equirect_vert,fragmentShader:yn.equirect_frag},distanceRGBA:{uniforms:$i([_n.common,_n.displacementmap,{referencePosition:{value:new ee},nearDistance:{value:1},farDistance:{value:1e3}}]),vertexShader:yn.distanceRGBA_vert,fragmentShader:yn.distanceRGBA_frag},shadow:{uniforms:$i([_n.lights,_n.fog,{color:{value:new Ht(0)},opacity:{value:1}}]),vertexShader:yn.shadow_vert,fragmentShader:yn.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 m(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,m(a,h)},getClearAlpha:function(){return h},setClearAlpha:function(t){h=t,m(a,h)},render:function(i,r){let s=!1,f=!0===r.isScene?r.background:null;f&&f.isTexture&&(f=e.get(f));const g=t.xr,v=g.getSession&&g.getSession();v&&"additive"===v.environmentBlendMode&&(f=null),null===f?m(a,h):f&&f.isColor&&(m(f,1),s=!0),(t.autoClear||s)&&t.clear(t.autoClearColor,t.autoClearDepth,t.autoClearStencil),f&&(f.isCubeTexture||f.mapping===l)?(void 0===c&&(c=new Yi(new Ki(1,1,1),new en({name:"BackgroundCubeMaterial",uniforms:Qi(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=f,c.material.uniforms.flipEnvMap.value=f.isCubeTexture&&!1===f.isRenderTargetTexture?-1:1,u===f&&d===f.version&&p===t.toneMapping||(c.material.needsUpdate=!0,u=f,d=f.version,p=t.toneMapping),c.layers.enableAll(),i.unshift(c,c.geometry,c.material,0,0,null)):f&&f.isTexture&&(void 0===o&&(o=new Yi(new xn(2,2),new en({name:"BackgroundMaterial",uniforms:Qi(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=f,!0===f.matrixAutoUpdate&&f.updateMatrix(),o.material.uniforms.uvTransform.value.copy(f.matrix),u===f&&d===f.version&&p===t.toneMapping||(o.material.needsUpdate=!0,u=f,d=f.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,y,d,_),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,y,d,_)}else{const t=!0===l.wireframe;c.geometry===y.id&&c.program===d.id&&c.wireframe===t||(c.geometry=y.id,c.program=d.id,c.wireframe=t,M=!0)}null!==_&&i.update(_,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,y=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:y,floatVertexTextures:x&&y,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:$i([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:yn.meshphysical_vert,fragmentShader:yn.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,zn=1/Nn,On=[new ee(1,1,1),new ee(-1,1,1),new ee(1,1,-1),new ee(-1,1,-1),new ee(0,Nn,zn),new ee(0,Nn,-zn),new ee(zn,0,Nn),new ee(-zn,0,Nn),new ee(Nn,zn,0),new ee(-Nn,zn,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,r=null,s=null){return Dn=this._renderer.getRenderTarget(),r||(r=this._allocateTargets()),s&&(this._pingPongRenderTarget=s),this._setSize(256),r.depthBuffer=!0,this._sceneToCubeUV(t,i,n,r),e>0&&this._blur(r,0,0,e),this._applyPMREM(r),this._cleanup(r),r}prepareForRenderTarget(t,e=null,i=256){this._setSize(i);const{_lodMax:n}=this;({sizeLods:this._sizeLods,lodPlanes:this._lodPlanes,sigmas:this._sigmas}=Bn(n));const r=3*Math.max(this._cubeSize,112),s=4*this._cubeSize;this._blurMaterial=Gn(n,r,s),t.setSize(r,s),e&&e.setSize(r,s)}fromSceneToRenderTarget(t,e,i,n=0,r=.1,s=100){return Dn=this._renderer.getRenderTarget(),this._pingPongRenderTarget=i,this._sceneToCubeUV(t,r,s,e),n>0&&this._blur(e,0,0,n),this._applyPMREM(e),this._renderer.setRenderTarget(Dn),e.scissorTest=!1,kn(e,0,0,e.width,e.height),e}fromEquirectangular(t,e=null){return this._fromTexture(t,e)}fromCubemap(t,e=null){return this._fromTexture(t,e)}compileCubemapShader(){null===this._cubemapMaterial&&(this._cubemapMaterial=Hn(),this._compileMaterial(this._cubemapMaterial))}compileEquirectangularShader(){null===this._equirectMaterial&&(this._equirectMaterial=Vn(),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;t2?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=Hn()),this._cubemapMaterial.uniforms.flipEnvMap.value=!1===t.isRenderTargetTexture?-1:1):null===this._equirectMaterial&&(this._equirectMaterial=Vn());const a=n?this._cubemapMaterial:this._equirectMaterial,o=new Yi(this._lodPlanes[0],a);a.uniforms.envMap.value=t;const l=this._cubeSize;kn(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 ${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,Pn)}}function Bn(t){const e=[],i=[],n=[];let r=t;const s=t-4+1+Ln.length;for(let a=0;at-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,m=3,f=2,g=1,v=new Float32Array(m*p*d),x=new Float32Array(f*p*d),y=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];y.set(r,g*p*t)}const _=new Pi;_.setAttribute("position",new _i(v,m)),_.setAttribute("uv",new _i(x,f)),_.setAttribute("faceIndex",new _i(y,g)),e.push(_),r>4&&r--}return{lodPlanes:e,sizeLods:i,sigmas:n}}function Un(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 kn(t,e,i,n,r){t.viewport.set(e,i,n,r),t.scissor.set(e,i,n,r)}function Gn(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:Wn(),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})}function Vn(){return new en({name:"EquirectangularToCubeUV",uniforms:{envMap:{value:null}},vertexShader:Wn(),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 Hn(){return new en({name:"CubemapToCubeUV",uniforms:{envMap:{value:null},flipEnvMap:{value:-1}},vertexShader:Wn(),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 Wn(){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\tmat3 getRotationMatrix(vec3 axis, float angle) {\n\t\t\taxis = normalize(axis);\n\t\t\tfloat s = sin(angle);\n\t\t\tfloat c = cos(angle);\n\t\t\tfloat oc = 1.0 - c;\n\t\t\n\t\t\treturn mat3(oc * axis.x * axis.x + c,\t\t\t\t\t oc * axis.x * axis.y - axis.z * s,\toc * axis.z * axis.x + axis.y * s,\n\t\t\t\t\t\toc * axis.x * axis.y + axis.z * s,\toc * axis.y * axis.y + c,\t\t\t\t\t oc * axis.y * axis.z - axis.x * s,\n\t\t\t\t\t\toc * axis.z * axis.x - axis.y * s,\toc * axis.y * axis.z + axis.x * s,\toc * axis.z * axis.z + c);\n\t\t}\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\t\t\tmat3 rotationMatrix = getRotationMatrix(vec3(1.0, 0.0, 0.0), 1.57);\n\t\t\tdirection = rotationMatrix * direction;\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 jn(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*m),L=new Qt(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=sr[r];if(void 0===s&&(s=new Float32Array(r),sr[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 ur(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 ls(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 cs(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 hs(t){return""!==t}function us(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 ds(t,e){return t.replace(/NUM_CLIPPING_PLANES/g,e.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g,e.numClippingPlanes-e.numClipIntersection)}const ps=/^[ \t]*#include +<([\w\d./]+)>/gm;function ms(t){return t.replace(ps,fs)}function fs(t,e){const i=yn[e];if(void 0===i)throw new Error("Can not resolve #include <"+e+">");return ms(i)}const gs=/#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g,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).replace(gs,ys)}function ys(t,e,i,n){return console.warn("WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead."),_s(t,e,i,n)}function _s(t,e,i,n){let r="";for(let t=parseInt(e);t0&&(y+="\n"),_=[g,v].filter(hs).join("\n"),_.length>0&&(_+="\n")):(y=[Ms(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(hs).join("\n"),_=[g,Ms(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?yn.tonemapping_pars_fragment:"",0!==i.toneMapping?cs("toneMapping",i.toneMapping):"",i.dithering?"#define DITHERING":"",i.opaque?"#define OPAQUE":"",yn.encodings_pars_fragment,ls("linearToOutputTexel",i.outputEncoding),i.useDepthPacking?"#define DEPTH_PACKING "+i.depthPacking:"","\n"].filter(hs).join("\n")),t.onShaderBeforeResolve){const e=t.onShaderBeforeResolve(c,h,i);c=e.vertexShader,h=e.fragmentShader}c=ms(c),c=us(c,i),c=ds(c,i),h=ms(h),h=us(h,i),h=ds(h,i),c=xs(c),h=xs(h),i.isWebGL2&&!0!==i.isRawShaderMaterial&&(M="#version 300 es\n",y=["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"+_);let b=M+y+c,w=M+_+h;if(t.onShaderBeforeCompile){const e=t.onShaderBeforeCompile(b,w,i);b=e.vertexShader,w=e.fragmentShader}const S=ss(a,35633,b),T=ss(a,35632,w);if(a.attachShader(x,S),a.attachShader(x,T),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(T).trim();let n=!0,r=!0;if(!1===a.getProgramParameter(x,35714)){n=!1;const e=os(a,S,"vertex"),i=os(a,T,"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:y},fragmentShader:{log:i,prefix:_}})}let A,E;return a.deleteShader(S),a.deleteShader(T),this.getUniforms=function(){return void 0===A&&(A=new rs(a,x)),A},this.getAttributes=function(){return void 0===E&&(E=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: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&&!!y.attributes.tangent,vertexColors:s.vertexColors,vertexAlphas:!0===s.vertexColors&&!!y.attributes.color&&4===y.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!==y.morphAttributes.position,morphNormals:void 0!==y.morphAttributes.normal,morphColors:void 0!==y.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(),extraProgramCacheKey:t.extraProgramCacheKey}},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),t.extraProgramCacheKey&&i.push(t.extraProgramCacheKey),i.join()},getUniforms:function(t){const e=f[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||Cs),n.length>1&&n.sort(e||Ls),r.length>1&&r.sort(e||Ls)}}}function Ps(){let t=new WeakMap;return{get:function(e,i){let n;return!1===t.has(e)?(n=new Rs,t.set(e,[n])):i>=t.get(e).length?(n=new Rs,t.get(e).push(n)):n=t.get(e)[i],n},dispose:function(){t=new WeakMap}}}function Is(){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 Ds=0;function Ns(t,e){return(e.castShadow?1:0)-(t.castShadow?1:0)}function zs(t,e){const i=new Is,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,m=0,f=0,g=0,v=0;s.sort(Ns);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=_n.LTC_FLOAT_1,r.rectAreaLTC2=_n.LTC_FLOAT_2):!0===t.has("OES_texture_half_float_linear")?(r.rectAreaLTC1=_n.LTC_HALF_1,r.rectAreaLTC2=_n.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 y=r.hash;y.directionalLength===h&&y.pointLength===u&&y.spotLength===d&&y.rectAreaLength===p&&y.hemiLength===m&&y.numDirectionalShadows===f&&y.numPointShadows===g&&y.numSpotShadows===v||(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.spotShadowMatrix.length=v,y.directionalLength=h,y.pointLength=u,y.spotLength=d,y.rectAreaLength=p,y.hemiLength=m,y.numDirectionalShadows=f,y.numPointShadows=g,y.numSpotShadows=v,r.version=Ds++)},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 Os(t,e),i.get(n).push(s)):s=i.get(n)[r],s},dispose:function(){i=new WeakMap}}}class Bs 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 Us 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 ks(t,e,i){let n=new fn;const r=new Et,s=new Et,a=new Zt,o=new Bs({depthPacking:3201}),l=new Us,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}"}),m=p.clone();m.defines.HORIZONTAL_PASS=1;const f=new Pi;f.setAttribute("position",new _i(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));const g=new Yi(f,p),v=this;function x(i,n){const r=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),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,r,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,r,m,g,null)}function y(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&&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 _(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||u.isPointLightShadow||3!==this.type||(u.map=new Kt(r.x,r.y),u.map.texture.name=c.name+".shadowMap",u.mapPass=new Kt(r.x,r.y),u.camera.updateProjectionMatrix()),null===u.map){const t={minFilter:d,magFilter:d,format:S};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 f=u.getViewportCount();for(let t=0;t=1):-1!==R.indexOf("OpenGL ES")&&(L=parseFloat(/^OpenGL ES (\d)/.exec(R)[1]),C=L>=2);let P=null,I={};const D=t.getParameter(3088),N=t.getParameter(2978),z=(new Zt).fromArray(D),O=(new Zt).fromArray(N);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=O(s,a));const o=i?O(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!==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===U(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 $(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 Y={[c]:10497,[h]:33071,[u]:33648},Z={[d]:9728,[p]:9984,[m]:9986,[f]:9729,[g]:9985,[v]:9987};function K(i,s,a){if(a?(t.texParameteri(i,10242,Y[s.wrapS]),t.texParameteri(i,10243,Y[s.wrapT]),32879!==i&&35866!==i||t.texParameteri(i,32882,Y[s.wrapR]),t.texParameteri(i,10240,Z[s.magFilter]),t.texParameteri(i,10241,Z[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 Q(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 $(e,n,r){let a=3553;n.isDataArrayTexture&&(a=35866),n.isData3DTexture&&(a=32879);const l=Q(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!==f)}(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 m,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===_?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!==y&&n.type!==_&&(console.warn("THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture."),n.type=_,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=f,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=J,this.setTexture2DArray=function(t,e){const r=n.get(t);t.version>0&&r.__version!==t.version?$(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?$(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=Q(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),m=G(n.internalFormat,d,p,n.encoding),f=o&&!0!==n.isVideoTexture,g=void 0===l.__currentVersion||!0===a;let v,x=V(n,h,u);if(K(34067,n,u),e){f&&g&&i.texStorage2D(34067,x,m,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,m,c[0].width,c[0].height));for(let t=0;t<6;t++)if(r){f?i.texSubImage2D(34069+t,0,0,0,c[t].width,c[t].height,d,p,c[t].data):i.texImage2D(34069+t,0,m,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));return null!==a&&(a.visible=null!==n),null!==o&&(o.visible=null!==r),null!==l&&(l.visible=null!==s),this}}class Js extends Yt{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=_),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 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 Map,y=new rn;y.layers.enable(1),y.viewport=new Zt;const M=new rn;M.layers.enable(2),M.viewport=new Zt;const b=[y,M],E=new Ws;E.layers.enable(1),E.layers.enable(2);let C=null,L=null;function R(t){const e=v.get(t.inputSource);void 0!==e&&e.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),v.forEach((function(t,e){void 0!==t&&t.disconnect(e)})),v.clear(),C=null,L=null,t.setRenderTarget(m),u=null,h=null,c=null,n=null,f=null,F.stop(),i.isPresenting=!1,i.dispatchEvent({type:"sessionend"})}function I(t){const e=n.inputSources;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 Ks(t={}){this.isWebGLRenderer=!0;const e=void 0!==t.canvas?t.canvas:function(){const t=It("canvas");return t.style.display="block",t}(),i=void 0!==t.context?t.context:null,n=void 0===t.depth||t.depth,r=void 0===t.stencil||t.stencil,s=void 0!==t.antialias&&t.antialias,a=void 0===t.premultipliedAlpha||t.premultipliedAlpha,o=void 0!==t.preserveDrawingBuffer&&t.preserveDrawingBuffer,l=void 0!==t.powerPreference?t.powerPreference:"default",c=void 0!==t.failIfMajorPerformanceCaveat&&t.failIfMajorPerformanceCaveat;let h;h=null!==i?i.getContextAttributes().alpha:void 0!==t.alpha&&t.alpha;let u=null,d=null;const p=[],m=[];this.domElement=e,this.debug={checkShaderErrors:!0},this.autoClear=!0,this.autoClearColor=!0,this.autoClearDepth=!0,this.autoClearStencil=!0,this.sortObjects=!0,this.clippingPlanes=[],this.localClippingEnabled=!1,this.outputEncoding=at,this.physicallyCorrectLights=!1,this.toneMapping=0,this.toneMappingExposure=1,Object.defineProperties(this,{gammaFactor:{get:function(){return console.warn("THREE.WebGLRenderer: .gammaFactor has been removed."),2},set:function(){console.warn("THREE.WebGLRenderer: .gammaFactor has been removed.")}}});const f=this;let g=!1,y=0,_=0,w=null,T=-1,A=null;const E=new Zt,C=new Zt;let L=null,R=e.width,P=e.height,I=1,D=null,N=null;const z=new Zt(0,0,R,P),O=new Zt(0,0,R,P);let F=!1;const B=new fn;let U=!1,k=!1,G=null;const V=new Ie,H=new Et,W=new ee,j={background:null,fog:null,environment:null,overrideMaterial:null,isScene:!0};function q(){return null===w?I:1}let X,J,Y,Z,K,Q,$,tt,et,it,nt,rt,st,ot,lt,ct,ht,ut,dt,pt,mt,ft,gt,vt=i;function xt(t,i){for(let n=0;n0&&function(t,e,i){const n=J.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}));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,Q.updateMultisampleRenderTarget(G),Q.updateRenderTargetMipmap(G),f.setRenderTarget(r)}(r,e,i),n&&Y.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),Y.buffers.depth.setTest(!0),Y.buffers.depth.setMask(!0),Y.buffers.color.setMask(!0),Y.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 y},this.getActiveMipmapLevel=function(){return _},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,y=e,_=i;let n=!0;if(t){const e=K.get(t);void 0!==e.__useDefaultFramebuffer?(Y.bindFramebuffer(36160,null),n=!1):void 0===e.__webglFramebuffer?Q.setupRenderTarget(t):e.__hasExternalTextures&&Q.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=J.isWebGL2&&t.samples>0&&!1===Q.useMultisampledRTT(t)?K.get(t).__webglMultisampledFramebuffer:n,E.copy(t.viewport),C.copy(t.scissor),L=t.scissorTest}else E.copy(z).multiplyScalar(I).floor(),C.copy(O).multiplyScalar(I).floor(),L=F;if(Y.bindFramebuffer(36160,r)&&J.drawBuffers&&n&&Y.drawBuffers(t,r),Y.viewport(E),Y.scissor(C),Y.setScissorTest(L),s){const n=K.get(t.texture);vt.framebufferTexture2D(36160,36064,34069+e,n.__webglTexture,i)}else if(a){const n=K.get(t.texture),r=e||0;vt.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){Y.bindFramebuffer(36160,o);try{const a=t.texture,o=a.format,l=a.type;if(o!==S&&ft.convert(o)!==vt.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")||J.isWebGL2&&X.has("EXT_color_buffer_float"));if(!(l===x||ft.convert(l)===vt.getParameter(35738)||l===M&&(J.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&&vt.readPixels(e,i,n,r,ft.convert(o),ft.convert(l),s)}finally{const t=null!==w?K.get(w).__webglFramebuffer:null;Y.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);Q.setTexture2D(e,0),vt.copyTexSubImage2D(3553,i,0,0,t.x,t.y,r,s),Y.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);Q.setTexture2D(i,0),vt.pixelStorei(37440,i.flipY),vt.pixelStorei(37441,i.premultiplyAlpha),vt.pixelStorei(3317,i.unpackAlignment),e.isDataTexture?vt.texSubImage2D(3553,n,t.x,t.y,r,s,a,o,e.image.data):e.isCompressedTexture?vt.compressedTexSubImage2D(3553,n,t.x,t.y,e.mipmaps[0].width,e.mipmaps[0].height,a,e.mipmaps[0].data):vt.texSubImage2D(3553,n,t.x,t.y,a,o,e.image),0===n&&i.generateMipmaps&&vt.generateMipmap(3553),Y.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)Q.setTexture3D(n,0),h=32879;else{if(!n.isDataArrayTexture)return void console.warn("THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.");Q.setTexture2DArray(n,0),h=35866}vt.pixelStorei(37440,n.flipY),vt.pixelStorei(37441,n.premultiplyAlpha),vt.pixelStorei(3317,n.unpackAlignment);const u=vt.getParameter(3314),d=vt.getParameter(32878),p=vt.getParameter(3316),m=vt.getParameter(3315),g=vt.getParameter(32877),v=i.isCompressedTexture?i.mipmaps[0]:i.image;vt.pixelStorei(3314,v.width),vt.pixelStorei(32878,v.height),vt.pixelStorei(3316,t.min.x),vt.pixelStorei(3315,t.min.y),vt.pixelStorei(32877,t.min.z),i.isDataTexture||i.isData3DTexture?vt.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."),vt.compressedTexSubImage3D(h,r,e.x,e.y,e.z,s,a,o,l,v.data)):vt.texSubImage3D(h,r,e.x,e.y,e.z,s,a,o,l,c,v),vt.pixelStorei(3314,u),vt.pixelStorei(32878,d),vt.pixelStorei(3316,p),vt.pixelStorei(3315,m),vt.pixelStorei(32877,g),0===r&&n.generateMipmaps&&vt.generateMipmap(h),Y.unbindTexture()},this.initTexture=function(t){Q.setTexture2D(t,0),Y.unbindTexture()},this.resetState=function(){y=0,_=0,w=null,Y.reset(),gt.reset()},"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}class Qs extends Ks{}Qs.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 ta{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 ta(this.color,this.near,this.far)}toJSON(){return{type:"Fog",color:this.color.getHex(),near:this.near,far:this.far}}}class ea 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 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=yt()}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:mi.getUV(oa,pa,ma,fa,ga,va,xa,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){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 ee,ba=new ee;class wa 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){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=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(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 so extends Yt{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 ao{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(_t(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(_t(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 oo extends ao{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]:(ho.subVectors(n[0],n[1]).add(n[0]),a=ho);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(go(a,o.x,l.x,c.x,h.x),go(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 Lo 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=_t(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,m=new ee;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 wi(h,3)),this.setAttribute("normal",new wi(u,3)),this.setAttribute("uv",new wi(d,2))}static fromJSON(t){return new Io(t.radiusTop,t.radiusBottom,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class Do extends Io{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 Do(t.radius,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class No 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 No(t.vertices,t.indices,t.radius,t.details)}}class zo extends No{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 Oo=new ee,Fo=new ee,Bo=new ee,Uo=new mi;class ko 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 jo(s,a,i,o,l,p),a};function Ho(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=hl(s,t[s],t[s+1],a);return a&&rl(a,a.next)&&(ul(a),a=a.next),a}function Wo(t,e){if(!t)return t;e||(e=t);let i,n=t;do{if(i=!1,n.steiner||!rl(n,n.next)&&0!==nl(n.prev,n,n.next))n=n.next;else{if(ul(n),n=e=n.prev,n===n.next)break;i=!0}}while(i||n!==e);return e}function jo(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?Xo(t,n,r,s):qo(t))e.push(o.i/i),e.push(t.i/i),e.push(l.i/i),ul(t),t=l.next,c=l.next;else if((t=l)===c){a?1===a?jo(t=Jo(Wo(t),e,i),e,i,n,r,s,2):2===a&&Yo(t,e,i,n,r,s):jo(Wo(t),e,i,n,r,s,1);break}}function qo(t){const e=t.prev,i=t,n=t.next;if(nl(e,i,n)>=0)return!1;let r=t.next.next;for(;r!==t.prev;){if(el(e.x,e.y,i.x,i.y,n.x,n.y,r.x,r.y)&&nl(r.prev,r,r.next)>=0)return!1;r=r.next}return!0}function Xo(t,e,i,n){const r=t.prev,s=t,a=t.next;if(nl(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,m=t.nextZ;for(;p&&p.z>=u&&m&&m.z<=d;){if(p!==t.prev&&p!==t.next&&el(r.x,r.y,s.x,s.y,a.x,a.y,p.x,p.y)&&nl(p.prev,p,p.next)>=0)return!1;if(p=p.prevZ,m!==t.prev&&m!==t.next&&el(r.x,r.y,s.x,s.y,a.x,a.y,m.x,m.y)&&nl(m.prev,m,m.next)>=0)return!1;m=m.nextZ}for(;p&&p.z>=u;){if(p!==t.prev&&p!==t.next&&el(r.x,r.y,s.x,s.y,a.x,a.y,p.x,p.y)&&nl(p.prev,p,p.next)>=0)return!1;p=p.prevZ}for(;m&&m.z<=d;){if(m!==t.prev&&m!==t.next&&el(r.x,r.y,s.x,s.y,a.x,a.y,m.x,m.y)&&nl(m.prev,m,m.next)>=0)return!1;m=m.nextZ}return!0}function Jo(t,e,i){let n=t;do{const r=n.prev,s=n.next.next;!rl(r,s)&&sl(r,n,n.next,s)&&ll(r,s)&&ll(s,r)&&(e.push(r.i/i),e.push(n.i/i),e.push(s.i/i),ul(n),ul(n.next),n=t=s),n=n.next}while(n!==t);return Wo(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&&il(a,t)){let o=cl(a,t);return a=Wo(a,a.next),o=Wo(o,o.next),jo(a,e,i,n,r,s),void jo(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 Ko(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&&el(rs.x||i.x===s.x&&Qo(s,i)))&&(s=i,u=h)),i=i.next}while(i!==o);return s}(t,e),e){const i=cl(e,t);Wo(e,e.next),Wo(i,i.next)}}function Qo(t,e){return nl(t.prev,t,e.prev)<0&&nl(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 tl(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 il(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&&sl(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(ll(t,e)&&ll(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)&&(nl(t.prev,t,e.prev)||nl(t,e.prev,e))||rl(t,e)&&nl(t.prev,t,t.next)>0&&nl(e.prev,e,e.next)>0)}function nl(t,e,i){return(e.y-t.y)*(i.x-e.x)-(e.x-t.x)*(i.y-e.y)}function rl(t,e){return t.x===e.x&&t.y===e.y}function sl(t,e,i,n){const r=ol(nl(t,e,i)),s=ol(nl(t,e,n)),a=ol(nl(i,n,t)),o=ol(nl(i,n,e));return r!==s&&a!==o||(!(0!==r||!al(t,i,e))||(!(0!==s||!al(t,n,e))||(!(0!==a||!al(i,t,n))||!(0!==o||!al(i,e,n)))))}function al(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 ol(t){return t>0?1:t<0?-1:0}function ll(t,e){return nl(t.prev,t,t.next)<0?nl(t,e,t.next)>=0&&nl(t,t.prev,e)>=0:nl(t,e,t.prev)<0||nl(t,t.next,e)<0}function cl(t,e){const i=new dl(t.i,t.x,t.y),n=new dl(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 hl(t,e,i,n){const r=new dl(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 ul(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 dl(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 pl{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,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 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 Nl 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 zl 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 Fl 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 Bl 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 Ul extends Ga{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}}const kl={ShadowMaterial:Rl,SpriteMaterial:sa,RawShaderMaterial:Pl,ShaderMaterial:en,PointsMaterial:Qa,MeshPhysicalMaterial:Dl,MeshStandardMaterial:Il,MeshPhongMaterial:Nl,MeshToonMaterial:zl,MeshNormalMaterial:Ol,MeshLambertMaterial:Fl,MeshDepthMaterial:Bs,MeshDistanceMaterial:Us,MeshBasicMaterial:vi,MeshMatcapMaterial:Bl,LineDashedMaterial:Ul,LineBasicMaterial:Ga,Material:gi};gi.fromType=function(t){return new kl[t]};const Gl={arraySlice:function(t,e,i){return Gl.isTypedArray(t)?new t.constructor(t.subarray(e,void 0!==i?i:t.length)):t.slice(e,i)},convertArray:function(t,e,i){return!t||!i&&t.constructor===e?t:"number"==typeof e.BYTES_PER_ELEMENT?new e(t):Array.prototype.slice.call(t)},isTypedArray:function(t){return ArrayBuffer.isView(t)&&!(t instanceof DataView)},getKeyframeOrder:function(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},sortedArray:function(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},flattenJSON:function(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)},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.arraySlice(n.values,t,e)}else{const t=n.createInterpolant(),e=o,i=l-o;t.evaluate(s),d=Gl.arraySlice(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=Gl.arraySlice(i,r,s),this.values=Gl.arraySlice(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.isTypedArray(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.arraySlice(this.times),e=Gl.arraySlice(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.arraySlice(t,0,s),this.values=Gl.arraySlice(e,0,s*i)):(this.times=t,this.values=e),this}clone(){const t=Gl.arraySlice(this.times,0),e=Gl.arraySlice(this.values,0),i=new(0,this.constructor)(this.name,t,e);return i.createInterpolant=this.createInterpolant,i}}ql.prototype.TimeBufferType=Float32Array,ql.prototype.ValueBufferType=Float32Array,ql.prototype.DefaultInterpolation=$;class Xl extends ql{}Xl.prototype.ValueTypeName="bool",Xl.prototype.ValueBufferType=Array,Xl.prototype.DefaultInterpolation=Q,Xl.prototype.InterpolantFactoryMethodLinear=void 0,Xl.prototype.InterpolantFactoryMethodSmooth=void 0;class Jl extends ql{}Jl.prototype.ValueTypeName="color";class Yl extends ql{}Yl.prototype.ValueTypeName="number";class Zl extends Vl{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 Kl extends ql{InterpolantFactoryMethodLinear(t){return new Zl(this.times,this.values,this.getValueSize(),t)}}Kl.prototype.ValueTypeName="quaternion",Kl.prototype.DefaultInterpolation=$,Kl.prototype.InterpolantFactoryMethodSmooth=void 0;class Ql extends ql{}Ql.prototype.ValueTypeName="string",Ql.prototype.ValueBufferType=Array,Ql.prototype.DefaultInterpolation=Q,Ql.prototype.InterpolantFactoryMethodLinear=void 0,Ql.prototype.InterpolantFactoryMethodSmooth=void 0;class $l extends ql{}$l.prototype.ValueTypeName="vector";class tc{constructor(t,e=-1,i,n=2500){this.name=t,this.tracks=i,this.duration=e,this.blendMode=n,this.uuid=yt(),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(ec(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(ql.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=[];Gl.flattenJSON(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!==ac[t])return void ac[t].push({onLoad:e,onProgress:i,onError:n});ac[t]=[],ac[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=ac[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=>{ic.add(t,e);const i=ac[t];delete ac[t];for(let t=0,n=i.length;t{const i=ac[t];if(void 0===i)throw this.manager.itemError(t),e;delete ac[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 lc extends sc{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=ic.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(),ic.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 cc 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 hc extends cc{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 uc=new Ie,dc=new ee,pc=new ee;class mc{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 fn,this._frameExtents=new Et(1,1),this._viewportCount=1,this._viewports=[new Zt(0,0,1,1)]}getViewportCount(){return this._viewportCount}getFrustum(){return this._frustum}updateMatrices(t){const e=this.camera,i=this.matrix;dc.setFromMatrixPosition(t.matrixWorld),e.position.copy(dc),pc.setFromMatrixPosition(t.target.matrixWorld),e.lookAt(pc),e.updateMatrixWorld(),uc.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this._frustum.setFromProjectionMatrix(uc),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 fc extends mc{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 gc extends cc{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 fc}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 vc=new Ie,xc=new ee,yc=new ee;class _c extends mc{constructor(){super(new rn(90,1,.5,500)),this.isPointLightShadow=!0,this._frameExtents=new Et(4,2),this._viewportCount=6,this._viewports=[new Zt(2,1,1,1),new Zt(0,1,1,1),new Zt(3,1,1,1),new Zt(1,1,1,1),new Zt(3,0,1,1),new Zt(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()),xc.setFromMatrixPosition(t.matrixWorld),i.position.copy(xc),yc.copy(i.position),yc.add(this._cubeDirections[e]),i.up.copy(this._cubeUps[e]),i.lookAt(yc),i.updateMatrixWorld(),n.makeTranslation(-xc.x,-xc.y,-xc.z),vc.multiplyMatrices(i.projectionMatrix,i.matrixWorldInverse),this._frustum.setFromProjectionMatrix(vc)}}class Mc extends cc{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 _c}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 bc extends mc{constructor(){super(new Cn(-5,5,5,-5,.5,500)),this.isDirectionalLightShadow=!0}}class wc extends cc{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 bc}dispose(){this.shadow.dispose()}copy(t){return super.copy(t),this.target=t.target.clone(),this.shadow=t.shadow.clone(),this}}class Sc extends cc{constructor(t,e){super(t,e),this.isAmbientLight=!0,this.type="AmbientLight"}}class Tc extends cc{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 Ac{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 Ec extends cc{constructor(t=new Ac,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 Cc extends sc{constructor(t){super(t),this.textures={}}load(t,e,i,n){const r=this,s=new oc(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=gi.fromType(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 Zt).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}}class Lc{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 Qc="\\[\\]\\.:\\/",$c=new RegExp("[\\[\\]\\.:\\/]","g"),th="[^\\[\\]\\.:\\/]",eh="[^"+Qc.replace("\\.","")+"]",ih=/((?:WC+[\/:])*)/.source.replace("WC",th),nh=/(WCOD+)?/.source.replace("WCOD",eh),rh=/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC",th),sh=/\.(WC+)(?:\[(.+)\])?/.source.replace("WC",th),ah=new RegExp("^"+ih+nh+rh+sh+"$"),oh=["material","materials","bones"];class lh{constructor(t,e,i){this.path=e,this.parsedPath=i||lh.parseTrackName(e),this.node=lh.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 lh.Composite(t,e,i):new lh(t,e,i)}static sanitizeNodeName(t){return t.replace(/\s/g,"_").replace($c,"")}static parseTrackName(t){const e=ah.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!==oh.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 hh=new Float32Array(1);class uh{constructor(t){"string"==typeof t&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),t=arguments[1]),this.value=t}clone(){return new uh(void 0===this.value.clone?this.value:this.value.clone())}}function dh(t,e){return t.distance-e.distance}function ph(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,Bh[256|t]=1024>>-e-14|32768,Uh[t]=-e-1,Uh[256|t]=-e-1):e<=15?(Bh[t]=e+15<<10,Bh[256|t]=e+15<<10|32768,Uh[t]=13,Uh[256|t]=13):e<128?(Bh[t]=31744,Bh[256|t]=64512,Uh[t]=24,Uh[256|t]=24):(Bh[t]=31744,Bh[256|t]=64512,Uh[t]=13,Uh[256|t]=13)}const kh=new Uint32Array(2048),Gh=new Uint32Array(64),Vh=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,kh[t]=e|i}for(let t=1024;t<2048;++t)kh[t]=939524096+(t-1024<<13);for(let t=1;t<31;++t)Gh[t]=t<<23;Gh[31]=1199570944,Gh[32]=2147483648;for(let t=33;t<63;++t)Gh[t]=2147483648+(t-32<<23);Gh[63]=3347054592;for(let t=1;t<64;++t)32!==t&&(Vh[t]=1024);"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=Sc,t.AmbientLightProbe=class extends Ec{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=tc,t.AnimationLoader=class extends sc{constructor(t){super(t)}load(t,e,i,n){const r=this,s=new oc(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 lh(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=Gl,t.ArcCurve=lo,t.ArrayCamera=Ws,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===Dh&&(Dh=new Pi,Dh.setAttribute("position",new wi([0,0,0,0,1,0],3)),Nh=new Io(0,.5,1,5,1),Nh.translate(0,-.5,0)),this.position.copy(e),this.line=new Xa(Dh,new Ga({color:n,toneMapped:!1})),this.line.matrixAutoUpdate=!1,this.add(this.line),this.cone=new Yi(Nh,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{Ih.set(t.z,0,-t.x).normalize();const e=Math.acos(t.y);this.quaternion.setFromAxisAngle(Ih,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=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 mh.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 _i(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 Ga({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 _i(i,1)),r.setAttribute("position",new _i(n,3)),super(r,new Ga({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&&Ph.setFromObject(this.object),Ph.isEmpty())return;const e=Ph.min,i=Ph.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=_i,t.BufferGeometry=Pi,t.BufferGeometryLoader=Pc,t.ByteType=1010,t.Cache=ic,t.Camera=nn,t.CameraHelper=class extends Za{constructor(t){const e=new Pi,i=new Ga({color:16777215,vertexColors:!0,toneMapped:!1}),n=[],r=[],s={},a=new Ht(16755200),o=new Ht(16711680),l=new Ht(43775),c=new Ht(16777215),h=new Ht(3355443);function u(t,e,i){d(t,i),d(e,i)}function d(t,e){n.push(0,0,0),r.push(e.r,e.g,e.b),void 0===s[t]&&(s[t]=[]),s[t].push(n.length/3-1)}u("n1","n2",a),u("n2","n4",a),u("n4","n3",a),u("n3","n1",a),u("f1","f2",a),u("f2","f4",a),u("f4","f3",a),u("f3","f1",a),u("n1","f1",a),u("n2","f2",a),u("n3","f3",a),u("n4","f4",a),u("p","n1",o),u("p","n2",o),u("p","n3",o),u("p","n4",o),u("u1","u2",l),u("u2","u3",l),u("u3","u1",l),u("c","t",c),u("p","c",h),u("cn1","cn2",h),u("cn3","cn4",h),u("cf1","cf2",h),u("cf3","cf4",h),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()}update(){const t=this.geometry,e=this.pointMap;Lh.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse),Rh("c",e,t,Lh,0,0,-1),Rh("t",e,t,Lh,0,0,1),Rh("n1",e,t,Lh,-1,-1,-1),Rh("n2",e,t,Lh,1,-1,-1),Rh("n3",e,t,Lh,-1,1,-1),Rh("n4",e,t,Lh,1,1,-1),Rh("f1",e,t,Lh,-1,-1,1),Rh("f2",e,t,Lh,1,-1,1),Rh("f3",e,t,Lh,-1,1,1),Rh("f4",e,t,Lh,1,1,1),Rh("u1",e,t,Lh,.7,1.1,-1),Rh("u2",e,t,Lh,-.7,1.1,-1),Rh("u3",e,t,Lh,0,2,-1),Rh("cf1",e,t,Lh,-1,0,1),Rh("cf2",e,t,Lh,1,0,1),Rh("cf3",e,t,Lh,0,-1,1),Rh("cf4",e,t,Lh,0,1,1),Rh("cn1",e,t,Lh,-1,0,-1),Rh("cn2",e,t,Lh,1,0,-1),Rh("cn3",e,t,Lh,0,-1,-1),Rh("cn4",e,t,Lh,0,1,-1),t.getAttribute("position").needsUpdate=!0}dispose(){this.geometry.dispose(),this.material.dispose()}},t.CanvasTexture=class extends Yt{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=Ro,t.CapsuleGeometry=Ro,t.CatmullRomCurve3=fo,t.CineonToneMapping=3,t.CircleBufferGeometry=Po,t.CircleGeometry=Po,t.ClampToEdgeWrapping=h,t.Clock=kc,t.Color=Ht,t.ColorKeyframeTrack=Jl,t.ColorManagement=Ot,t.CompressedTexture=so,t.CompressedTextureLoader=class extends sc{constructor(t){super(t)}load(t,e,i,n){const r=this,s=[],a=new so,o=new oc(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;e65504&&console.warn("THREE.DataUtils.toHalfFloat(): Value out of range."),t=_t(t,-65504,65504),Oh[0]=t;const e=Fh[0],i=e>>23&511;return Bh[i]+((8388607&e)>>Uh[i])}static fromHalfFloat(t){const e=t>>10;return Fh[0]=kh[Vh[e]+(1023&t)]+Gh[e],Oh[0]}},t.DecrementStencilOp=7683,t.DecrementWrapStencilOp=34056,t.DefaultLoadingManager=rc,t.DepthFormat=T,t.DepthStencilFormat=A,t.DepthTexture=Js,t.DirectionalLight=wc,t.DirectionalLightHelper=class extends ni{constructor(t,e,i){super(),this.light=t,this.light.updateMatrixWorld(),this.matrix=t.matrixWorld,this.matrixAutoUpdate=!1,this.color=i,void 0===e&&(e=1);let n=new Pi;n.setAttribute("position",new wi([-e,e,0,e,e,0,e,-e,0,-e,-e,0,-e,e,0],3));const r=new Ga({fog:!1,toneMapped:!1});this.lightPlane=new Xa(n,r),this.add(this.lightPlane),n=new Pi,n.setAttribute("position",new wi([0,0,0,0,0,1],3)),this.targetLine=new Xa(n,r),this.add(this.targetLine),this.update()}dispose(){this.lightPlane.geometry.dispose(),this.lightPlane.material.dispose(),this.targetLine.geometry.dispose(),this.targetLine.material.dispose()}update(){Th.setFromMatrixPosition(this.light.matrixWorld),Ah.setFromMatrixPosition(this.light.target.matrixWorld),Eh.subVectors(Ah,Th),this.lightPlane.lookAt(Ah),void 0!==this.color?(this.lightPlane.material.color.set(this.color),this.targetLine.material.color.set(this.color)):(this.lightPlane.material.color.copy(this.light.color),this.targetLine.material.color.copy(this.light.color)),this.targetLine.lookAt(Ah),this.targetLine.scale.z=Eh.length()}},t.DiscreteInterpolant=jl,t.DodecahedronBufferGeometry=zo,t.DodecahedronGeometry=zo,t.DoubleSide=2,t.DstAlphaFactor=206,t.DstColorFactor=208,t.DynamicCopyUsage=35050,t.DynamicDrawUsage=35048,t.DynamicReadUsage=35049,t.EdgesGeometry=ko,t.EllipseCurve=oo,t.EqualDepth=4,t.EqualStencilFunc=514,t.EquirectangularReflectionMapping=a,t.EquirectangularRefractionMapping=o,t.Euler=Ve,t.EventDispatcher=mt,t.ExtrudeBufferGeometry=gl,t.ExtrudeGeometry=gl,t.FileLoader=oc,t.FlatShading=1,t.Float16BufferAttribute=class extends _i{constructor(t,e,i){super(new Uint16Array(t),e,i),this.isFloat16BufferAttribute=!0}},t.Float32BufferAttribute=wi,t.Float64BufferAttribute=class extends _i{constructor(t,e,i){super(new Float64Array(t),e,i)}},t.FloatType=M,t.Fog=ta,t.FogExp2=$s,t.Font=function(){console.error("THREE.Font has been moved to /examples/jsm/loaders/FontLoader.js")},t.FontLoader=function(){console.error("THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js")},t.FramebufferTexture=class extends Yt{constructor(t,e,i){super({width:t,height:e}),this.isFramebufferTexture=!0,this.format=i,this.magFilter=d,this.minFilter=d,this.generateMipmaps=!1,this.needsUpdate=!0}},t.FrontSide=0,t.Frustum=fn,t.GLBufferAttribute=class{constructor(t,e,i,n,r){this.isGLBufferAttribute=!0,this.buffer=t,this.type=e,this.itemSize=i,this.elementSize=n,this.count=r,this.version=0}set needsUpdate(t){!0===t&&this.version++}setBuffer(t){return this.buffer=t,this}setType(t,e){return this.type=t,this.elementSize=e,this}setItemSize(t){return this.itemSize=t,this}setCount(t){return this.count=t,this}},t.GLSL1="100",t.GLSL3=dt,t.GreaterDepth=6,t.GreaterEqualDepth=5,t.GreaterEqualStencilFunc=518,t.GreaterStencilFunc=516,t.GridHelper=class extends Za{constructor(t=10,e=10,i=4473924,n=8947848){i=new Ht(i),n=new Ht(n);const r=e/2,s=t/e,a=t/2,o=[],l=[];for(let t=0,c=0,h=-a;t<=e;t++,h+=s){o.push(-a,0,h,a,0,h),o.push(h,0,-a,h,0,a);const e=t===r?i:n;e.toArray(l,c),c+=3,e.toArray(l,c),c+=3,e.toArray(l,c),c+=3,e.toArray(l,c),c+=3}const c=new Pi;c.setAttribute("position",new wi(o,3)),c.setAttribute("color",new wi(l,3));super(c,new Ga({vertexColors:!0,toneMapped:!1})),this.type="GridHelper"}},t.Group=js,t.HalfFloatType=b,t.HemisphereLight=hc,t.HemisphereLightHelper=class extends ni{constructor(t,e,i){super(),this.light=t,this.light.updateMatrixWorld(),this.matrix=t.matrixWorld,this.matrixAutoUpdate=!1,this.color=i;const n=new yl(e);n.rotateY(.5*Math.PI),this.material=new vi({wireframe:!0,fog:!1,toneMapped:!1}),void 0===this.color&&(this.material.vertexColors=!0);const r=n.getAttribute("position"),s=new Float32Array(3*r.count);n.setAttribute("color",new _i(s,3)),this.add(new Yi(n,this.material)),this.update()}dispose(){this.children[0].geometry.dispose(),this.children[0].material.dispose()}update(){const t=this.children[0];if(void 0!==this.color)this.material.color.set(this.color);else{const e=t.geometry.getAttribute("color");wh.copy(this.light.color),Sh.copy(this.light.groundColor);for(let t=0,i=e.count;t0){const i=new nc(e);r=new lc(i),r.setCrossOrigin(this.crossOrigin);for(let e=0,i=t.length;e0){n=new lc(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=pl.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 Go,l.curves=o.curves,c.push(l),c;let h=!r(s[0].getPoints());h=t?!h:h;const u=[],d=[];let p,m,f=[],g=0;d[g]=void 0,f[g]=[];for(let e=0,i=s.length;e1){let t=!1,e=0;for(let t=0,e=d.length;t0&&!1===t&&(f=u)}for(let t=0,e=d.length;t=t.HAVE_CURRENT_DATA&&(this.needsUpdate=!0)}},t.WebGL1Renderer=Qs,t.WebGL3DRenderTarget=class extends Kt{constructor(t,e,i){super(t,e),this.isWebGL3DRenderTarget=!0,this.depth=i,this.texture=new $t(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 Qt(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]+xt[t>>16&255]+xt[t>>24&255]+"-"+xt[255&e]+xt[e>>8&255]+"-"+xt[e>>16&15|64]+xt[e>>24&255]+"-"+xt[63&i|128]+xt[i>>8&255]+"-"+xt[i>>16&255]+xt[i>>24&255]+xt[255&n]+xt[n>>8&255]+xt[n>>16&255]+xt[n>>24&255]).toLowerCase()}function St(t,e,i){return Math.max(e,Math.min(i,t))}function wt(t,e){return(t%e+e)%e}function Tt(t,e,i){return(1-i)*t+i*e}function At(t){return 0==(t&t-1)&&0!==t}function Et(t){return Math.pow(2,Math.ceil(Math.log(t)/Math.LN2))}function Ct(t){return Math.pow(2,Math.floor(Math.log(t)/Math.LN2))}function Lt(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 Rt(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 Pt=Object.freeze({__proto__:null,DEG2RAD:yt,RAD2DEG:Mt,ceilPowerOfTwo:Et,clamp:St,damp:function(t,e,i,n){return Tt(t,e,1-Math.exp(-i*n))},degToRad:function(t){return t*yt},denormalize:Lt,euclideanModulo:wt,floorPowerOfTwo:Ct,generateUUID:bt,inverseLerp:function(t,e,i){return t!==e?(i-t)/(e-t):0},isPowerOfTwo:At,lerp:Tt,mapLinear:function(t,e,i,n,r){return n+(t-e)*(r-n)/(i-e)},normalize:Rt,pingpong:function(t,e=1){return e-Math.abs(wt(t,2*e)-e)},radToDeg:function(t){return t*Mt},randFloat:function(t,e){return t+Math.random()*(e-t)},randFloatSpread:function(t){return t*(.5-Math.random())},randInt:function(t,e){return t+Math.floor(Math.random()*(e-t+1))},seededRandom:function(t){void 0!==t&&(_t=t);let e=_t+=1831565813;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296},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)}},smootherstep:function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*t*(t*(6*t-15)+10)},smoothstep:function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*(3-2*t)}});class It{constructor(t=0,e=0){It.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 Dt{constructor(){Dt.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(Nt.makeScale(t,e)),this}rotate(t){return this.premultiply(Nt.makeRotation(-t)),this}translate(t,e){return this.premultiply(Nt.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 Nt=new Dt;function Ot(t){for(let e=t.length-1;e>=0;--e)if(t[e]>=65535)return!0;return!1}const zt={Int8Array:Int8Array,Uint8Array:Uint8Array,Uint8ClampedArray:Uint8ClampedArray,Int16Array:Int16Array,Uint16Array:Uint16Array,Int32Array:Int32Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array};function Ut(t,e){return new zt[t](e)}function Bt(t){return document.createElementNS("http://www.w3.org/1999/xhtml",t)}function Ft(t){return t<.04045?.0773993808*t:Math.pow(.9478672986*t+.0521327014,2.4)}function kt(t){return t<.0031308?12.92*t:1.055*Math.pow(t,.41666)-.055}const Gt={[ut]:{[dt]:Ft},[dt]:{[ut]:kt}},Vt={legacyMode:!0,get workingColorSpace(){return dt},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(Gt[e]&&void 0!==Gt[e][i]){const n=Gt[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)}},Ht={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},Wt={r:0,g:0,b:0},jt={h:0,s:0,l:0},qt={h:0,s:0,l:0};function Xt(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 Yt(t,e){return e.r=t.r,e.g=t.g,e.b=t.b,e}class Zt{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=ut){return t=Math.floor(t),this.r=(t>>16&255)/255,this.g=(t>>8&255)/255,this.b=(255&t)/255,Vt.toWorkingColorSpace(this,e),this}setRGB(t,e,i,n=Vt.workingColorSpace){return this.r=t,this.g=e,this.b=i,Vt.toWorkingColorSpace(this,n),this}setHSL(t,e,i,n=Vt.workingColorSpace){if(t=wt(t,1),e=St(e,0,1),i=St(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=Xt(r,n,t+1/3),this.g=Xt(r,n,t),this.b=Xt(r,n,t-1/3)}return Vt.toWorkingColorSpace(this,n),this}setStyle(t,e=ut){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,Vt.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,Vt.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,Vt.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,Vt.toWorkingColorSpace(this,e),this}return t&&t.length>0?this.setColorName(t,e):this}setColorName(t,e=ut){const i=Ht[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=Ft(t.r),this.g=Ft(t.g),this.b=Ft(t.b),this}copyLinearToSRGB(t){return this.r=kt(t.r),this.g=kt(t.g),this.b=kt(t.b),this}convertSRGBToLinear(){return this.copySRGBToLinear(this),this}convertLinearToSRGB(){return this.copyLinearToSRGB(this),this}getHex(t=ut){return Vt.fromWorkingColorSpace(Yt(this,Wt),t),St(255*Wt.r,0,255)<<16^St(255*Wt.g,0,255)<<8^St(255*Wt.b,0,255)<<0}getHexString(t=ut){return("000000"+this.getHex(t).toString(16)).slice(-6)}getHSL(t,e=Vt.workingColorSpace){Vt.fromWorkingColorSpace(Yt(this,Wt),e);const i=Wt.r,n=Wt.g,r=Wt.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=Bt("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;t0&&(i.userData=this.userData),e||(t.textures[this.uuid]=i),i}dispose(){this.dispatchEvent({type:"dispose"})}transformUv(t){if(this.mapping!==n)return t;if(t.applyMatrix3(this.matrix),t.x<0||t.x>1)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)}}ee.DEFAULT_IMAGE=null,ee.DEFAULT_MAPPING=n,ee.DEFAULT_ANISOTROPY=1;class ie{constructor(t=0,e=0,i=0,n=1){ie.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(St(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 oe{constructor(t=0,e=0,i=0){oe.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(ce.setFromEuler(t))}applyAxisAngle(t,e){return this.applyQuaternion(ce.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 le.copy(this).projectOnVector(t),this.sub(le)}reflect(t){return this.sub(le.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(St(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 le=new oe,ce=new ae;class he{constructor(t=new oe(1/0,1/0,1/0),e=new oe(-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,de),de.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(ye),Me.subVectors(this.max,ye),me.subVectors(t.a,ye),fe.subVectors(t.b,ye),ge.subVectors(t.c,ye),ve.subVectors(fe,me),xe.subVectors(ge,fe),_e.subVectors(me,ge);let e=[0,-ve.z,ve.y,0,-xe.z,xe.y,0,-_e.z,_e.y,ve.z,0,-ve.x,xe.z,0,-xe.x,_e.z,0,-_e.x,-ve.y,ve.x,0,-xe.y,xe.x,0,-_e.y,_e.x,0];return!!we(e,me,fe,ge,Me)&&(e=[1,0,0,0,1,0,0,0,1],!!we(e,me,fe,ge,Me)&&(be.crossVectors(ve,xe),e=[be.x,be.y,be.z],we(e,me,fe,ge,Me)))}clampPoint(t,e){return e.copy(t).clamp(this.min,this.max)}distanceToPoint(t){return de.copy(t).clamp(this.min,this.max).sub(t).length()}getBoundingSphere(t){return this.getCenter(t.center),t.radius=.5*this.getSize(de).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()||(ue[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(t),ue[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(t),ue[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(t),ue[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(t),ue[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(t),ue[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(t),ue[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(t),ue[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(t),this.setFromPoints(ue)),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 ue=[new oe,new oe,new oe,new oe,new oe,new oe,new oe,new oe],de=new oe,pe=new he,me=new oe,fe=new oe,ge=new oe,ve=new oe,xe=new oe,_e=new oe,ye=new oe,Me=new oe,be=new oe,Se=new oe;function we(t,e,i,n,r){for(let s=0,a=t.length-3;s<=a;s+=3){Se.fromArray(t,s);const a=r.x*Math.abs(Se.x)+r.y*Math.abs(Se.y)+r.z*Math.abs(Se.z),o=e.dot(Se),l=i.dot(Se),c=n.dot(Se);if(Math.max(-Math.max(o,l,c),Math.min(o,l,c))>a)return!1}return!0}const Te=new he,Ae=new oe,Ee=new oe;class Ce{constructor(t=new oe,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):Te.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;Ae.subVectors(t,this.center);const e=Ae.lengthSq();if(e>this.radius*this.radius){const t=Math.sqrt(e),i=.5*(t-this.radius);this.center.addScaledVector(Ae,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):(Ee.subVectors(t.center,this.center).setLength(t.radius),this.expandByPoint(Ae.copy(t.center).add(Ee)),this.expandByPoint(Ae.copy(t.center).sub(Ee))),this)}equals(t){return t.center.equals(this.center)&&t.radius===this.radius}clone(){return(new this.constructor).copy(this)}}const Le=new oe,Re=new oe,Pe=new oe,Ie=new oe,De=new oe,Ne=new oe,Oe=new oe;class ze{constructor(t=new oe,e=new oe(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,Le)),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=Le.subVectors(t,this.origin).dot(this.direction);return e<0?this.origin.distanceToSquared(t):(Le.copy(this.direction).multiplyScalar(e).add(this.origin),Le.distanceToSquared(t))}distanceSqToSegment(t,e,i,n){Re.copy(t).add(e).multiplyScalar(.5),Pe.copy(e).sub(t).normalize(),Ie.copy(this.origin).sub(Re);const r=.5*t.distanceTo(e),s=-this.direction.dot(Pe),a=Ie.dot(this.direction),o=-Ie.dot(Pe),l=Ie.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(Pe).multiplyScalar(u).add(Re),d}intersectSphere(t,e){Le.subVectors(t.center,this.origin);const i=Le.dot(this.direction),n=Le.dot(Le)-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,Le)}intersectTriangle(t,e,i,n,r){De.subVectors(e,t),Ne.subVectors(i,t),Oe.crossVectors(De,Ne);let s,a=this.direction.dot(Oe);if(a>0){if(n)return null;s=1}else{if(!(a<0))return null;s=-1,a=-a}Ie.subVectors(this.origin,t);const o=s*this.direction.dot(Ne.crossVectors(Ie,Ne));if(o<0)return null;const l=s*this.direction.dot(De.cross(Ie));if(l<0)return null;if(o+l>a)return null;const c=-s*Ie.dot(Oe);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 Ue{constructor(){Ue.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 Ue).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/Be.setFromMatrixColumn(t,0).length(),r=1/Be.setFromMatrixColumn(t,1).length(),s=1/Be.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(ke,t,Ge)}lookAt(t,e,i){const n=this.elements;return We.subVectors(t,e),0===We.lengthSq()&&(We.z=1),We.normalize(),Ve.crossVectors(i,We),0===Ve.lengthSq()&&(1===Math.abs(i.z)?We.x+=1e-4:We.z+=1e-4,We.normalize(),Ve.crossVectors(i,We)),Ve.normalize(),He.crossVectors(We,Ve),n[0]=Ve.x,n[4]=He.x,n[8]=We.x,n[1]=Ve.y,n[5]=He.y,n[9]=We.y,n[2]=Ve.z,n[6]=He.z,n[10]=We.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=Be.set(n[0],n[1],n[2]).length();const s=Be.set(n[4],n[5],n[6]).length(),a=Be.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],Fe.copy(this);const o=1/r,l=1/s,c=1/a;return Fe.elements[0]*=o,Fe.elements[1]*=o,Fe.elements[2]*=o,Fe.elements[4]*=l,Fe.elements[5]*=l,Fe.elements[6]*=l,Fe.elements[8]*=c,Fe.elements[9]*=c,Fe.elements[10]*=c,e.setFromRotationMatrix(Fe),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 Be=new oe,Fe=new Ue,ke=new oe(0,0,0),Ge=new oe(1,1,1),Ve=new oe,He=new oe,We=new oe,je=new Ue,qe=new ae;class Xe{constructor(t=0,e=0,i=0,n=Xe.DEFAULT_ORDER){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(St(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(-St(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(St(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(-St(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(St(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(-St(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 je.makeRotationFromQuaternion(t),this.setFromRotationMatrix(je,e,i)}setFromVector3(t,e=this._order){return this.set(t.x,t.y,t.z,e)}reorder(t){return qe.setFromEuler(this),this.setFromQuaternion(qe,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}}Xe.DEFAULT_ORDER="XYZ";class Ye{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&&(i=i.concat(r))}return i}getWorldPosition(t){return this.updateWorldMatrix(!0,!1),t.setFromMatrixPosition(this.matrixWorld)}getWorldQuaternion(t){return this.updateWorldMatrix(!0,!1),this.matrixWorld.decompose(ti,t,ei),t}getWorldScale(t){return this.updateWorldMatrix(!0,!1),this.matrixWorld.decompose(ti,ii,t),t}getWorldDirection(t){this.updateWorldMatrix(!0,!1);const e=this.matrixWorld.elements;return t.set(e[8],e[9],e[10]).normalize()}raycast(){}traverse(t){t(this);const e=this.children;for(let i=0,n=e.length;i0&&(n.userData=this.userData),n.layers=this.layers.mask,n.matrix=this.matrix.toArray(),!1===this.matrixAutoUpdate&&(n.matrixAutoUpdate=!1),this.isInstancedMesh&&(n.type="InstancedMesh",n.count=this.count,n.instanceMatrix=this.instanceMatrix.toJSON(),null!==this.instanceColor&&(n.instanceColor=this.instanceColor.toJSON())),this.isScene)this.background&&(this.background.isColor?n.background=this.background.toJSON():this.background.isTexture&&(n.background=this.background.toJSON(t).uuid)),this.environment&&this.environment.isTexture&&!0!==this.environment.isRenderTargetTexture&&(n.environment=this.environment.toJSON(t).uuid);else if(this.isMesh||this.isLine||this.isPoints){n.geometry=r(t.geometries,this.geometry);const e=this.geometry.parameters;if(void 0!==e&&void 0!==e.shapes){const i=e.shapes;if(Array.isArray(i))for(let e=0,n=i.length;e0){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){ci.subVectors(n,e),hi.subVectors(i,e),ui.subVectors(t,e);const s=ci.dot(ci),a=ci.dot(hi),o=ci.dot(ui),l=hi.dot(hi),c=hi.dot(ui),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,di),di.x>=0&&di.y>=0&&di.x+di.y<=1}static getUV(t,e,i,n,r,s,a,o){return this.getBarycoord(t,e,i,n,di),o.set(0,0),o.addScaledVector(r,di.x),o.addScaledVector(s,di.y),o.addScaledVector(a,di.z),o}static isFrontFacing(t,e,i,n){return ci.subVectors(i,e),hi.subVectors(t,e),ci.cross(hi).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 ci.subVectors(this.c,this.b),hi.subVectors(this.a,this.b),.5*ci.cross(hi).length()}getMidpoint(t){return t.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)}getNormal(t){return _i.getNormal(this.a,this.b,this.c,t)}getPlane(t){return t.setFromCoplanarPoints(this.a,this.b,this.c)}getBarycoord(t,e){return _i.getBarycoord(t,this.a,this.b,this.c,e)}getUV(t,e,i,n,r){return _i.getUV(t,this.a,this.b,this.c,e,i,n,r)}containsPoint(t){return _i.containsPoint(t,this.a,this.b,this.c)}isFrontFacing(t){return _i.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;pi.subVectors(n,i),mi.subVectors(r,i),gi.subVectors(t,i);const o=pi.dot(gi),l=mi.dot(gi);if(o<=0&&l<=0)return e.copy(i);vi.subVectors(t,n);const c=pi.dot(vi),h=mi.dot(vi);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(pi,s);xi.subVectors(t,r);const d=pi.dot(xi),p=mi.dot(xi);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(mi,a);const f=c*p-d*h;if(f<=0&&h-c>=0&&d-p>=0)return fi.subVectors(r,n),a=(h-c)/(h-c+(d-p)),e.copy(n).addScaledVector(fi,a);const g=1/(f+m+u);return s=m*g,a=u*g,e.copy(i).addScaledVector(pi,s).addScaledVector(mi,a)}equals(t){return t.a.equals(this.a)&&t.b.equals(this.b)&&t.c.equals(this.c)}}let yi=0;class Mi extends vt{constructor(){super(),this.isMaterial=!0,Object.defineProperty(this,"id",{value:yi++}),this.uuid=bt(),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=pt,this.stencilZFail=pt,this.stencilZPass=pt,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.forceSinglePass=!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.forceSinglePass&&(i.forceSinglePass=this.forceSinglePass),!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),Object.keys(this.userData).length>0&&(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.forceSinglePass=t.forceSinglePass,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 bi extends Mi{constructor(t){super(),this.isMeshBasicMaterial=!0,this.type="MeshBasicMaterial",this.color=new Zt(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 Si=new oe,wi=new It;class Ti{constructor(t,e,i=!1){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=i,this.usage=mt,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:Zi.clone(),object:t}}(t,e,i,n,ki,Gi,Vi,Yi);if(c){r&&(ji.fromBufferAttribute(r,a),qi.fromBufferAttribute(r,o),Xi.fromBufferAttribute(r,l),c.uv=_i.getUV(Yi,ki,Gi,Vi,ji,qi,Xi,new It)),s&&(ji.fromBufferAttribute(s,a),qi.fromBufferAttribute(s,o),Xi.fromBufferAttribute(s,l),c.uv2=_i.getUV(Yi,ki,Gi,Vi,ji,qi,Xi,new It));const t={a:a,b:o,c:l,normal:new oe,materialIndex:0};_i.getNormal(ki,Gi,Vi,t.normal),c.face=t}return c}class $i extends zi{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 oe;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 sn extends li{constructor(){super(),this.isCamera=!0,this.type="Camera",this.matrixWorldInverse=new Ue,this.projectionMatrix=new Ue,this.projectionMatrixInverse=new Ue}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 an extends sn{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*Mt*Math.atan(e),this.updateProjectionMatrix()}getFocalLength(){const t=Math.tan(.5*yt*this.fov);return.5*this.getFilmHeight()/t}getEffectiveFOV(){return 2*Mt*Math.atan(Math.tan(.5*yt*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*yt*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 on=-90;class ln extends li{constructor(t,e,i){super(),this.type="CubeCamera",this.renderTarget=i;const n=new an(on,1,t,e);n.layers=this.layers,n.up.set(0,1,0),n.lookAt(1,0,0),this.add(n);const r=new an(on,1,t,e);r.layers=this.layers,r.up.set(0,1,0),r.lookAt(-1,0,0),this.add(r);const s=new an(on,1,t,e);s.layers=this.layers,s.up.set(0,0,-1),s.lookAt(0,1,0),this.add(s);const a=new an(on,1,t,e);a.layers=this.layers,a.up.set(0,0,1),a.lookAt(0,-1,0),this.add(a);const o=new an(on,1,t,e);o.layers=this.layers,o.up.set(0,1,0),o.lookAt(0,0,1),this.add(o);const l=new an(on,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 cn extends ee{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 hn extends ne{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 cn(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 $i(5,5,5),r=new rn({name:"CubemapFromEquirect",uniforms:Qi(i.uniforms),vertexShader:i.vertexShader,fragmentShader:i.fragmentShader,side:1,blending:0});r.uniforms.tEquirect.value=e;const s=new Ji(n,r),a=e.minFilter;e.minFilter===v&&(e.minFilter=f);return new ln(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 un=new oe,dn=new oe,pn=new Dt;class mn{constructor(t=new oe(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=un.subVectors(i,e).cross(dn.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(un),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||pn.getNormalMatrix(t),n=this.coplanarPoint(un).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 fn=new Ce,gn=new oe;class vn{constructor(t=new mn,e=new mn,i=new mn,n=new mn,r=new mn,s=new mn){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(),fn.copy(e.boundingSphere).applyMatrix4(t.matrixWorld),this.intersectsSphere(fn)}intersectsSprite(t){return fn.center.set(0,0,0),fn.radius=.7071067811865476,fn.applyMatrix4(t.matrixWorld),this.intersectsSphere(fn)}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,gn.y=n.normal.y>0?t.max.y:t.min.y,gn.z=n.normal.z>0?t.max.z:t.min.z,n.distanceToPoint(gn)<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 xn(){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 _n(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, 0.0556434,\n\t\t-1.5371385, 1.8760108, -0.2040259,\n\t\t-0.4985314, 0.0415560, 1.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\thighp vec2 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( 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}",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 *= ( 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 *= ( 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 *= ( 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 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\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\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",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",shadowmap_vertex:"#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\tvec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#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#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( 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; }",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}"},bn={common:{diffuse:{value:new Zt(16777215)},opacity:{value:1},map:{value:null},uvTransform:{value:new Dt},uv2Transform:{value:new Dt},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 It(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 Zt(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 Zt(16777215)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},alphaMap:{value:null},alphaTest:{value:0},uvTransform:{value:new Dt}},sprite:{diffuse:{value:new Zt(16777215)},opacity:{value:1},center:{value:new It(.5,.5)},rotation:{value:0},map:{value:null},alphaMap:{value:null},alphaTest:{value:0},uvTransform:{value:new Dt}}},Sn={basic:{uniforms:tn([bn.common,bn.specularmap,bn.envmap,bn.aomap,bn.lightmap,bn.fog]),vertexShader:Mn.meshbasic_vert,fragmentShader:Mn.meshbasic_frag},lambert:{uniforms:tn([bn.common,bn.specularmap,bn.envmap,bn.aomap,bn.lightmap,bn.emissivemap,bn.bumpmap,bn.normalmap,bn.displacementmap,bn.fog,bn.lights,{emissive:{value:new Zt(0)}}]),vertexShader:Mn.meshlambert_vert,fragmentShader:Mn.meshlambert_frag},phong:{uniforms:tn([bn.common,bn.specularmap,bn.envmap,bn.aomap,bn.lightmap,bn.emissivemap,bn.bumpmap,bn.normalmap,bn.displacementmap,bn.fog,bn.lights,{emissive:{value:new Zt(0)},specular:{value:new Zt(1118481)},shininess:{value:30}}]),vertexShader:Mn.meshphong_vert,fragmentShader:Mn.meshphong_frag},standard:{uniforms:tn([bn.common,bn.envmap,bn.aomap,bn.lightmap,bn.emissivemap,bn.bumpmap,bn.normalmap,bn.displacementmap,bn.roughnessmap,bn.metalnessmap,bn.fog,bn.lights,{emissive:{value:new Zt(0)},roughness:{value:1},metalness:{value:0},envMapIntensity:{value:1}}]),vertexShader:Mn.meshphysical_vert,fragmentShader:Mn.meshphysical_frag},toon:{uniforms:tn([bn.common,bn.aomap,bn.lightmap,bn.emissivemap,bn.bumpmap,bn.normalmap,bn.displacementmap,bn.gradientmap,bn.fog,bn.lights,{emissive:{value:new Zt(0)}}]),vertexShader:Mn.meshtoon_vert,fragmentShader:Mn.meshtoon_frag},matcap:{uniforms:tn([bn.common,bn.bumpmap,bn.normalmap,bn.displacementmap,bn.fog,{matcap:{value:null}}]),vertexShader:Mn.meshmatcap_vert,fragmentShader:Mn.meshmatcap_frag},points:{uniforms:tn([bn.points,bn.fog]),vertexShader:Mn.points_vert,fragmentShader:Mn.points_frag},dashed:{uniforms:tn([bn.common,bn.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:Mn.linedashed_vert,fragmentShader:Mn.linedashed_frag},depth:{uniforms:tn([bn.common,bn.displacementmap]),vertexShader:Mn.depth_vert,fragmentShader:Mn.depth_frag},normal:{uniforms:tn([bn.common,bn.bumpmap,bn.normalmap,bn.displacementmap,{opacity:{value:1}}]),vertexShader:Mn.meshnormal_vert,fragmentShader:Mn.meshnormal_frag},sprite:{uniforms:tn([bn.sprite,bn.fog]),vertexShader:Mn.sprite_vert,fragmentShader:Mn.sprite_frag},background:{uniforms:{uvTransform:{value:new Dt},t2D:{value:null},backgroundIntensity:{value:1}},vertexShader:Mn.background_vert,fragmentShader:Mn.background_frag},backgroundCube:{uniforms:{envMap:{value:null},flipEnvMap:{value:-1},backgroundBlurriness:{value:0},backgroundIntensity:{value:1}},vertexShader:Mn.backgroundCube_vert,fragmentShader:Mn.backgroundCube_frag},cube:{uniforms:{tCube:{value:null},tFlip:{value:-1},opacity:{value:1}},vertexShader:Mn.cube_vert,fragmentShader:Mn.cube_frag},equirect:{uniforms:{tEquirect:{value:null}},vertexShader:Mn.equirect_vert,fragmentShader:Mn.equirect_frag},distanceRGBA:{uniforms:tn([bn.common,bn.displacementmap,{referencePosition:{value:new oe},nearDistance:{value:1},farDistance:{value:1e3}}]),vertexShader:Mn.distanceRGBA_vert,fragmentShader:Mn.distanceRGBA_frag},shadow:{uniforms:tn([bn.lights,bn.fog,{color:{value:new Zt(0)},opacity:{value:1}}]),vertexShader:Mn.shadow_vert,fragmentShader:Mn.shadow_frag}};Sn.physical={uniforms:tn([Sn.standard.uniforms,{clearcoat:{value:0},clearcoatMap:{value:null},clearcoatRoughness:{value:0},clearcoatRoughnessMap:{value:null},clearcoatNormalScale:{value:new It(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 Zt(0)},sheenColorMap:{value:null},sheenRoughness:{value:1},sheenRoughnessMap:{value:null},transmission:{value:0},transmissionMap:{value:null},transmissionSamplerSize:{value:new It},transmissionSamplerMap:{value:null},thickness:{value:0},thicknessMap:{value:null},attenuationDistance:{value:0},attenuationColor:{value:new Zt(0)},specularIntensity:{value:1},specularIntensityMap:{value:null},specularColor:{value:new Zt(1,1,1)},specularColorMap:{value:null}}]),vertexShader:Mn.meshphysical_vert,fragmentShader:Mn.meshphysical_frag};const wn={r:0,b:0,g:0};function Tn(t,e,i,n,r,s,a){const o=new Zt(0);let c,h,u=!0===s?0:1,d=null,p=0,m=null;function f(e,i){e.getRGB(wn,en(t)),n.buffers.color.setClear(wn.r,wn.g,wn.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 Ji(new $i(1,1,1),new rn({name:"BackgroundCubeMaterial",uniforms:Qi(Sn.backgroundCube.uniforms),vertexShader:Sn.backgroundCube.vertexShader,fragmentShader:Sn.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,h.material.toneMapped=g.encoding!==ht,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 Ji(new yn(2,2),new rn({name:"BackgroundMaterial",uniforms:Qi(Sn.background.uniforms),vertexShader:Sn.background.vertexShader,fragmentShader:Sn.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,c.material.toneMapped=g.encoding!==ht,!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 An(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;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 Ln(t){const e=this;let i=null,n=0,r=!1,s=!1;const a=new mn,o=new Dt,l={value:null,needsUpdate:!1};function c(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);e.numPlanes=n,e.numIntersection=0}();else{const t=s?0:n,e=4*t;let r=m.clippingState||null;l.value=r,r=c(u,o,e,h);for(let t=0;t!==e;++t)r[t]=i[t];m.clippingState=r,this.numIntersection=d?this.numPlanes:0,this.numPlanes+=t}}}function Rn(t){let e=new WeakMap;function i(t,e){return e===a?t.mapping=r:e===o&&(t.mapping=s),t}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(r){if(r&&r.isTexture&&!1===r.isRenderTargetTexture){const s=r.mapping;if(s===a||s===o){if(e.has(r)){return i(e.get(r).texture,r.mapping)}{const s=r.image;if(s&&s.height>0){const a=new hn(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 Pn extends sn{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 In=[.125,.215,.35,.446,.526,.582],Dn=20,Nn=new Pn,On=new Zt;let zn=null;const Un=(1+Math.sqrt(5))/2,Bn=1/Un,Fn=[new oe(1,1,1),new oe(-1,1,1),new oe(1,1,-1),new oe(-1,1,-1),new oe(0,Un,Bn),new oe(0,Un,-Bn),new oe(Bn,0,Un),new oe(-Bn,0,Un),new oe(Un,Bn,0),new oe(-Un,Bn,0)];class kn{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){zn=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=Wn(),this._compileMaterial(this._cubemapMaterial))}compileEquirectangularShader(){null===this._equirectMaterial&&(this._equirectMaterial=Hn(),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=In[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 zi;y.setAttribute("position",new Ti(v,m)),y.setAttribute("uv",new Ti(x,f)),y.setAttribute("faceIndex",new Ti(_,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(Dn),r=new oe(0,1,0),s=new rn({name:"SphericalGaussianBlur",defines:{n:Dn,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:jn(),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});return s}(n,t,e)}return n}_compileMaterial(t){const e=new Ji(this._lodPlanes[0],t);this._renderer.compile(e,Nn)}_sceneToCubeUV(t,e,i,n){const r=new an(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(On),o.toneMapping=0,o.autoClear=!1;const h=new bi({name:"PMREM.Background",side:1,depthWrite:!1,depthTest:!1}),u=new Ji(new $i,h);let d=!1;const p=t.background;p?p.isColor&&(h.color.copy(p),t.background=null,d=!0):(h.color.copy(On),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;Vn(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=Wn()),this._cubemapMaterial.uniforms.flipEnvMap.value=!1===t.isRenderTargetTexture?-1:1):null===this._equirectMaterial&&(this._equirectMaterial=Hn());const a=n?this._cubemapMaterial:this._equirectMaterial,o=new Ji(this._lodPlanes[0],a);a.uniforms.envMap.value=t;const l=this._cubeSize;Vn(e,0,0,3*l,2*l),i.setRenderTarget(e),i.render(o,Nn)}_applyPMREM(t){const e=this._renderer,i=e.autoClear;e.autoClear=!1;for(let e=1;eDn&&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,Nn)}}function Gn(t,e,i){const n=new ne(t,e,i);return n.texture.mapping=l,n.texture.name="PMREM.cubeUv",n.scissorTest=!0,n}function Vn(t,e,i,n,r){t.viewport.set(e,i,n,r),t.scissor.set(e,i,n,r)}function Hn(){return new rn({name:"EquirectangularToCubeUV",uniforms:{envMap:{value:null}},vertexShader:jn(),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 Wn(){return new rn({name:"CubemapToCubeUV",uniforms:{envMap:{value:null},flipEnvMap:{value:-1}},vertexShader:jn(),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 jn(){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 qn(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 kn(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 re(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=sr[r];if(void 0===s&&(s=new Float32Array(r),sr[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 ur(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 ls(t,e){const i=function(t){switch(t){case ct:return["Linear","( value )"];case ht: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 cs(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 hs(t){return""!==t}function us(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 ds(t,e){return t.replace(/NUM_CLIPPING_PLANES/g,e.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g,e.numClippingPlanes-e.numClipIntersection)}const ps=/^[ \t]*#include +<([\w\d./]+)>/gm;function ms(t){return t.replace(ps,fs)}function fs(t,e){const i=Mn[e];if(void 0===i)throw new Error("Can not resolve #include <"+e+">");return ms(i)}const gs=/#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 vs(t){return t.replace(gs,xs)}function xs(t,e,i,n){let r="";for(let t=parseInt(e);t0&&(_+="\n"),y=[g,v].filter(hs).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(hs).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 "+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?Mn.tonemapping_pars_fragment:"",0!==i.toneMapping?cs("toneMapping",i.toneMapping):"",i.dithering?"#define DITHERING":"",i.opaque?"#define OPAQUE":"",Mn.encodings_pars_fragment,ls("linearToOutputTexel",i.outputEncoding),i.useDepthPacking?"#define DEPTH_PACKING "+i.depthPacking:"","\n"].filter(hs).join("\n")),c=ms(c),c=us(c,i),c=ds(c,i),h=ms(h),h=us(h,i),h=ds(h,i),c=vs(c),h=vs(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===ft?"":"layout(location = 0) out highp vec4 pc_fragColor;",i.glslVersion===ft?"":"#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=ss(a,35633,M+_+c),w=ss(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=os(a,S,"vertex"),i=os(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 rs(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:ct,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===ht,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=Sn[e];i=nn.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){const n=t.get(e);let r;return void 0===n?(r=new Cs,t.set(e,[r])):i>=n.length?(r=new Cs,n.push(r)):r=n[i],r},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 oe,color:new Zt};break;case"SpotLight":i={position:new oe,direction:new oe,color:new Zt,distance:0,coneCos:0,penumbraCos:0,decay:0};break;case"PointLight":i={position:new oe,color:new Zt,distance:0,decay:0};break;case"HemisphereLight":i={direction:new oe,skyColor:new Zt,groundColor:new Zt};break;case"RectAreaLight":i={color:new Zt,position:new oe,halfWidth:new oe,halfHeight:new oe}}return t[e.id]=i,i}}}let Ps=0;function Is(t,e){return(e.castShadow?2:0)-(t.castShadow?2:0)+(e.map?1:0)-(t.map?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 It};break;case"PointLight":i={shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new It,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 oe);const s=new oe,a=new Ue,o=new Ue;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(Is);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=bn.LTC_FLOAT_1,r.rectAreaLTC2=bn.LTC_FLOAT_2):!0===t.has("OES_texture_half_float_linear")?(r.rectAreaLTC1=bn.LTC_HALF_1,r.rectAreaLTC2=bn.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=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=s.length?(a=new Ns(t,e),s.push(a)):a=s[r],a},dispose:function(){i=new WeakMap}}}class zs extends Mi{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 Us extends Mi{constructor(t){super(),this.isMeshDistanceMaterial=!0,this.type="MeshDistanceMaterial",this.referencePosition=new oe,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 vn;const r=new It,s=new It,a=new ie,o=new zs({depthPacking:3201}),l=new Us,c={},h=i.maxTextureSize,u={0:1,1:0,2:2},p=new rn({defines:{VSM_SAMPLES:8},uniforms:{shadow_pass:{value:null},resolution:{value:new It},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 zi;f.setAttribute("position",new Ti(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));const g=new Ji(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 ne(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(void 0!==d)h=d;else if(h=!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 ne(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 ie).fromArray(O),B=(new ie).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?Ct: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 At(t.width)&&At(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===ht&&!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.magFilter===d)return;if(s.minFilter!==m&&s.minFilter!==v)return;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===gt||n!==ct&&(n===ht?!1===o?!0===e.has("EXT_sRGB")&&r===w?(t.format=gt,t.minFilter=f,t.generateMipmaps=!1):i=Kt.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(Ws)))}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 Hs;i.matrixAutoUpdate=!1,i.visible=!1,t.joints[e.jointName]=i,t.add(i)}return t.joints[e.jointName]}}class qs extends ee{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 Xs extends vt{constructor(t,e){super();const i=this;let n=null,r=1,s=null,a="local-floor",o=1,l=null,c=null,h=null,u=null,d=null,p=null;const m=e.getContextAttributes();let f=null,g=null;const v=[],_=[],M=new Set,b=new Map,E=new an;E.layers.enable(1),E.viewport=new ie;const C=new an;C.layers.enable(2),C.viewport=new ie;const L=[E,C],R=new Vs;R.layers.enable(1),R.layers.enable(2);let P=null,I=null;function D(t){const e=_.indexOf(t.inputSource);if(-1===e)return;const i=v[e];void 0!==i&&i.dispatchEvent({type:t.type,data:t.inputSource})}function N(){n.removeEventListener("select",D),n.removeEventListener("selectstart",D),n.removeEventListener("selectend",D),n.removeEventListener("squeeze",D),n.removeEventListener("squeezestart",D),n.removeEventListener("squeezeend",D),n.removeEventListener("end",N),n.removeEventListener("inputsourceschange",O);for(let t=0;t=0&&(_[n]=null,v[n].disconnect(i))}for(let e=0;e=_.length){_.push(i),n=t;break}if(null===_[t]){_[t]=i,n=t;break}}if(-1===n)break}const r=v[n];r&&r.connect(i)}}this.cameraAutoUpdate=!0,this.enabled=!1,this.isPresenting=!1,this.getController=function(t){let e=v[t];return void 0===e&&(e=new js,v[t]=e),e.getTargetRaySpace()},this.getControllerGrip=function(t){let e=v[t];return void 0===e&&(e=new js,v[t]=e),e.getGripSpace()},this.getHand=function(t){let e=v[t];return void 0===e&&(e=new js,v[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 l||s},this.setReferenceSpace=function(t){l=t},this.getBaseLayer=function(){return null!==u?u:d},this.getBinding=function(){return h},this.getFrame=function(){return p},this.getSession=function(){return n},this.setSession=async function(c){if(n=c,null!==n){if(f=t.getRenderTarget(),n.addEventListener("select",D),n.addEventListener("selectstart",D),n.addEventListener("selectend",D),n.addEventListener("squeeze",D),n.addEventListener("squeezestart",D),n.addEventListener("squeezeend",D),n.addEventListener("end",N),n.addEventListener("inputsourceschange",O),!0!==m.xrCompatible&&await e.makeXRCompatible(),void 0===n.renderState.layers||!1===t.capabilities.isWebGL2){const i={antialias:void 0!==n.renderState.layers||m.antialias,alpha:m.alpha,depth:m.depth,stencil:m.stencil,framebufferScaleFactor:r};d=new XRWebGLLayer(n,e,i),n.updateRenderState({baseLayer:d}),g=new ne(d.framebufferWidth,d.framebufferHeight,{format:w,type:x,encoding:t.outputEncoding,stencilBuffer:m.stencil})}else{let i=null,s=null,a=null;m.depth&&(a=m.stencil?35056:33190,i=m.stencil?A:T,s=m.stencil?S:y);const o={colorFormat:32856,depthFormat:a,scaleFactor:r};h=new XRWebGLBinding(n,e),u=h.createProjectionLayer(o),n.updateRenderState({layers:[u]}),g=new ne(u.textureWidth,u.textureHeight,{format:w,type:x,depthTexture:new qs(u.textureWidth,u.textureHeight,s,void 0,void 0,void 0,void 0,void 0,void 0,i),stencilBuffer:m.stencil,encoding:t.outputEncoding,samples:m.antialias?4:0});t.properties.get(g).__ignoreDepthValues=u.ignoreDepthValues}g.isXRRenderTarget=!0,this.setFoveation(o),l=null,s=await n.requestReferenceSpace(a),k.setContext(n),k.start(),i.isPresenting=!0,i.dispatchEvent({type:"sessionstart"})}};const z=new oe,U=new oe;function B(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;R.near=C.near=E.near=t.near,R.far=C.far=E.far=t.far,P===R.near&&I===R.far||(n.updateRenderState({depthNear:R.near,depthFar:R.far}),P=R.near,I=R.far);const e=t.parent,i=R.cameras;B(R,e);for(let t=0;te&&(b.set(t,t.lastChangedTime),i.dispatchEvent({type:"planechanged",data:t}))}else M.add(t),b.set(t,n.lastChangedTime),i.dispatchEvent({type:"planeadded",data:t})}p=null})),this.setAnimationLoop=function(t){F=t},this.dispose=function(){}}}function Ys(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,en(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);const n=e.get(i).envMap;n&&(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]){if("number"==typeof n)i[e]=n;else{const t=Array.isArray(n)?n:[n],r=[];for(let e=0;e0){r=i%n;0!==r&&n-r-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=Z.isWebGL2;null===V&&(V=new ne(1,1,{generateMipmaps:!0,type:Y.has("EXT_color_buffer_half_float")?b:x,minFilter:v,samples:n&&!0===a?4:0}));g.getDrawingBufferSize(W),n?V.setSize(W.x,W.y):V.setSize(Ct(W.x),Ct(W.y));const r=g.getRenderTarget();g.setRenderTarget(V),g.clear();const s=g.toneMapping;g.toneMapping=0,Ot(t,e,i),g.toneMapping=s,Q.updateMultisampleRenderTarget(V),Q.updateRenderTargetMipmap(V),g.setRenderTarget(r)}(r,e,i),n&&J.viewport(C.copy(n)),r.length>0&&Ot(r,e,i),s.length>0&&Ot(s,e,i),o.length>0&&Ot(o,e,i),J.buffers.depth.setTest(!0),J.buffers.depth.setMask(!0),J.buffers.color.setMask(!0),J.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,m.pop(),d=m.length>0?m[m.length-1]:null},this.getActiveCubeFace=function(){return y},this.getActiveMipmapLevel=function(){return S},this.getRenderTarget=function(){return T},this.setRenderTargetTextures=function(t,e,i){$.get(t.texture).__webglTexture=e,$.get(t.depthTexture).__webglTexture=i;const n=$.get(t);n.__hasExternalTextures=!0,n.__hasExternalTextures&&(n.__autoAllocateDepthBuffer=void 0===i,n.__autoAllocateDepthBuffer||!0===Y.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=$.get(t);i.__webglFramebuffer=e,i.__useDefaultFramebuffer=void 0===e},this.setRenderTarget=function(t,e=0,i=0){T=t,y=e,S=i;let n=!0,r=null,s=!1,a=!1;if(t){const i=$.get(t);void 0!==i.__useDefaultFramebuffer?(J.bindFramebuffer(36160,null),n=!1):void 0===i.__webglFramebuffer?Q.setupRenderTarget(t):i.__hasExternalTextures&&Q.rebindTextures(t,$.get(t.texture).__webglTexture,$.get(t.depthTexture).__webglTexture);const o=t.texture;(o.isData3DTexture||o.isDataArrayTexture||o.isCompressedArrayTexture)&&(a=!0);const l=$.get(t).__webglFramebuffer;t.isWebGLCubeRenderTarget?(r=l[e],s=!0):r=Z.isWebGL2&&t.samples>0&&!1===Q.useMultisampledRTT(t)?$.get(t).__webglMultisampledFramebuffer:l,C.copy(t.viewport),L.copy(t.scissor),R=t.scissorTest}else C.copy(z).multiplyScalar(D).floor(),L.copy(U).multiplyScalar(D).floor(),R=B;if(J.bindFramebuffer(36160,r)&&Z.drawBuffers&&n&&J.drawBuffers(t,r),J.viewport(C),J.scissor(L),J.setScissorTest(R),s){const n=$.get(t.texture);_t.framebufferTexture2D(36160,36064,34069+e,n.__webglTexture,i)}else if(a){const n=$.get(t.texture),r=e||0;_t.framebufferTextureLayer(36160,36064,n.__webglTexture,i||0,r)}A=-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=$.get(t).__webglFramebuffer;if(t.isWebGLCubeRenderTarget&&void 0!==a&&(o=o[a]),o){J.bindFramebuffer(36160,o);try{const a=t.texture,o=a.format,l=a.type;if(o!==w&>.convert(o)!==_t.getParameter(35739))return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.");const c=l===b&&(Y.has("EXT_color_buffer_half_float")||Z.isWebGL2&&Y.has("EXT_color_buffer_float"));if(!(l===x||gt.convert(l)===_t.getParameter(35738)||l===M&&(Z.isWebGL2||Y.has("OES_texture_float")||Y.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&&_t.readPixels(e,i,n,r,gt.convert(o),gt.convert(l),s)}finally{const t=null!==T?$.get(T).__webglFramebuffer:null;J.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);Q.setTexture2D(e,0),_t.copyTexSubImage2D(3553,i,0,0,t.x,t.y,r,s),J.unbindTexture()},this.copyTextureToTexture=function(t,e,i,n=0){const r=e.image.width,s=e.image.height,a=gt.convert(i.format),o=gt.convert(i.type);Q.setTexture2D(i,0),_t.pixelStorei(37440,i.flipY),_t.pixelStorei(37441,i.premultiplyAlpha),_t.pixelStorei(3317,i.unpackAlignment),e.isDataTexture?_t.texSubImage2D(3553,n,t.x,t.y,r,s,a,o,e.image.data):e.isCompressedTexture?_t.compressedTexSubImage2D(3553,n,t.x,t.y,e.mipmaps[0].width,e.mipmaps[0].height,a,e.mipmaps[0].data):_t.texSubImage2D(3553,n,t.x,t.y,a,o,e.image),0===n&&i.generateMipmaps&&_t.generateMipmap(3553),J.unbindTexture()},this.copyTextureToTexture3D=function(t,e,i,n,r=0){if(g.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=gt.convert(n.format),c=gt.convert(n.type);let h;if(n.isData3DTexture)Q.setTexture3D(n,0),h=32879;else{if(!n.isDataArrayTexture)return void console.warn("THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.");Q.setTexture2DArray(n,0),h=35866}_t.pixelStorei(37440,n.flipY),_t.pixelStorei(37441,n.premultiplyAlpha),_t.pixelStorei(3317,n.unpackAlignment);const u=_t.getParameter(3314),d=_t.getParameter(32878),p=_t.getParameter(3316),m=_t.getParameter(3315),f=_t.getParameter(32877),v=i.isCompressedTexture?i.mipmaps[0]:i.image;_t.pixelStorei(3314,v.width),_t.pixelStorei(32878,v.height),_t.pixelStorei(3316,t.min.x),_t.pixelStorei(3315,t.min.y),_t.pixelStorei(32877,t.min.z),i.isDataTexture||i.isData3DTexture?_t.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."),_t.compressedTexSubImage3D(h,r,e.x,e.y,e.z,s,a,o,l,v.data)):_t.texSubImage3D(h,r,e.x,e.y,e.z,s,a,o,l,c,v),_t.pixelStorei(3314,u),_t.pixelStorei(32878,d),_t.pixelStorei(3316,p),_t.pixelStorei(3315,m),_t.pixelStorei(32877,f),0===r&&n.generateMipmaps&&_t.generateMipmap(h),J.unbindTexture()},this.initTexture=function(t){t.isCubeTexture?Q.setTextureCube(t,0):t.isData3DTexture?Q.setTexture3D(t,0):t.isDataArrayTexture||t.isCompressedArrayTexture?Q.setTexture2DArray(t,0):Q.setTexture2D(t,0),J.unbindTexture()},this.resetState=function(){y=0,S=0,T=null,J.reset(),vt.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 Zt(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 Zt(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 li{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.object.backgroundBlurriness=this.backgroundBlurriness),1!==this.backgroundIntensity&&(e.object.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 ea{constructor(t,e){this.isInterleavedBuffer=!0,this.array=t,this.stride=e,this.count=void 0!==t?t.length/e:0,this.usage=mt,this.updateRange={offset:0,count:-1},this.version=0,this.uuid=bt()}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:_i.getUV(aa,da,pa,ma,fa,ga,va,new It),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 oe,Ma=new oe;class ba extends li{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=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 so extends ee{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 ao{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 It:new oe);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 oe,n=[],r=[],s=[],a=new oe,o=new Ue;for(let e=0;e<=t;e++){const i=e/t;n[e]=this.getTangentAt(i,new oe)}r[0]=new oe,s[0]=new oe;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(St(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(St(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 oo extends ao{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 It,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]:(ho.subVectors(n[0],n[1]).add(n[0]),a=ho);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(go(a,o.x,l.x,c.x,h.x),go(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 Lo extends zi{constructor(t=[new It(0,-.5),new It(.5,0),new It(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=St(n,0,2*Math.PI);const r=[],s=[],a=[],o=[],l=[],c=1/e,h=new oe,u=new It,d=new oe,p=new oe,m=new oe;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 Ci(h,3)),this.setAttribute("normal",new Ci(u,3)),this.setAttribute("uv",new Ci(d,2))}static fromJSON(t){return new Io(t.radiusTop,t.radiusBottom,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class Do extends Io{constructor(t=1,e=1,i=32,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 Do(t.radius,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class No extends zi{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 Ci(r,3)),this.setAttribute("normal",new Ci(r.slice(),3)),this.setAttribute("uv",new Ci(s,2)),0===n?this.computeVertexNormals():this.normalizeNormals()}static fromJSON(t){return new No(t.vertices,t.indices,t.radius,t.details)}}class Oo extends No{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 Oo(t.radius,t.detail)}}const zo=new oe,Uo=new oe,Bo=new oe,Fo=new _i;class ko extends zi{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(yt*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 jo(s,a,i,o,l,p,0),a};function Ho(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=hl(s,t[s],t[s+1],a);return a&&rl(a,a.next)&&(ul(a),a=a.next),a}function Wo(t,e){if(!t)return t;e||(e=t);let i,n=t;do{if(i=!1,n.steiner||!rl(n,n.next)&&0!==nl(n.prev,n,n.next))n=n.next;else{if(ul(n),n=e=n.prev,n===n.next)break;i=!0}}while(i||n!==e);return e}function jo(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=Qo(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?Xo(t,n,r,s):qo(t))e.push(o.i/i|0),e.push(t.i/i|0),e.push(l.i/i|0),ul(t),t=l.next,c=l.next;else if((t=l)===c){a?1===a?jo(t=Yo(Wo(t),e,i),e,i,n,r,s,2):2===a&&Zo(t,e,i,n,r,s):jo(Wo(t),e,i,n,r,s,1);break}}function qo(t){const e=t.prev,i=t,n=t.next;if(nl(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&&el(r,o,s,l,a,c,m.x,m.y)&&nl(m.prev,m,m.next)>=0)return!1;m=m.next}return!0}function Xo(t,e,i,n){const r=t.prev,s=t,a=t.next;if(nl(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=Qo(p,m,e,i,n),x=Qo(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&&el(o,h,l,u,c,d,_.x,_.y)&&nl(_.prev,_,_.next)>=0)return!1;if(_=_.prevZ,y.x>=p&&y.x<=f&&y.y>=m&&y.y<=g&&y!==r&&y!==a&&el(o,h,l,u,c,d,y.x,y.y)&&nl(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&&el(o,h,l,u,c,d,_.x,_.y)&&nl(_.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&&el(o,h,l,u,c,d,y.x,y.y)&&nl(y.prev,y,y.next)>=0)return!1;y=y.nextZ}return!0}function Yo(t,e,i){let n=t;do{const r=n.prev,s=n.next.next;!rl(r,s)&&sl(r,n,n.next,s)&&ll(r,s)&&ll(s,r)&&(e.push(r.i/i|0),e.push(n.i/i|0),e.push(s.i/i|0),ul(n),ul(n.next),n=t=s),n=n.next}while(n!==t);return Wo(n)}function Zo(t,e,i,n,r,s){let a=t;do{let t=a.next.next;for(;t!==a.prev;){if(a.i!==t.i&&il(a,t)){let o=cl(a,t);return a=Wo(a,a.next),o=Wo(o,o.next),jo(a,e,i,n,r,s,0),void jo(o,e,i,n,r,s,0)}t=t.next}a=a.next}while(a!==t)}function Jo(t,e){return t.x-e.x}function Ko(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&&el(ai.x||n.x===i.x&&$o(i,n)))&&(i=n,u=h)),n=n.next}while(n!==o);return i}(t,e);if(!i)return e;const n=cl(i,t);return Wo(n,n.next),Wo(i,i.next)}function $o(t,e){return nl(t.prev,t,e.prev)<0&&nl(e.next,t,t.next)<0}function Qo(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 tl(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 il(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&&sl(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(ll(t,e)&&ll(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)&&(nl(t.prev,t,e.prev)||nl(t,e.prev,e))||rl(t,e)&&nl(t.prev,t,t.next)>0&&nl(e.prev,e,e.next)>0)}function nl(t,e,i){return(e.y-t.y)*(i.x-e.x)-(e.x-t.x)*(i.y-e.y)}function rl(t,e){return t.x===e.x&&t.y===e.y}function sl(t,e,i,n){const r=ol(nl(t,e,i)),s=ol(nl(t,e,n)),a=ol(nl(i,n,t)),o=ol(nl(i,n,e));return r!==s&&a!==o||(!(0!==r||!al(t,i,e))||(!(0!==s||!al(t,n,e))||(!(0!==a||!al(i,t,n))||!(0!==o||!al(i,e,n)))))}function al(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 ol(t){return t>0?1:t<0?-1:0}function ll(t,e){return nl(t.prev,t,t.next)<0?nl(t,e,t.next)>=0&&nl(t,t.prev,e)>=0:nl(t,e,t.prev)<0||nl(t,t.next,e)<0}function cl(t,e){const i=new dl(t.i,t.x,t.y),n=new dl(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 hl(t,e,i,n){const r=new dl(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 ul(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 dl(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 pl{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,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 It(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 It(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 Nl extends Mi{constructor(t){super(),this.isMeshPhongMaterial=!0,this.type="MeshPhongMaterial",this.color=new Zt(16777215),this.specular=new Zt(1118481),this.shininess=30,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new Zt(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new It(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 Ol extends Mi{constructor(t){super(),this.isMeshToonMaterial=!0,this.defines={TOON:""},this.type="MeshToonMaterial",this.color=new Zt(16777215),this.map=null,this.gradientMap=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new Zt(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new It(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 zl extends Mi{constructor(t){super(),this.isMeshNormalMaterial=!0,this.type="MeshNormalMaterial",this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new It(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 Ul extends Mi{constructor(t){super(),this.isMeshLambertMaterial=!0,this.type="MeshLambertMaterial",this.color=new Zt(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new Zt(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new It(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 Bl extends Mi{constructor(t){super(),this.isMeshMatcapMaterial=!0,this.defines={MATCAP:""},this.type="MeshMatcapMaterial",this.color=new Zt(16777215),this.matcap=null,this.map=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new It(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 Fl extends Ga{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 kl(t,e,i){return Vl(t)?new t.constructor(t.subarray(e,void 0!==i?i:t.length)):t.slice(e,i)}function Gl(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 Vl(t){return ArrayBuffer.isView(t)&&!(t instanceof DataView)}function Hl(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 Wl(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 jl(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 ql=Object.freeze({__proto__:null,arraySlice:kl,convertArray:Gl,flattenJSON:jl,getKeyframeOrder:Hl,isTypedArray:Vl,makeClipAdditive:function(t,e=0,i=t,n=30){n<=0&&(n=30);const r=i.tracks.length,s=e/n;for(let e=0;e=n.times[u]){const t=u*l+o,e=t+l-o;d=kl(n.values,t,e)}else{const t=n.createInterpolant(),e=o,i=l-o;t.evaluate(s),d=kl(t.resultBuffer,e,i)}if("quaternion"===r){(new ae).fromArray(d).normalize().conjugate().toArray(d)}const p=a.times.length;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=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=kl(i,r,s),this.values=kl(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&&Vl(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=kl(this.times),e=kl(this.values),i=this.getValueSize(),n=this.getInterpolation()===nt,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=kl(t,0,s),this.values=kl(e,0,s*i)):(this.times=t,this.values=e),this}clone(){const t=kl(this.times,0),e=kl(this.values,0),i=new(0,this.constructor)(this.name,t,e);return i.createInterpolant=this.createInterpolant,i}}Kl.prototype.TimeBufferType=Float32Array,Kl.prototype.ValueBufferType=Float32Array,Kl.prototype.DefaultInterpolation=it;class $l extends Kl{}$l.prototype.ValueTypeName="bool",$l.prototype.ValueBufferType=Array,$l.prototype.DefaultInterpolation=et,$l.prototype.InterpolantFactoryMethodLinear=void 0,$l.prototype.InterpolantFactoryMethodSmooth=void 0;class Ql extends Kl{}Ql.prototype.ValueTypeName="color";class tc extends Kl{}tc.prototype.ValueTypeName="number";class ec extends Xl{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)ae.slerpFlat(r,0,s,l-a,s,l,o);return r}}class ic extends Kl{InterpolantFactoryMethodLinear(t){return new ec(this.times,this.values,this.getValueSize(),t)}}ic.prototype.ValueTypeName="quaternion",ic.prototype.DefaultInterpolation=it,ic.prototype.InterpolantFactoryMethodSmooth=void 0;class nc extends Kl{}nc.prototype.ValueTypeName="string",nc.prototype.ValueBufferType=Array,nc.prototype.DefaultInterpolation=et,nc.prototype.InterpolantFactoryMethodLinear=void 0,nc.prototype.InterpolantFactoryMethodSmooth=void 0;class rc extends Kl{}rc.prototype.ValueTypeName="vector";class sc{constructor(t,e=-1,i,n=2500){this.name=t,this.tracks=i,this.duration=e,this.blendMode=n,this.uuid=bt(),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(ac(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(Kl.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=[];jl(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!==uc[t])return void uc[t].push({onLoad:e,onProgress:i,onError:n});uc[t]=[],uc[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=uc[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=>{oc.add(t,e);const i=uc[t];delete uc[t];for(let t=0,n=i.length;t{const i=uc[t];if(void 0===i)throw this.manager.itemError(t),e;delete uc[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 mc extends hc{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=oc.get(t);if(void 0!==s)return r.manager.itemStart(t),setTimeout((function(){e&&e(s),r.manager.itemEnd(t)}),0),s;const a=Bt("img");function o(){c(),oc.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 li{constructor(t,e=1){super(),this.isLight=!0,this.type="Light",this.color=new Zt(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 gc extends fc{constructor(t,e,i){super(t,i),this.isHemisphereLight=!0,this.type="HemisphereLight",this.position.copy(li.DEFAULT_UP),this.updateMatrix(),this.groundColor=new Zt(e)}copy(t,e){return super.copy(t,e),this.groundColor.copy(t.groundColor),this}}const vc=new Ue,xc=new oe,_c=new oe;class yc{constructor(t){this.camera=t,this.bias=0,this.normalBias=0,this.radius=1,this.blurSamples=8,this.mapSize=new It(512,512),this.map=null,this.mapPass=null,this.matrix=new Ue,this.autoUpdate=!0,this.needsUpdate=!1,this._frustum=new vn,this._frameExtents=new It(1,1),this._viewportCount=1,this._viewports=[new ie(0,0,1,1)]}getViewportCount(){return this._viewportCount}getFrustum(){return this._frustum}updateMatrices(t){const e=this.camera,i=this.matrix;xc.setFromMatrixPosition(t.matrixWorld),e.position.copy(xc),_c.setFromMatrixPosition(t.target.matrixWorld),e.lookAt(_c),e.updateMatrixWorld(),vc.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this._frustum.setFromProjectionMatrix(vc),i.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1),i.multiply(vc)}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 Mc extends yc{constructor(){super(new an(50,1,.5,500)),this.isSpotLightShadow=!0,this.focus=1}updateMatrices(t){const e=this.camera,i=2*Mt*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 bc extends fc{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(li.DEFAULT_UP),this.updateMatrix(),this.target=new li,this.distance=i,this.angle=n,this.penumbra=r,this.decay=s,this.map=null,this.shadow=new Mc}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 Sc=new Ue,wc=new oe,Tc=new oe;class Ac extends yc{constructor(){super(new an(90,1,.5,500)),this.isPointLightShadow=!0,this._frameExtents=new It(4,2),this._viewportCount=6,this._viewports=[new ie(2,1,1,1),new ie(0,1,1,1),new ie(3,1,1,1),new ie(1,1,1,1),new ie(3,0,1,1),new ie(1,0,1,1)],this._cubeDirections=[new oe(1,0,0),new oe(-1,0,0),new oe(0,0,1),new oe(0,0,-1),new oe(0,1,0),new oe(0,-1,0)],this._cubeUps=[new oe(0,1,0),new oe(0,1,0),new oe(0,1,0),new oe(0,1,0),new oe(0,0,1),new oe(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),Tc.copy(i.position),Tc.add(this._cubeDirections[e]),i.up.copy(this._cubeUps[e]),i.lookAt(Tc),i.updateMatrixWorld(),n.makeTranslation(-wc.x,-wc.y,-wc.z),Sc.multiplyMatrices(i.projectionMatrix,i.matrixWorldInverse),this._frustum.setFromProjectionMatrix(Sc)}}class Ec extends fc{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 Ac}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 Cc extends yc{constructor(){super(new Pn(-5,5,5,-5,.5,500)),this.isDirectionalLightShadow=!0}}class Lc extends fc{constructor(t,e){super(t,e),this.isDirectionalLight=!0,this.type="DirectionalLight",this.position.copy(li.DEFAULT_UP),this.updateMatrix(),this.target=new li,this.shadow=new Cc}dispose(){this.shadow.dispose()}copy(t){return super.copy(t),this.target=t.target.clone(),this.shadow=t.shadow.clone(),this}}class Rc extends fc{constructor(t,e){super(t,e),this.isAmbientLight=!0,this.type="AmbientLight"}}class Pc 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 Ic{constructor(){this.isSphericalHarmonics3=!0,this.coefficients=[];for(let t=0;t<9;t++)this.coefficients.push(new oe)}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 Dc extends fc{constructor(t=new Ic,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 Nc extends hc{constructor(t){super(t),this.textures={}}load(t,e,i,n){const r=this,s=new pc(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=Nc.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 Zt).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.forceSinglePass&&(n.forceSinglePass=t.forceSinglePass),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 Zt).setHex(r.value);break;case"v2":n.uniforms[e].value=(new It).fromArray(r.value);break;case"v3":n.uniforms[e].value=(new oe).fromArray(r.value);break;case"v4":n.uniforms[e].value=(new ie).fromArray(r.value);break;case"m3":n.uniforms[e].value=(new Dt).fromArray(r.value);break;case"m4":n.uniforms[e].value=(new Ue).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 It).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 It).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:Rl,SpriteMaterial:ra,RawShaderMaterial:Pl,ShaderMaterial:rn,PointsMaterial:$a,MeshPhysicalMaterial:Dl,MeshStandardMaterial:Il,MeshPhongMaterial:Nl,MeshToonMaterial:Ol,MeshNormalMaterial:zl,MeshLambertMaterial:Ul,MeshDepthMaterial:zs,MeshDistanceMaterial:Us,MeshBasicMaterial:bi,MeshMatcapMaterial:Bl,LineDashedMaterial:Fl,LineBasicMaterial:Ga,Material:Mi}[t]}}class Oc{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){ae.slerpFlat(t,e,t,e,t,i,n)}_slerpAdditive(t,e,i,n,r){const s=this._workIndex*r;ae.multiplyQuaternionsFlat(t,s,t,e,t,i),ae.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 rh="\\[\\]\\.:\\/",sh=new RegExp("["+rh+"]","g"),ah="[^"+rh+"]",oh="[^"+rh.replace("\\.","")+"]",lh=new RegExp("^"+/((?:WC+[\/:])*)/.source.replace("WC",ah)+/(WCOD+)?/.source.replace("WCOD",oh)+/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC",ah)+/\.(WC+)(?:\[(.+)\])?/.source.replace("WC",ah)+"$"),ch=["material","materials","bones","map"];class hh{constructor(t,e,i){this.path=e,this.parsedPath=i||hh.parseTrackName(e),this.node=hh.findNode(t,this.parsedPath.nodeName),this.rootNode=t,this.getValue=this._getValue_unbound,this.setValue=this._setValue_unbound}static create(t,e,i){return t&&t.isAnimationObjectGroup?new hh.Composite(t,e,i):new hh(t,e,i)}static sanitizeNodeName(t){return t.replace(/\s/g,"_").replace(sh,"")}static parseTrackName(t){const e=lh.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!==ch.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===lt)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=st,n.endingEnd=st):(n.endingStart=t?this.zeroSlopeAtStart?st:rt:at,n.endingEnd=e?this.zeroSlopeAtEnd?st:rt:at)}_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 dh=new Float32Array(1);class ph{constructor(t){this.value=t}clone(){return new ph(void 0===this.value.clone?this.value:this.value.clone())}}let mh=0;function fh(t,e){return t.distance-e.distance}function gh(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 kh=Object.freeze({__proto__:null,fromHalfFloat:function(t){const e=t>>10;return Bh.uint32View[0]=Bh.mantissaTable[Bh.offsetTable[e]+(1023&t)]+Bh.exponentTable[e],Bh.floatView[0]},toHalfFloat:function(t){Math.abs(t)>65504&&console.warn("THREE.DataUtils.toHalfFloat(): Value out of range."),t=St(t,-65504,65504),Bh.floatView[0]=t;const e=Bh.uint32View[0],i=e>>23&511;return Bh.baseTable[i]+((8388607&e)>>Bh.shiftTable[i])}});"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=lt,t.AdditiveBlending=2,t.AlphaFormat=1021,t.AlwaysDepth=1,t.AlwaysStencilFunc=519,t.AmbientLight=Rc,t.AmbientLightProbe=class extends Dc{constructor(t,e=1){super(void 0,e),this.isAmbientLightProbe=!0;const i=(new Zt).set(t);this.sh.coefficients[0].set(i.r,i.g,i.b).multiplyScalar(2*Math.sqrt(Math.PI))}},t.AnimationClip=sc,t.AnimationLoader=class extends hc{constructor(t){super(t)}load(t,e,i,n){const r=this,s=new pc(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 hh(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=ql,t.ArcCurve=lo,t.ArrayCamera=Vs,t.ArrowHelper=class extends li{constructor(t=new oe(0,0,1),e=new oe(0,0,0),i=1,n=16776960,r=.2*i,s=.2*r){super(),this.type="ArrowHelper",void 0===zh&&(zh=new zi,zh.setAttribute("position",new Ci([0,0,0,0,1,0],3)),Uh=new Io(0,.5,1,5,1),Uh.translate(0,-.5,0)),this.position.copy(e),this.line=new Xa(zh,new Ga({color:n,toneMapped:!1})),this.line.matrixAutoUpdate=!1,this.add(this.line),this.cone=new Ji(Uh,new bi({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{Oh.set(t.z,0,-t.x).normalize();const e=Math.acos(t.y);this.quaternion.setFromAxisAngle(Oh,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=$c,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 vh.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=he,t.Box3Helper=class extends Ja{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 zi;n.setIndex(new Ti(i,1)),n.setAttribute("position",new Ci([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 Ga({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 $i{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=$i,t.BoxHelper=class extends Ja{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 zi;r.setIndex(new Ti(i,1)),r.setAttribute("position",new Ti(n,3)),super(r,new Ga({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&&Nh.setFromObject(this.object),Nh.isEmpty())return;const e=Nh.min,i=Nh.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=Ti,t.BufferGeometry=zi,t.BufferGeometryLoader=Uc,t.ByteType=1010,t.Cache=oc,t.Camera=sn,t.CameraHelper=class extends Ja{constructor(t){const e=new zi,i=new Ga({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 Ci(n,3)),e.setAttribute("color",new Ci(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 Zt(16755200),c=new Zt(16711680),h=new Zt(43775),u=new Zt(16777215),d=new Zt(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;Ih.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse),Dh("c",e,t,Ih,0,0,-1),Dh("t",e,t,Ih,0,0,1),Dh("n1",e,t,Ih,-1,-1,-1),Dh("n2",e,t,Ih,1,-1,-1),Dh("n3",e,t,Ih,-1,1,-1),Dh("n4",e,t,Ih,1,1,-1),Dh("f1",e,t,Ih,-1,-1,1),Dh("f2",e,t,Ih,1,-1,1),Dh("f3",e,t,Ih,-1,1,1),Dh("f4",e,t,Ih,1,1,1),Dh("u1",e,t,Ih,.7,1.1,-1),Dh("u2",e,t,Ih,-.7,1.1,-1),Dh("u3",e,t,Ih,0,2,-1),Dh("cf1",e,t,Ih,-1,0,1),Dh("cf2",e,t,Ih,1,0,1),Dh("cf3",e,t,Ih,0,-1,1),Dh("cf4",e,t,Ih,0,1,1),Dh("cn1",e,t,Ih,-1,0,-1),Dh("cn2",e,t,Ih,1,0,-1),Dh("cn3",e,t,Ih,0,-1,-1),Dh("cn4",e,t,Ih,0,1,-1),t.getAttribute("position").needsUpdate=!0}dispose(){this.geometry.dispose(),this.material.dispose()}},t.CanvasTexture=class extends ee{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 Ro{constructor(t,e,i,n){console.warn("THREE.CapsuleBufferGeometry has been renamed to THREE.CapsuleGeometry."),super(t,e,i,n)}},t.CapsuleGeometry=Ro,t.CatmullRomCurve3=fo,t.CineonToneMapping=3,t.CircleBufferGeometry=class extends Po{constructor(t,e,i,n){console.warn("THREE.CircleBufferGeometry has been renamed to THREE.CircleGeometry."),super(t,e,i,n)}},t.CircleGeometry=Po,t.ClampToEdgeWrapping=h,t.Clock=qc,t.Color=Zt,t.ColorKeyframeTrack=Ql,t.ColorManagement=Vt,t.CompressedArrayTexture=class extends so{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=so,t.CompressedTextureLoader=class extends hc{constructor(t){super(t)}load(t,e,i,n){const r=this,s=[],a=new so,o=new pc(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 lc(e);r=new mc(i),r.setCrossOrigin(this.crossOrigin);for(let e=0,i=t.length;e0){n=new mc(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=pl.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 Go,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=Ks,t.WebGL3DRenderTarget=class extends ne{constructor(t=1,e=1,i=1){super(t,e),this.isWebGL3DRenderTarget=!0,this.depth=i,this.texture=new se(null,t,e,i),this.texture.isRenderTargetTexture=!0}},t.WebGLArrayRenderTarget=class extends ne{constructor(t=1,e=1,i=1){super(t,e),this.isWebGLArrayRenderTarget=!0,this.depth=i,this.texture=new re(null,t,e,i),this.texture.isRenderTargetTexture=!0}},t.WebGLCubeRenderTarget=hn,t.WebGLMultipleRenderTargets=class extends ne{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>>>>>> mrdoob-dev diff --git a/build/three.module.js b/build/three.module.js index 476a4c76dcbf62..8318ca6f436e01 100644 --- a/build/three.module.js +++ b/build/three.module.js @@ -1,9 +1,9 @@ /** * @license - * Copyright 2010-2022 Three.js Authors + * Copyright 2010-2023 Three.js Authors * SPDX-License-Identifier: MIT */ -const REVISION = '141dev'; +const REVISION = '150dev'; const MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 }; const TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 }; const CullFaceNone = 0; @@ -17,8 +17,7 @@ const VSMShadowMap = 3; const FrontSide = 0; const BackSide = 1; const DoubleSide = 2; -const FlatShading = 1; -const SmoothShading = 2; +const TwoPassDoubleSide = 2; // r149 const NoBlending = 0; const NormalBlending = 1; const AdditiveBlending = 2; @@ -90,7 +89,6 @@ const UnsignedShort4444Type = 1017; const UnsignedShort5551Type = 1018; const UnsignedInt248Type = 1020; const AlphaFormat = 1021; -const RGBFormat = 1022; const RGBAFormat = 1023; const LuminanceFormat = 1024; const LuminanceAlphaFormat = 1025; @@ -128,6 +126,10 @@ const RGBA_ASTC_10x10_Format = 37819; const RGBA_ASTC_12x10_Format = 37820; const RGBA_ASTC_12x12_Format = 37821; const RGBA_BPTC_Format = 36492; +const RED_RGTC1_Format = 36283; +const SIGNED_RED_RGTC1_Format = 36284; +const RED_GREEN_RGTC2_Format = 36285; +const SIGNED_RED_GREEN_RGTC2_Format = 36286; const LoopOnce = 2200; const LoopRepeat = 2201; const LoopPingPong = 2202; @@ -272,13 +274,7 @@ class EventDispatcher { } -const _lut = []; - -for ( let i = 0; i < 256; i ++ ) { - - _lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 ); - -} +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; @@ -507,7 +503,7 @@ function setQuaternionFromProperEuler( q, a, b, c, order ) { } -function denormalize$1( value, array ) { +function denormalize( value, array ) { switch ( array.constructor ) { @@ -575,35 +571,35 @@ var MathUtils = /*#__PURE__*/Object.freeze({ __proto__: null, DEG2RAD: DEG2RAD, RAD2DEG: RAD2DEG, - generateUUID: generateUUID, + ceilPowerOfTwo: ceilPowerOfTwo, clamp: clamp, + damp: damp, + degToRad: degToRad, + denormalize: denormalize, euclideanModulo: euclideanModulo, - mapLinear: mapLinear, + floorPowerOfTwo: floorPowerOfTwo, + generateUUID: generateUUID, inverseLerp: inverseLerp, + isPowerOfTwo: isPowerOfTwo, lerp: lerp, - damp: damp, + mapLinear: mapLinear, + normalize: normalize, pingpong: pingpong, - smoothstep: smoothstep, - smootherstep: smootherstep, - randInt: randInt, + radToDeg: radToDeg, randFloat: randFloat, randFloatSpread: randFloatSpread, + randInt: randInt, seededRandom: seededRandom, - degToRad: degToRad, - radToDeg: radToDeg, - isPowerOfTwo: isPowerOfTwo, - ceilPowerOfTwo: ceilPowerOfTwo, - floorPowerOfTwo: floorPowerOfTwo, setQuaternionFromProperEuler: setQuaternionFromProperEuler, - normalize: normalize, - denormalize: denormalize$1 + smootherstep: smootherstep, + smoothstep: smoothstep }); class Vector2 { constructor( x = 0, y = 0 ) { - this.isVector2 = true; + Vector2.prototype.isVector2 = true; this.x = x; this.y = y; @@ -709,14 +705,7 @@ class Vector2 { } - add( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); - - } + add( v ) { this.x += v.x; this.y += v.y; @@ -752,14 +741,7 @@ class Vector2 { } - sub( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); - return this.subVectors( v, w ); - - } + sub( v ) { this.x -= v.x; this.y -= v.y; @@ -1035,13 +1017,7 @@ class Vector2 { } - fromBufferAttribute( attribute, index, offset ) { - - if ( offset !== undefined ) { - - console.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' ); - - } + fromBufferAttribute( attribute, index ) { this.x = attribute.getX( index ); this.y = attribute.getY( index ); @@ -1086,7 +1062,7 @@ class Matrix3 { constructor() { - this.isMatrix3 = true; + Matrix3.prototype.isMatrix3 = true; this.elements = [ @@ -1096,12 +1072,6 @@ class Matrix3 { ]; - if ( arguments.length > 0 ) { - - console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); - - } - } set( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { @@ -1321,12 +1291,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; @@ -1334,37 +1303,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; @@ -1420,13 +1423,15 @@ class Matrix3 { } +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 } @@ -1556,7 +1561,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 }; @@ -1646,7 +1651,7 @@ class Color { } - setRGB( r, g, b, colorSpace = LinearSRGBColorSpace ) { + setRGB( r, g, b, colorSpace = ColorManagement.workingColorSpace ) { this.r = r; this.g = g; @@ -1658,7 +1663,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 ); @@ -1751,12 +1756,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 ] ); @@ -1886,9 +1891,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; } @@ -1898,13 +1903,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 ); @@ -1943,13 +1948,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; @@ -1957,16 +1962,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})`; } @@ -2109,16 +2114,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; } @@ -2368,7 +2363,7 @@ function serializeImage( image ) { // images of DataTexture return { - data: Array.prototype.slice.call( image.data ), + data: Array.from( image.data ), width: image.width, height: image.height, type: image.data.constructor.name @@ -2389,7 +2384,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(); @@ -2556,12 +2551,13 @@ class Texture extends EventDispatcher { flipY: this.flipY, + generateMipmaps: this.generateMipmaps, premultiplyAlpha: this.premultiplyAlpha, unpackAlignment: this.unpackAlignment }; - if ( JSON.stringify( this.userData ) !== '{}' ) output.userData = this.userData; + if ( Object.keys( this.userData ).length > 0 ) output.userData = this.userData; if ( ! isRootObject ) { @@ -2674,12 +2670,13 @@ class Texture extends EventDispatcher { Texture.DEFAULT_IMAGE = null; Texture.DEFAULT_MAPPING = UVMapping; +Texture.DEFAULT_ANISOTROPY = 1; class Vector4 { constructor( x = 0, y = 0, z = 0, w = 1 ) { - this.isVector4 = true; + Vector4.prototype.isVector4 = true; this.x = x; this.y = y; @@ -2813,14 +2810,7 @@ class Vector4 { } - add( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); - - } + add( v ) { this.x += v.x; this.y += v.y; @@ -2864,14 +2854,7 @@ class Vector4 { } - sub( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); - return this.subVectors( v, w ); - - } + sub( v ) { this.x -= v.x; this.y -= v.y; @@ -3299,13 +3282,7 @@ class Vector4 { } - fromBufferAttribute( attribute, index, offset ) { - - if ( offset !== undefined ) { - - console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' ); - - } + fromBufferAttribute( attribute, index ) { this.x = attribute.getX( index ); this.y = attribute.getY( index ); @@ -3345,7 +3322,7 @@ class Vector4 { */ class WebGLRenderTarget extends EventDispatcher { - constructor( width, height, options = {} ) { + constructor( width = 1, height = 1, options = {} ) { super(); @@ -3466,7 +3443,7 @@ class DataArrayTexture extends Texture { class WebGLArrayRenderTarget extends WebGLRenderTarget { - constructor( width, height, depth ) { + constructor( width = 1, height = 1, depth = 1 ) { super( width, height ); @@ -3515,7 +3492,7 @@ class Data3DTexture extends Texture { class WebGL3DRenderTarget extends WebGLRenderTarget { - constructor( width, height, depth ) { + constructor( width = 1, height = 1, depth = 1 ) { super( width, height ); @@ -3533,7 +3510,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 ); @@ -3623,13 +3600,6 @@ class Quaternion { } - static slerp( qa, qb, qm, t ) { - - console.warn( 'THREE.Quaternion: Static .slerp() has been deprecated. Use qm.slerpQuaternions( qa, qb, t ) instead.' ); - return qm.slerpQuaternions( qa, qb, t ); - - } - static slerpFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { // fuzz-free, array-based Quaternion SLERP operation @@ -3817,12 +3787,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/ @@ -4107,14 +4071,7 @@ class Quaternion { } - multiply( q, p ) { - - if ( p !== undefined ) { - - console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); - return this.multiplyQuaternions( q, p ); - - } + multiply( q ) { return this.multiplyQuaternions( this, q ); @@ -4309,7 +4266,7 @@ class Vector3 { constructor( x = 0, y = 0, z = 0 ) { - this.isVector3 = true; + Vector3.prototype.isVector3 = true; this.x = x; this.y = y; @@ -4407,14 +4364,7 @@ class Vector3 { } - add( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); - - } + add( v ) { this.x += v.x; this.y += v.y; @@ -4454,14 +4404,7 @@ class Vector3 { } - sub( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); - return this.subVectors( v, w ); - - } + sub( v ) { this.x -= v.x; this.y -= v.y; @@ -4491,14 +4434,7 @@ class Vector3 { } - multiply( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); - return this.multiplyVectors( v, w ); - - } + multiply( v ) { this.x *= v.x; this.y *= v.y; @@ -4530,12 +4466,6 @@ class Vector3 { applyEuler( euler ) { - if ( ! ( euler && euler.isEuler ) ) { - - console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); - - } - return this.applyQuaternion( _quaternion$4.setFromEuler( euler ) ); } @@ -4804,14 +4734,7 @@ class Vector3 { } - cross( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); - return this.crossVectors( v, w ); - - } + cross( v ) { return this.crossVectors( this, v ); @@ -5001,13 +4924,7 @@ class Vector3 { } - fromBufferAttribute( attribute, index, offset ) { - - if ( offset !== undefined ) { - - console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' ); - - } + fromBufferAttribute( attribute, index ) { this.x = attribute.getX( index ); this.y = attribute.getY( index ); @@ -5406,12 +5323,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 @@ -5421,7 +5338,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; @@ -5429,7 +5346,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; @@ -5440,7 +5357,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 ); } @@ -5546,7 +5463,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 @@ -5587,8 +5504,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 { @@ -5745,23 +5661,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; + + return this; + + } - _toPoint.subVectors( point, this.center ); + _v1$6.subVectors( point, this.center ); - const lengthSq = _toPoint.lengthSq(); + 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; } @@ -5771,25 +5695,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.center.equals( sphere.center ) === true ) { + if ( this.isEmpty() ) { - _toFarthestPoint.set( 0, 0, 1 ).multiplyScalar( sphere.radius ); + this.copy( sphere ); + 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$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 ).add( _toFarthestPoint ) ); - this.expandByPoint( _v1$6.copy( sphere.center ).sub( _toFarthestPoint ) ); + this.expandByPoint( _v1$6.copy( sphere.center ).sub( _v2$3 ) ); + + } return this; @@ -6165,12 +6097,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 ) { @@ -6306,7 +6235,7 @@ class Matrix4 { constructor() { - this.isMatrix4 = true; + Matrix4.prototype.isMatrix4 = true; this.elements = [ @@ -6317,12 +6246,6 @@ class Matrix4 { ]; - if ( arguments.length > 0 ) { - - console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); - - } - } set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { @@ -6462,12 +6385,6 @@ class Matrix4 { makeRotationFromEuler( euler ) { - if ( ! ( euler && euler.isEuler ) ) { - - console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); - - } - const te = this.elements; const x = euler.x, y = euler.y, z = euler.z; @@ -6641,14 +6558,7 @@ class Matrix4 { } - multiply( m, n ) { - - if ( n !== undefined ) { - - console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); - return this.multiplyMatrices( m, n ); - - } + multiply( m ) { return this.multiplyMatrices( this, m ); @@ -7075,12 +6985,6 @@ class Matrix4 { makePerspective( left, right, top, bottom, near, far ) { - if ( far === undefined ) { - - console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' ); - - } - const te = this.elements; const x = 2 * near / ( right - left ); const y = 2 * near / ( top - bottom ); @@ -7189,7 +7093,7 @@ const _quaternion$3 = /*@__PURE__*/ new Quaternion(); class Euler { - constructor( x = 0, y = 0, z = 0, order = Euler.DefaultOrder ) { + constructor( x = 0, y = 0, z = 0, order = Euler.DEFAULT_ORDER ) { this.isEuler = true; @@ -7490,18 +7394,9 @@ class Euler { } - // @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' ]; +Euler.DEFAULT_ORDER = 'XYZ'; class Layers { @@ -7597,7 +7492,7 @@ class Object3D extends EventDispatcher { this.parent = null; this.children = []; - this.up = Object3D.DefaultUp.clone(); + this.up = Object3D.DEFAULT_UP.clone(); const position = new Vector3(); const rotation = new Euler(); @@ -7651,9 +7546,11 @@ class Object3D extends EventDispatcher { this.matrix = new Matrix4(); this.matrixWorld = new Matrix4(); - this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; + this.matrixAutoUpdate = Object3D.DEFAULT_MATRIX_AUTO_UPDATE; this.matrixWorldNeedsUpdate = false; + this.matrixWorldAutoUpdate = Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; // checked by the renderer + this.layers = new Layers(); this.visible = true; @@ -7799,12 +7696,16 @@ class Object3D extends EventDispatcher { localToWorld( vector ) { + this.updateWorldMatrix( true, false ); + return vector.applyMatrix4( this.matrixWorld ); } worldToLocal( vector ) { + this.updateWorldMatrix( true, false ); + return vector.applyMatrix4( _m1$1.copy( this.matrixWorld ).invert() ); } @@ -8018,6 +7919,28 @@ class Object3D extends EventDispatcher { } + getObjectsByProperty( name, value ) { + + let result = []; + + if ( this[ name ] === value ) result.push( this ); + + for ( let i = 0, l = this.children.length; i < l; i ++ ) { + + const childResult = this.children[ i ].getObjectsByProperty( name, value ); + + if ( childResult.length > 0 ) { + + result = result.concat( childResult ); + + } + + } + + return result; + + } + getWorldPosition( target ) { this.updateWorldMatrix( true, false ); @@ -8138,7 +8061,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 ); + + } } @@ -8148,7 +8077,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 ); @@ -8174,7 +8103,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 ); + + } } @@ -8227,7 +8162,7 @@ class Object3D extends EventDispatcher { if ( this.visible === false ) object.visible = false; if ( this.frustumCulled === false ) object.frustumCulled = false; if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; - if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData; + if ( Object.keys( this.userData ).length > 0 ) object.userData = this.userData; object.layers = this.layers.mask; object.matrix = this.matrix.toArray(); @@ -8275,7 +8210,7 @@ class Object3D extends EventDispatcher { } - if ( this.environment && this.environment.isTexture ) { + if ( this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true ) { object.environment = this.environment.toJSON( meta ).uuid; @@ -8447,6 +8382,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; @@ -8475,8 +8412,9 @@ class Object3D extends EventDispatcher { } -Object3D.DefaultUp = new Vector3( 0, 1, 0 ); -Object3D.DefaultMatrixAutoUpdate = true; +Object3D.DEFAULT_UP = /*@__PURE__*/ new Vector3( 0, 1, 0 ); +Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true; +Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true; const _v0$1 = /*@__PURE__*/ new Vector3(); const _v1$3 = /*@__PURE__*/ new Vector3(); @@ -8836,6 +8774,7 @@ class Material extends EventDispatcher { this.alphaToCoverage = false; this.premultipliedAlpha = false; + this.forceSinglePass = false; this.visible = true; @@ -8894,15 +8833,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 ) { @@ -9081,7 +9011,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; @@ -9126,6 +9056,7 @@ class Material extends EventDispatcher { if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; if ( this.alphaToCoverage === true ) data.alphaToCoverage = this.alphaToCoverage; if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha; + if ( this.forceSinglePass === true ) data.forceSinglePass = this.forceSinglePass; if ( this.wireframe === true ) data.wireframe = this.wireframe; if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; @@ -9140,7 +9071,7 @@ class Material extends EventDispatcher { if ( this.fog === false ) data.fog = false; - if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData; + if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; // TODO: Copied from Object3D.toJSON @@ -9246,6 +9177,7 @@ class Material extends EventDispatcher { this.alphaTest = source.alphaTest; this.alphaToCoverage = source.alphaToCoverage; this.premultipliedAlpha = source.premultipliedAlpha; + this.forceSinglePass = source.forceSinglePass; this.visible = source.visible; @@ -9269,31 +9201,8 @@ class Material extends EventDispatcher { } - // @deprecated since r131, f5803c62cc4a29d90744e9dc7811d086e354c1d8 - - get vertexTangents() { - - console.warn( 'THREE.' + this.type + ': .vertexTangents has been removed.' ); - return false; - - } - - set vertexTangents( value ) { - - console.warn( 'THREE.' + this.type + ': .vertexTangents has been removed.' ); - - } - } -Material.fromType = function ( /*type*/ ) { - - // TODO: Behavior added in Materials.js - - return null; - -}; - class MeshBasicMaterial extends Material { constructor( parameters ) { @@ -9375,7 +9284,7 @@ const _vector2$1 = /*@__PURE__*/ new Vector2(); class BufferAttribute { - constructor( array, itemSize, normalized ) { + constructor( array, itemSize, normalized = false ) { if ( Array.isArray( array ) ) { @@ -9390,7 +9299,7 @@ class BufferAttribute { this.array = array; this.itemSize = itemSize; this.count = array !== undefined ? array.length / itemSize : 0; - this.normalized = normalized === true; + this.normalized = normalized; this.usage = StaticDrawUsage; this.updateRange = { offset: 0, count: - 1 }; @@ -9452,110 +9361,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 ) { @@ -9636,6 +9441,7 @@ class BufferAttribute { set( value, offset = 0 ) { + // Matching BufferAttribute constructor, do not normalize the array. this.array.set( value, offset ); return this; @@ -9644,12 +9450,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; @@ -9658,12 +9470,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; @@ -9672,12 +9490,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; @@ -9686,12 +9510,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; @@ -9702,6 +9532,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; @@ -9713,6 +9550,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; @@ -9725,6 +9570,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; @@ -9753,7 +9607,7 @@ class BufferAttribute { const data = { itemSize: this.itemSize, type: this.array.constructor.name, - array: Array.prototype.slice.call( this.array ), + array: Array.from( this.array ), normalized: this.normalized }; @@ -9765,6 +9619,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.' ); + + } + } // @@ -10588,49 +10468,11 @@ class BufferGeometry extends EventDispatcher { } - 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; + // @deprecated since r144 - 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; } @@ -10868,7 +10710,7 @@ class BufferGeometry extends EventDispatcher { clone() { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); } @@ -10998,12 +10840,7 @@ 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(); @@ -11083,6 +10920,56 @@ class Mesh extends Object3D { } + getVertexPosition( index, target ) { + + const geometry = this.geometry; + const position = geometry.attributes.position; + const morphPosition = geometry.morphAttributes.position; + const morphTargetsRelative = geometry.morphTargetsRelative; + + target.fromBufferAttribute( position, index ); + + const morphInfluences = this.morphTargetInfluences; + + if ( morphPosition && morphInfluences ) { + + _morphA.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, index ); + + if ( morphTargetsRelative ) { + + _morphA.addScaledVector( _tempA, influence ); + + } else { + + _morphA.addScaledVector( _tempA.sub( target ), influence ); + + } + + } + + target.add( _morphA ); + + } + + if ( this.isSkinnedMesh ) { + + this.boneTransform( index, target ); + + } + + return target; + + } + raycast( raycaster, intersects ) { const geometry = this.geometry; @@ -11117,8 +11004,6 @@ class Mesh extends Object3D { const index = geometry.index; const position = geometry.attributes.position; - const morphPosition = geometry.morphAttributes.position; - const morphTargetsRelative = geometry.morphTargetsRelative; const uv = geometry.attributes.uv; const uv2 = geometry.attributes.uv2; const groups = geometry.groups; @@ -11144,7 +11029,7 @@ class Mesh extends Object3D { 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 ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray$2, uv, uv2, a, b, c ); if ( intersection ) { @@ -11169,7 +11054,7 @@ class Mesh extends Object3D { 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 ); + intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray$2, uv, uv2, a, b, c ); if ( intersection ) { @@ -11202,7 +11087,7 @@ class Mesh extends Object3D { const b = j + 1; const c = j + 2; - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray$2, uv, uv2, a, b, c ); if ( intersection ) { @@ -11227,7 +11112,7 @@ class Mesh extends Object3D { const b = i + 1; const c = i + 2; - intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); + intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray$2, uv, uv2, a, b, c ); if ( intersection ) { @@ -11256,7 +11141,7 @@ function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point } else { - intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point ); + intersect = ray.intersectTriangle( pA, pB, pC, ( material.side === FrontSide ), point ); } @@ -11277,60 +11162,11 @@ function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point } -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 ); +function checkBufferGeometryIntersection( object, material, raycaster, ray, uv, uv2, a, b, 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 ); - - } + object.getVertexPosition( a, _vA$1 ); + object.getVertexPosition( b, _vB$1 ); + object.getVertexPosition( c, _vC$1 ); const intersection = checkIntersection( object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint ); @@ -11600,6 +11436,33 @@ function mergeUniforms( uniforms ) { } +function cloneUniformsGroups( src ) { + + const dst = []; + + for ( let u = 0; u < src.length; u ++ ) { + + dst.push( src[ u ].clone() ); + + } + + return dst; + +} + +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 }; @@ -11620,6 +11483,7 @@ class ShaderMaterial extends Material { this.defines = {}; this.uniforms = {}; + this.uniformsGroups = []; this.vertexShader = default_vertex; this.fragmentShader = default_fragment; @@ -11655,12 +11519,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 ); } @@ -11675,6 +11533,7 @@ class ShaderMaterial extends Material { this.vertexShader = source.vertexShader; this.uniforms = cloneUniforms( source.uniforms ); + this.uniformsGroups = cloneUniformsGroups( source.uniformsGroups ); this.defines = Object.assign( {}, source.defines ); @@ -12080,7 +11939,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 { @@ -12090,49 +11950,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 ); } @@ -12219,7 +12072,7 @@ class CubeTexture extends Texture { class WebGLCubeRenderTarget extends WebGLRenderTarget { - constructor( size, options = {} ) { + constructor( size = 1, options = {} ) { super( size, size, options ); @@ -12876,6 +12729,8 @@ function WebGLAttributes( gl, capabilities ) { } + attribute.onUploadCallback(); + } // @@ -12958,6 +12813,7 @@ class PlaneGeometry extends BufferGeometry { constructor( width = 1, height = 1, widthSegments = 1, heightSegments = 1 ) { super(); + this.type = 'PlaneGeometry'; this.parameters = { @@ -13052,11 +12908,11 @@ var begin_vertex = "vec3 transformed = vec3( position );"; var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; -var bsdfs = "vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\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 dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( V * D );\n}\n#ifdef USE_IRIDESCENCE\nvec3 BRDF_GGX_Iridescence( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float iridescence, const in vec3 iridescenceFresnel, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\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 dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = mix(F_Schlick( f0, f90, dotVH ), iridescenceFresnel, iridescence);\n\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( V * D );\n}\n#endif\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\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"; +var bsdfs = "vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\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 dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( V * D );\n}\n#ifdef USE_IRIDESCENCE\n\tvec3 BRDF_GGX_Iridescence( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float iridescence, const in vec3 iridescenceFresnel, const in float roughness ) {\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = mix( F_Schlick( f0, f90, dotVH ), iridescenceFresnel, iridescence );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\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"; -var iridescence_fragment = "#ifdef USE_IRIDESCENCE\nconst mat3 XYZ_TO_REC709 = mat3(\n 3.2404542, -0.9692660, 0.0556434,\n -1.5371385, 1.8760108, -0.2040259,\n -0.4985314, 0.0415560, 1.0572252\n);\nvec3 Fresnel0ToIor( vec3 fresnel0 ) {\n vec3 sqrtF0 = sqrt( fresnel0 );\n return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n}\nvec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n return pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n}\nfloat IorToFresnel0( float transmittedIor, float incidentIor ) {\n return pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n}\nvec3 evalSensitivity( float OPD, vec3 shift ) {\n float phase = 2.0 * PI * OPD * 1.0e-9;\n vec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n vec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n vec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n vec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( -pow2( phase ) * var );\n xyz.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 xyz /= 1.0685e-7;\n vec3 srgb = XYZ_TO_REC709 * xyz;\n return srgb;\n}\nvec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n vec3 I;\n float iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n float sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n float cosTheta2Sq = 1.0 - sinTheta2Sq;\n if ( cosTheta2Sq < 0.0 ) {\n return vec3( 1.0 );\n }\n float cosTheta2 = sqrt( cosTheta2Sq );\n float R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\n float R12 = F_Schlick( R0, 1.0, cosTheta1 );\n float R21 = R12;\n float T121 = 1.0 - R12;\n float phi12 = 0.0;\n if ( iridescenceIOR < outsideIOR ) phi12 = PI;\n float phi21 = PI - phi12;\n vec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) ); vec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n vec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n vec3 phi23 = vec3( 0.0 );\n if ( baseIOR[0] < iridescenceIOR ) phi23[0] = PI;\n if ( baseIOR[1] < iridescenceIOR ) phi23[1] = PI;\n if ( baseIOR[2] < iridescenceIOR ) phi23[2] = PI;\n float OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n vec3 phi = vec3( phi21 ) + phi23;\n vec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n vec3 r123 = sqrt( R123 );\n vec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n vec3 C0 = R12 + Rs;\n I = C0;\n vec3 Cm = Rs - T121;\n for ( int m = 1; m <= 2; ++m ) {\n Cm *= r123;\n vec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n I += Cm * Sm;\n }\n return max( I, vec3( 0.0 ) );\n}\n#endif"; +var iridescence_fragment = "#ifdef USE_IRIDESCENCE\n\tconst mat3 XYZ_TO_REC709 = mat3(\n\t\t 3.2404542, -0.9692660, 0.0556434,\n\t\t-1.5371385, 1.8760108, -0.2040259,\n\t\t-0.4985314, 0.0415560, 1.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"; -var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 ) * 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"; +var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, 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"; var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; @@ -13074,9 +12930,9 @@ var color_pars_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\ var 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"; -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 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat 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 linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}"; +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\thighp vec2 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"; @@ -13092,13 +12948,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"; @@ -13110,13 +12966,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"; @@ -13124,17 +12982,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\nfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\nif ( material.iridescenceThickness == 0.0 ) {\n\tmaterial.iridescence = 0.0;\n} else {\n\tmaterial.iridescence = saturate( material.iridescence );\n}\nif ( material.iridescence > 0.0 ) {\n\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n}\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 *= ( 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 *= ( 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 *= ( 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 ) || defined( ENVMAP_TYPE_CUBE ) )\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"; @@ -13168,7 +13026,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"; @@ -13178,7 +13036,7 @@ var normal_pars_vertex = "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef var 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"; -var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN, float faceDirection ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\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"; +var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN, 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"; var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif"; @@ -13188,9 +13046,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"; @@ -13204,13 +13062,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\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\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_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\tvec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#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#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"; @@ -13228,9 +13086,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"; @@ -13244,15 +13102,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$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 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$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 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$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}"; @@ -13272,11 +13134,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}"; @@ -13288,7 +13150,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}"; @@ -13352,7 +13214,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, @@ -13417,8 +13280,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, @@ -13459,12 +13324,12 @@ const UniformsLib = { common: { - diffuse: { value: new Color( 0xffffff ) }, + diffuse: { value: /*@__PURE__*/ new Color( 0xffffff ) }, opacity: { value: 1.0 }, map: { value: null }, - uvTransform: { value: new Matrix3() }, - uv2Transform: { value: new Matrix3() }, + uvTransform: { value: /*@__PURE__*/ new Matrix3() }, + uv2Transform: { value: /*@__PURE__*/ new Matrix3() }, alphaMap: { value: null }, alphaTest: { value: 0 } @@ -13483,7 +13348,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 }, @@ -13517,7 +13382,7 @@ const UniformsLib = { normalmap: { normalMap: { value: null }, - normalScale: { value: new Vector2( 1, 1 ) } + normalScale: { value: /*@__PURE__*/ new Vector2( 1, 1 ) } }, @@ -13552,7 +13417,7 @@ const UniformsLib = { fogDensity: { value: 0.00025 }, fogNear: { value: 1 }, fogFar: { value: 2000 }, - fogColor: { value: new Color( 0xffffff ) } + fogColor: { value: /*@__PURE__*/ new Color( 0xffffff ) } }, @@ -13594,8 +13459,9 @@ const UniformsLib = { shadowMapSize: {} } }, + spotLightMap: { value: [] }, spotShadowMap: { value: [] }, - spotShadowMatrix: { value: [] }, + spotLightMatrix: { value: [] }, pointLights: { value: [], properties: { color: {}, @@ -13637,27 +13503,27 @@ const UniformsLib = { points: { - diffuse: { value: new Color( 0xffffff ) }, + diffuse: { value: /*@__PURE__*/ new Color( 0xffffff ) }, opacity: { value: 1.0 }, size: { value: 1.0 }, scale: { value: 1.0 }, map: { value: null }, alphaMap: { value: null }, alphaTest: { value: 0 }, - uvTransform: { value: new Matrix3() } + uvTransform: { value: /*@__PURE__*/ new Matrix3() } }, sprite: { - diffuse: { value: new Color( 0xffffff ) }, + diffuse: { value: /*@__PURE__*/ new Color( 0xffffff ) }, opacity: { value: 1.0 }, - center: { value: new Vector2( 0.5, 0.5 ) }, + center: { value: /*@__PURE__*/ new Vector2( 0.5, 0.5 ) }, rotation: { value: 0.0 }, map: { value: null }, alphaMap: { value: null }, alphaTest: { value: 0 }, - uvTransform: { value: new Matrix3() } + uvTransform: { value: /*@__PURE__*/ new Matrix3() } } @@ -13667,7 +13533,7 @@ const ShaderLib = { basic: { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, @@ -13683,17 +13549,20 @@ const ShaderLib = { lambert: { - uniforms: mergeUniforms( [ + 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: new Color( 0x000000 ) } + emissive: { value: /*@__PURE__*/ new Color( 0x000000 ) } } ] ), @@ -13704,7 +13573,7 @@ const ShaderLib = { phong: { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, @@ -13717,8 +13586,8 @@ const ShaderLib = { UniformsLib.fog, UniformsLib.lights, { - emissive: { value: new Color( 0x000000 ) }, - specular: { value: new Color( 0x111111 ) }, + emissive: { value: /*@__PURE__*/ new Color( 0x000000 ) }, + specular: { value: /*@__PURE__*/ new Color( 0x111111 ) }, shininess: { value: 30 } } ] ), @@ -13730,7 +13599,7 @@ const ShaderLib = { standard: { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ UniformsLib.common, UniformsLib.envmap, UniformsLib.aomap, @@ -13744,7 +13613,7 @@ const ShaderLib = { UniformsLib.fog, UniformsLib.lights, { - emissive: { value: new Color( 0x000000 ) }, + emissive: { value: /*@__PURE__*/ new Color( 0x000000 ) }, roughness: { value: 1.0 }, metalness: { value: 0.0 }, envMapIntensity: { value: 1 } // temporary @@ -13758,7 +13627,7 @@ const ShaderLib = { toon: { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ UniformsLib.common, UniformsLib.aomap, UniformsLib.lightmap, @@ -13770,7 +13639,7 @@ const ShaderLib = { UniformsLib.fog, UniformsLib.lights, { - emissive: { value: new Color( 0x000000 ) } + emissive: { value: /*@__PURE__*/ new Color( 0x000000 ) } } ] ), @@ -13781,7 +13650,7 @@ const ShaderLib = { matcap: { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, @@ -13799,7 +13668,7 @@ const ShaderLib = { points: { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ UniformsLib.points, UniformsLib.fog ] ), @@ -13811,7 +13680,7 @@ const ShaderLib = { dashed: { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ UniformsLib.common, UniformsLib.fog, { @@ -13828,7 +13697,7 @@ const ShaderLib = { depth: { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ UniformsLib.common, UniformsLib.displacementmap ] ), @@ -13840,7 +13709,7 @@ const ShaderLib = { normal: { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, @@ -13857,7 +13726,7 @@ const ShaderLib = { sprite: { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ UniformsLib.sprite, UniformsLib.fog ] ), @@ -13870,26 +13739,37 @@ const ShaderLib = { background: { uniforms: { - uvTransform: { value: new Matrix3() }, + uvTransform: { value: /*@__PURE__*/ new Matrix3() }, t2D: { value: null }, + backgroundIntensity: { value: 1 } }, vertexShader: ShaderChunk.background_vert, fragmentShader: ShaderChunk.background_frag }, - /* ------------------------------------------------------------------------- - // Cube map shader - ------------------------------------------------------------------------- */ + + backgroundCube: { + + uniforms: { + envMap: { value: null }, + flipEnvMap: { value: - 1 }, + backgroundBlurriness: { value: 0 }, + backgroundIntensity: { value: 1 } + }, + + vertexShader: ShaderChunk.backgroundCube_vert, + fragmentShader: ShaderChunk.backgroundCube_frag + + }, cube: { - uniforms: 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 @@ -13909,11 +13789,11 @@ const ShaderLib = { distanceRGBA: { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ UniformsLib.common, UniformsLib.displacementmap, { - referencePosition: { value: new Vector3() }, + referencePosition: { value: /*@__PURE__*/ new Vector3() }, nearDistance: { value: 1 }, farDistance: { value: 1000 } } @@ -13926,11 +13806,11 @@ const ShaderLib = { shadow: { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ UniformsLib.lights, UniformsLib.fog, { - color: { value: new Color( 0x00000 ) }, + color: { value: /*@__PURE__*/ new Color( 0x00000 ) }, opacity: { value: 1.0 } }, ] ), @@ -13944,14 +13824,14 @@ const ShaderLib = { ShaderLib.physical = { - uniforms: mergeUniforms( [ + uniforms: /*@__PURE__*/ mergeUniforms( [ ShaderLib.standard.uniforms, { clearcoat: { value: 0 }, clearcoatMap: { value: null }, clearcoatRoughness: { value: 0 }, clearcoatRoughnessMap: { value: null }, - clearcoatNormalScale: { value: new Vector2( 1, 1 ) }, + clearcoatNormalScale: { value: /*@__PURE__*/ new Vector2( 1, 1 ) }, clearcoatNormalMap: { value: null }, iridescence: { value: 0 }, iridescenceMap: { value: null }, @@ -13960,21 +13840,21 @@ ShaderLib.physical = { iridescenceThicknessMaximum: { value: 400 }, iridescenceThicknessMap: { value: null }, sheen: { value: 0 }, - sheenColor: { value: new Color( 0x000000 ) }, + sheenColor: { value: /*@__PURE__*/ new Color( 0x000000 ) }, sheenColorMap: { value: null }, sheenRoughness: { value: 1 }, sheenRoughnessMap: { value: null }, transmission: { value: 0 }, transmissionMap: { value: null }, - transmissionSamplerSize: { value: new Vector2() }, + transmissionSamplerSize: { value: /*@__PURE__*/ new Vector2() }, transmissionSamplerMap: { value: null }, thickness: { value: 0 }, thicknessMap: { value: null }, attenuationDistance: { value: 0 }, - attenuationColor: { value: new Color( 0x000000 ) }, + attenuationColor: { value: /*@__PURE__*/ new Color( 0x000000 ) }, specularIntensity: { value: 1 }, specularIntensityMap: { value: null }, - specularColor: { value: new Color( 1, 1, 1 ) }, + specularColor: { value: /*@__PURE__*/ new Color( 1, 1, 1 ) }, specularColorMap: { value: null }, } ] ), @@ -13984,7 +13864,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; @@ -14003,7 +13885,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 ); } @@ -14044,9 +13927,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, @@ -14063,7 +13946,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 () { @@ -14080,6 +13963,9 @@ 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; + boxMesh.material.toneMapped = ( background.encoding === sRGBEncoding ) ? false : true; if ( currentBackground !== background || currentBackgroundVersion !== background.version || @@ -14118,7 +14004,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 () { @@ -14134,6 +14020,8 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli } planeMesh.material.uniforms.t2D.value = background; + planeMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity; + planeMesh.material.toneMapped = ( background.encoding === sRGBEncoding ) ? false : true; if ( background.matrixAutoUpdate === true ) { @@ -14166,7 +14054,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 ); } @@ -14935,8 +14825,7 @@ function WebGLCapabilities( gl, extensions, parameters ) { } - const isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext ) || - ( typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext ); + const isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext; let precision = parameters.precision !== undefined ? parameters.precision : 'highp'; const maxPrecision = getMaxPrecision( precision ); @@ -15018,7 +14907,7 @@ function WebGLClipping( properties ) { this.numPlanes = 0; this.numIntersection = 0; - this.init = function ( planes, enableLocalClipping, camera ) { + this.init = function ( planes, enableLocalClipping ) { const enabled = planes.length !== 0 || @@ -15030,7 +14919,6 @@ function WebGLClipping( properties ) { localClippingEnabled = enableLocalClipping; - globalState = projectPlanes( planes, camera, 0 ); numGlobalPlanes = planes.length; return enabled; @@ -15047,7 +14935,12 @@ function WebGLClipping( properties ) { this.endShadows = function () { renderingShadows = false; - resetGlobalState(); + + }; + + this.setGlobalState = function ( planes, camera ) { + + globalState = projectPlanes( planes, camera, 0 ); }; @@ -15674,7 +15567,7 @@ class PMREMGenerator { const cubeUVRenderTarget = _createRenderTarget( width, height, params ); - if ( this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width ) { + if ( this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width || this._pingPongRenderTarget.height !== height ) { if ( this._pingPongRenderTarget !== null ) { @@ -16882,20 +16775,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 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 = {}; @@ -16979,8 +16858,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; @@ -16992,8 +16869,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; @@ -17005,8 +16880,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; @@ -17296,10 +17169,10 @@ function WebGLObjects( gl, geometries, attributes, info ) { * */ -const emptyTexture = new Texture(); -const emptyArrayTexture = new DataArrayTexture(); -const empty3dTexture = new Data3DTexture(); -const emptyCubeTexture = new CubeTexture(); +const emptyTexture = /*@__PURE__*/ new Texture(); +const emptyArrayTexture = /*@__PURE__*/ new DataArrayTexture(); +const empty3dTexture = /*@__PURE__*/ new Data3DTexture(); +const emptyCubeTexture = /*@__PURE__*/ new CubeTexture(); // --- Utilities --- @@ -17612,17 +17485,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; + + } + + } else { + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform2iv( this.addr, v ); - copyArray( cache, v ); + copyArray( cache, v ); + + } } @@ -17630,11 +17518,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 ); - copyArray( cache, v ); + 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 ); + + } } @@ -17642,11 +17546,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; + + gl.uniform4iv( this.addr, v ); + + copyArray( cache, v ); - copyArray( cache, v ); + } } @@ -17664,17 +17585,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 ) { - copyArray( cache, v ); + 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 ); + + } } @@ -17682,11 +17618,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; - copyArray( cache, v ); + } + + } else { + + if ( arraysEqual( cache, v ) ) return; + + gl.uniform3uiv( this.addr, v ); + + copyArray( cache, v ); + + } } @@ -17694,11 +17646,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 ); + + } } @@ -17944,11 +17913,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 ) { @@ -17960,11 +17937,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 ) { @@ -17976,11 +17961,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 ) { @@ -17992,11 +17985,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 ) { @@ -18449,13 +18450,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 ); @@ -18495,21 +18501,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 ); } @@ -19269,29 +19265,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; } @@ -19504,12 +19503,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, @@ -19612,11 +19613,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 ); @@ -19695,60 +19698,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 ); @@ -20089,23 +20092,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 ]; } @@ -20268,9 +20272,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 ); } @@ -20293,7 +20297,8 @@ function WebGLLights( extensions, capabilities ) { numDirectionalShadows: - 1, numPointShadows: - 1, - numSpotShadows: - 1 + numSpotShadows: - 1, + numSpotMaps: - 1 }, ambient: [ 0, 0, 0 ], @@ -20303,9 +20308,10 @@ function WebGLLights( extensions, capabilities ) { directionalShadowMap: [], directionalShadowMatrix: [], spot: [], + spotLightMap: [], spotShadow: [], spotShadowMap: [], - spotShadowMatrix: [], + spotLightMatrix: [], rectArea: [], rectAreaLTC1: null, rectAreaLTC2: null, @@ -20313,7 +20319,8 @@ function WebGLLights( extensions, capabilities ) { pointShadow: [], pointShadowMap: [], pointShadowMatrix: [], - hemi: [] + hemi: [], + numSpotLightShadowsWithMaps: 0 }; @@ -20338,8 +20345,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; @@ -20410,9 +20420,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 ); @@ -20423,24 +20450,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 ); @@ -20544,7 +20564,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; @@ -20560,7 +20581,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; @@ -20571,6 +20594,7 @@ function WebGLLights( extensions, capabilities ) { hash.numDirectionalShadows = numDirectionalShadows; hash.numPointShadows = numPointShadows; hash.numSpotShadows = numSpotShadows; + hash.numSpotMaps = numSpotMaps; state.version = nextVersion ++; @@ -20733,23 +20757,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 ]; } @@ -20890,7 +20915,7 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) { _maxTextureSize = _capabilities.maxTextureSize; - const shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide }; + const shadowSide = { [ FrontSide ]: BackSide, [ BackSide ]: FrontSide, [ DoubleSide ]: DoubleSide }; const shadowMaterialVertical = new ShaderMaterial( { defines: { @@ -20993,20 +21018,9 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) { } - if ( shadow.map === null && ! shadow.isPointLightShadow && this.type === VSMShadowMap ) { - - shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y ); - shadow.map.texture.name = light.name + '.shadowMap'; - - shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y ); - - shadow.camera.updateProjectionMatrix(); - - } - if ( shadow.map === null ) { - const pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; + const pars = ( this.type !== VSMShadowMap ) ? { minFilter: NearestFilter, magFilter: NearestFilter } : {}; shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); shadow.map.texture.name = light.name + '.shadowMap'; @@ -21043,7 +21057,7 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) { // do blur pass for VSM - if ( ! shadow.isPointLightShadow && this.type === VSMShadowMap ) { + if ( shadow.isPointLightShadow !== true && this.type === VSMShadowMap ) { VSMPass( shadow, camera ); @@ -21073,6 +21087,12 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) { } + if ( shadow.mapPass === null ) { + + shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y ); + + } + // vertical pass shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; @@ -21107,37 +21127,38 @@ function WebGLShadowMap( _renderer, _objects, _capabilities ) { 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 ) || + ( material.map && material.alphaTest > 0 ) ) { + + // in this case we need a unique material instance reflecting the + // appropriate state - if ( ( _renderer.localClippingEnabled && material.clipShadows === true && material.clippingPlanes.length !== 0 ) || - ( material.displacementMap && material.displacementScale !== 0 ) || - ( material.alphaMap && material.alphaTest > 0 ) ) { + const keyA = result.uuid, keyB = material.uuid; - // in this case we need a unique material instance reflecting the - // appropriate state + let materialsForVariant = _materialCache[ keyA ]; - const keyA = result.uuid, keyB = material.uuid; + if ( materialsForVariant === undefined ) { - let materialsForVariant = _materialCache[ keyA ]; + materialsForVariant = {}; + _materialCache[ keyA ] = materialsForVariant; - if ( materialsForVariant === undefined ) { + } - materialsForVariant = {}; - _materialCache[ keyA ] = materialsForVariant; + let cachedMaterial = materialsForVariant[ keyB ]; - } + if ( cachedMaterial === undefined ) { - let cachedMaterial = materialsForVariant[ keyB ]; + cachedMaterial = result.clone(); + materialsForVariant[ keyB ] = cachedMaterial; - if ( cachedMaterial === undefined ) { + } - cachedMaterial = result.clone(); - materialsForVariant[ keyB ] = cachedMaterial; + result = cachedMaterial; } - result = cachedMaterial; - } result.visible = material.visible; @@ -21155,6 +21176,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; @@ -21339,59 +21361,51 @@ function WebGLState( gl, extensions, capabilities ) { if ( currentDepthFunc !== depthFunc ) { - if ( depthFunc ) { + switch ( depthFunc ) { - switch ( depthFunc ) { + case NeverDepth: - case NeverDepth: - - gl.depthFunc( 512 ); - break; - - case AlwaysDepth: - - gl.depthFunc( 519 ); - break; - - case LessDepth: + gl.depthFunc( 512 ); + break; - gl.depthFunc( 513 ); - break; + case AlwaysDepth: - case LessEqualDepth: + gl.depthFunc( 519 ); + break; - gl.depthFunc( 515 ); - break; + case LessDepth: - case EqualDepth: + gl.depthFunc( 513 ); + break; - gl.depthFunc( 514 ); - break; + case LessEqualDepth: - case GreaterEqualDepth: + gl.depthFunc( 515 ); + break; - gl.depthFunc( 518 ); - break; + case EqualDepth: - case GreaterDepth: + gl.depthFunc( 514 ); + break; - gl.depthFunc( 516 ); - break; + case GreaterEqualDepth: - 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 ); } @@ -21550,6 +21564,9 @@ function WebGLState( gl, extensions, capabilities ) { const depthBuffer = new DepthBuffer(); const stencilBuffer = new StencilBuffer(); + const uboBindings = new WeakMap(); + const uboProgramMap = new WeakMap(); + let enabledCapabilities = {}; let currentBoundFramebuffers = {}; @@ -21959,7 +21976,7 @@ function WebGLState( gl, extensions, capabilities ) { } currentBlending = blending; - currentPremultipledAlpha = null; + currentPremultipledAlpha = false; } @@ -22121,25 +22138,40 @@ function WebGLState( gl, extensions, capabilities ) { } - function bindTexture( webglType, webglTexture ) { + function bindTexture( webglType, webglTexture, webglSlot ) { + + if ( webglSlot === undefined ) { - if ( currentTextureSlot === null ) { + if ( currentTextureSlot === null ) { - activeTexture(); + webglSlot = 33984 + 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; @@ -22178,6 +22210,20 @@ function WebGLState( gl, extensions, capabilities ) { } + function compressedTexImage3D() { + + try { + + gl.compressedTexImage3D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } + + } + function texSubImage2D() { try { @@ -22220,6 +22266,20 @@ function WebGLState( gl, extensions, capabilities ) { } + function compressedTexSubImage3D() { + + try { + + gl.compressedTexSubImage3D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( 'THREE.WebGLState:', error ); + + } + + } + function texStorage2D() { try { @@ -22300,6 +22360,46 @@ function WebGLState( gl, extensions, capabilities ) { } + function updateUBOMapping( uniformsGroup, program ) { + + let mapping = uboProgramMap.get( program ); + + if ( mapping === undefined ) { + + mapping = new WeakMap(); + + uboProgramMap.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 = uboProgramMap.get( program ); + const blockIndex = mapping.get( uniformsGroup ); + + if ( uboBindings.get( program ) !== blockIndex ) { + + // bind shader specific block index to global block point + gl.uniformBlockBinding( program, blockIndex, uniformsGroup.__bindingPointIndex ); + + uboBindings.set( program, blockIndex ); + + } + + } + // function reset() { @@ -22424,14 +22524,19 @@ function WebGLState( gl, extensions, capabilities ) { bindTexture: bindTexture, unbindTexture: unbindTexture, compressedTexImage2D: compressedTexImage2D, + compressedTexImage3D: compressedTexImage3D, texImage2D: texImage2D, texImage3D: texImage3D, + updateUBOMapping: updateUBOMapping, + uniformBlockBinding: uniformBlockBinding, + texStorage2D: texStorage2D, texStorage3D: texStorage3D, texSubImage2D: texSubImage2D, texSubImage3D: texSubImage3D, compressedTexSubImage2D: compressedTexSubImage2D, + compressedTexSubImage3D: compressedTexSubImage3D, scissor: scissor, viewport: viewport, @@ -22450,7 +22555,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; @@ -22574,7 +22679,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; @@ -22608,7 +22713,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; @@ -22854,6 +22959,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 ); @@ -22899,8 +23005,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 ); } @@ -22915,8 +23020,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 ); } @@ -22931,8 +23035,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 ); } @@ -22947,8 +23050,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 ); } @@ -23016,6 +23118,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, const extension = extensions.get( 'EXT_texture_filter_anisotropic' ); + if ( texture.magFilter === NearestFilter ) return; + if ( texture.minFilter !== NearestMipmapLinearFilter && texture.minFilter !== LinearMipmapLinearFilter ) return; 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 @@ -23114,16 +23218,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 !== sourceProperties.__version || forceUpload === true ) { - if ( source.version !== source.__currentVersion || forceUpload === true ) { + state.activeTexture( 33984 + slot ); _gl.pixelStorei( 37440, texture.flipY ); _gl.pixelStorei( 37441, texture.premultiplyAlpha ); @@ -23146,7 +23253,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 ) { @@ -23293,45 +23400,97 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } else if ( texture.isCompressedTexture ) { - if ( useTexStorage && allocateMemory ) { + if ( texture.isCompressedArrayTexture ) { - state.texStorage2D( 3553, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height ); + if ( useTexStorage && allocateMemory ) { - } + state.texStorage3D( 35866, 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( 35866, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data, 0, 0 ); + + } else { - state.compressedTexSubImage2D( 3553, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data ); + 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 ); + + } } @@ -23462,7 +23621,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - source.__currentVersion = source.version; + sourceProperties.__version = source.version; if ( texture.onUpdate ) texture.onUpdate( texture ); @@ -23479,10 +23638,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 ); @@ -23517,7 +23679,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 ); @@ -23666,7 +23828,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - source.__currentVersion = source.version; + sourceProperties.__version = source.version; if ( texture.onUpdate ) texture.onUpdate( texture ); @@ -23706,7 +23868,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 ); @@ -24030,7 +24192,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 ); @@ -24421,14 +24583,6 @@ 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; - - 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 6408; - - } // WebGL 1 sRGB fallback @@ -24450,6 +24604,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; @@ -24608,6 +24763,27 @@ function WebGLUtils( gl, extensions, capabilities ) { } + // RGTC + + if ( p === RED_RGTC1_Format || p === SIGNED_RED_RGTC1_Format || p === RED_GREEN_RGTC2_Format || p === SIGNED_RED_GREEN_RGTC2_Format ) { + + extension = extensions.get( 'EXT_texture_compression_rgtc' ); + + if ( extension !== null ) { + + if ( p === RGBA_BPTC_Format ) return extension.COMPRESSED_RED_RGTC1_EXT; + if ( p === SIGNED_RED_RGTC1_Format ) return extension.COMPRESSED_SIGNED_RED_RGTC1_EXT; + if ( p === RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_RED_GREEN_RGTC2_EXT; + if ( p === SIGNED_RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT; + + } else { + + return null; + + } + + } + // if ( p === UnsignedInt248Type ) { @@ -24755,6 +24931,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 } ); @@ -24793,43 +24994,6 @@ class WebXRController { if ( inputSource && frame.session.visibilityState !== 'visible-blurred' ) { - if ( targetRay !== null ) { - - inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace ); - - 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 ( hand && inputSource.hand ) { handPose = true; @@ -24839,19 +25003,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 ) { @@ -24934,6 +25087,51 @@ 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 + 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 ) { @@ -24958,6 +25156,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 { @@ -25005,6 +25222,8 @@ class WebXRManager extends EventDispatcher { let referenceSpace = null; let referenceSpaceType = 'local-floor'; + // Set default foveation to maximum. + let foveation = 1.0; let customReferenceSpace = null; let pose = null; @@ -25017,7 +25236,10 @@ class WebXRManager extends EventDispatcher { let newRenderTarget = null; const controllers = []; - const inputSourcesMap = new Map(); + const controllerInputSources = []; + + const planes = new Set(); + const planesLastChangedTimes = new Map(); // @@ -25094,7 +25316,15 @@ class WebXRManager extends EventDispatcher { function onSessionEvent( event ) { - const controller = inputSourcesMap.get( event.inputSource ); + const controllerIndex = controllerInputSources.indexOf( event.inputSource ); + + if ( controllerIndex === - 1 ) { + + return; + + } + + const controller = controllers[ controllerIndex ]; if ( controller !== undefined ) { @@ -25115,17 +25345,17 @@ class WebXRManager extends EventDispatcher { session.removeEventListener( 'end', onSessionEnd ); session.removeEventListener( 'inputsourceschange', onInputSourcesChange ); - inputSourcesMap.forEach( function ( controller, inputSource ) { + for ( let i = 0; i < controllers.length; i ++ ) { - if ( controller !== undefined ) { + const inputSource = controllerInputSources[ i ]; - controller.disconnect( inputSource ); + if ( inputSource === null ) continue; - } + controllerInputSources[ i ] = null; - } ); + controllers[ i ].disconnect( inputSource ); - inputSourcesMap.clear(); + } _currentDepthNear = null; _currentDepthFar = null; @@ -25253,7 +25483,8 @@ class WebXRManager extends EventDispatcher { { format: RGBAFormat, type: UnsignedByteType, - encoding: renderer.outputEncoding + encoding: renderer.outputEncoding, + stencilBuffer: attributes.stencil } ); @@ -25272,7 +25503,7 @@ class WebXRManager extends EventDispatcher { } const projectionlayerInit = { - colorFormat: ( renderer.outputEncoding === sRGBEncoding ) ? 35907 : 32856, + colorFormat: 32856, depthFormat: glDepthFormat, scaleFactor: framebufferScaleFactor }; @@ -25302,8 +25533,7 @@ class WebXRManager extends EventDispatcher { newRenderTarget.isXRRenderTarget = true; // TODO Remove this when possible, see #23278 - // Set foveation to maximum. - this.setFoveation( 1.0 ); + this.setFoveation( foveation ); customReferenceSpace = null; referenceSpace = await session.requestReferenceSpace( referenceSpaceType ); @@ -25321,28 +25551,17 @@ class WebXRManager extends EventDispatcher { function onInputSourcesChange( event ) { - const inputSources = session.inputSources; - - // Assign controllers to available inputSources - - for ( let i = 0; i < inputSources.length; i ++ ) { - - const index = inputSources[ i ].handedness === 'right' ? 1 : 0; - inputSourcesMap.set( inputSources[ i ], controllers[ index ] ); - - } - // Notify disconnected for ( let i = 0; i < event.removed.length; i ++ ) { const inputSource = event.removed[ i ]; - const controller = inputSourcesMap.get( inputSource ); + const index = controllerInputSources.indexOf( inputSource ); - if ( controller ) { + if ( index >= 0 ) { - controller.dispatchEvent( { type: 'disconnected', data: inputSource } ); - inputSourcesMap.delete( inputSource ); + controllerInputSources[ index ] = null; + controllers[ index ].disconnect( inputSource ); } @@ -25353,11 +25572,42 @@ class WebXRManager extends EventDispatcher { for ( let i = 0; i < event.added.length; i ++ ) { const inputSource = event.added[ i ]; - const controller = inputSourcesMap.get( inputSource ); + + 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 ); + controllerIndex = i; + break; + + } else if ( controllerInputSources[ i ] === null ) { + + controllerInputSources[ i ] = inputSource; + controllerIndex = i; + break; + + } + + } + + // 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 ); } @@ -25477,11 +25727,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; @@ -25515,41 +25762,43 @@ class WebXRManager extends EventDispatcher { this.getFoveation = function () { - if ( glProjLayer !== null ) { - - return glProjLayer.fixedFoveation; - - } - - if ( glBaseLayer !== null ) { + if ( glProjLayer === null && glBaseLayer === null ) { - return glBaseLayer.fixedFoveation; + return undefined; } - return undefined; + return foveation; }; - this.setFoveation = function ( foveation ) { + this.setFoveation = function ( value ) { // 0 = no foveation = full resolution // 1 = maximum foveation = the edges render at lower resolution + foveation = value; + if ( glProjLayer !== null ) { - glProjLayer.fixedFoveation = foveation; + glProjLayer.fixedFoveation = value; } if ( glBaseLayer !== null && glBaseLayer.fixedFoveation !== undefined ) { - glBaseLayer.fixedFoveation = foveation; + glBaseLayer.fixedFoveation = value; } }; + this.getPlanes = function () { + + return planes; + + }; + // Animation Loop let onAnimationFrameCallback = null; @@ -25643,14 +25892,12 @@ class WebXRManager extends EventDispatcher { // - const inputSources = session.inputSources; - for ( let i = 0; i < controllers.length; i ++ ) { - const inputSource = inputSources[ i ]; - const controller = inputSourcesMap.get( inputSource ); + const inputSource = controllerInputSources[ i ]; + const controller = controllers[ i ]; - if ( controller !== undefined ) { + if ( inputSource !== null && controller !== undefined ) { controller.update( inputSource, frame, customReferenceSpace || referenceSpace ); @@ -25660,6 +25907,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; } @@ -25684,7 +25990,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 ) { @@ -26354,6 +26660,417 @@ function WebGLMaterials( renderer, properties ) { } +function WebGLUniformsGroups( gl, info, capabilities, state ) { + + let buffers = {}; + let updateList = {}; + let allocatedBindingPoints = []; + + const maxBindingPoints = ( capabilities.isWebGL2 ) ? gl.getParameter( 35375 ) : 0; // binding points are global whereas block indices are per shader program + + function bind( uniformsGroup, program ) { + + 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 + + const webglProgram = program.program; + state.updateUBOMapping( uniformsGroup, webglProgram ); + + // 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(); + const size = uniformsGroup.__size; + const usage = uniformsGroup.usage; + + gl.bindBuffer( 35345, buffer ); + gl.bufferData( 35345, size, usage ); + gl.bindBuffer( 35345, null ); + gl.bindBufferBase( 35345, bindingPointIndex, buffer ); + + return buffer; + + } + + function allocateBindingPointIndex() { + + for ( let i = 0; i < maxBindingPoints; i ++ ) { + + if ( allocatedBindingPoints.indexOf( i ) === - 1 ) { + + allocatedBindingPoints.push( i ); + 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( 35345, buffer ); + + for ( let i = 0, il = uniforms.length; i < il; i ++ ) { + + const uniform = uniforms[ i ]; + + // partly update the buffer if necessary + + if ( hasUniformChanged( uniform, i, cache ) === true ) { + + const offset = uniform.__offset; + + const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ]; + + let arrayOffset = 0; + + for ( let i = 0; i < values.length; i ++ ) { + + const value = values[ i ]; + + const info = getUniformSize( value ); + + if ( typeof value === 'number' ) { + + uniform.__data[ 0 ] = value; + gl.bufferSubData( 35345, offset + arrayOffset, uniform.__data ); + + } else if ( value.isMatrix3 ) { + + // manually converting 3x3 to 3x4 + + uniform.__data[ 0 ] = value.elements[ 0 ]; + uniform.__data[ 1 ] = value.elements[ 1 ]; + uniform.__data[ 2 ] = value.elements[ 2 ]; + uniform.__data[ 3 ] = value.elements[ 0 ]; + uniform.__data[ 4 ] = value.elements[ 3 ]; + uniform.__data[ 5 ] = value.elements[ 4 ]; + uniform.__data[ 6 ] = value.elements[ 5 ]; + uniform.__data[ 7 ] = value.elements[ 0 ]; + uniform.__data[ 8 ] = value.elements[ 6 ]; + uniform.__data[ 9 ] = value.elements[ 7 ]; + uniform.__data[ 10 ] = value.elements[ 8 ]; + uniform.__data[ 11 ] = value.elements[ 0 ]; + + } else { + + value.toArray( uniform.__data, arrayOffset ); + + arrayOffset += info.storage / Float32Array.BYTES_PER_ELEMENT; + + } + + } + + gl.bufferSubData( 35345, offset, uniform.__data ); + + } + + } + + gl.bindBuffer( 35345, 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 { + + const values = Array.isArray( value ) ? value : [ value ]; + + const tempValues = []; + + for ( let i = 0; i < values.length; i ++ ) { + + tempValues.push( values[ i ].clone() ); + + } + + cache[ index ] = tempValues; + + } + + return true; + + } else { + + // compare current value with cached entry + + if ( typeof value === 'number' ) { + + if ( cache[ index ] !== value ) { + + cache[ index ] = value; + return true; + + } + + } else { + + const cachedObjects = Array.isArray( cache[ index ] ) ? cache[ index ] : [ cache[ index ] ]; + const values = Array.isArray( value ) ? value : [ value ]; + + for ( let i = 0; i < cachedObjects.length; i ++ ) { + + const cachedObject = cachedObjects[ i ]; + + if ( cachedObject.equals( values[ i ] ) === false ) { + + cachedObject.copy( values[ i ] ); + 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 infos = { + boundary: 0, // bytes + storage: 0 // bytes + }; + + const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ]; + + for ( let j = 0, jl = values.length; j < jl; j ++ ) { + + const value = values[ j ]; + + const info = getUniformSize( value ); + + infos.boundary += info.boundary; + infos.storage += info.storage; + + } + + // the following two properties will be used for partial buffer updates + + uniform.__data = new Float32Array( infos.storage / Float32Array.BYTES_PER_ELEMENT ); + uniform.__offset = offset; + + // + + if ( i > 0 ) { + + chunkOffset = offset % chunkSize; + + const remainingSizeInChunk = chunkSize - chunkOffset; + + // check for chunk overflow + + if ( chunkOffset !== 0 && ( remainingSizeInChunk - infos.boundary ) < 0 ) { + + // add padding and adjust offset + + offset += ( chunkSize - chunkOffset ); + uniform.__offset = offset; + + } + + } + + offset += infos.storage; + + } + + // ensure correct final padding + + chunkOffset = offset % chunkSize; + + if ( chunkOffset > 0 ) offset += ( chunkSize - chunkOffset ); + + // + + uniformsGroup.__size = offset; + uniformsGroup.__cache = {}; + + return this; + + } + + function getUniformSize( value ) { + + const info = { + boundary: 0, // bytes + storage: 0 // bytes + }; + + // 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 ) { + + console.warn( 'THREE.WebGLRenderer: Texture samplers can not be part of an uniforms group.' ); + + } else { + + console.warn( 'THREE.WebGLRenderer: Unsupported uniform value type.', value ); + + } + + return info; + + } + + function onUniformsGroupsDispose( event ) { + + const uniformsGroup = event.target; + + uniformsGroup.removeEventListener( 'dispose', onUniformsGroupsDispose ); + + const index = allocatedBindingPoints.indexOf( uniformsGroup.__bindingPointIndex ); + allocatedBindingPoints.splice( index, 1 ); + + gl.deleteBuffer( buffers[ uniformsGroup.id ] ); + + 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, + + dispose: dispose + + }; + +} + function createCanvasElement() { const canvas = createElementNS( 'canvas' ); @@ -26441,28 +27158,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; @@ -26615,7 +27310,7 @@ function WebGLRenderer( parameters = {} ) { let background, morphtargets, bufferRenderer, indexedBufferRenderer; - let utils, bindingStates; + let utils, bindingStates, uniformsGroups; function initGLContext() { @@ -26629,7 +27324,7 @@ function WebGLRenderer( parameters = {} ) { state = new WebGLState( _gl, extensions, capabilities ); - info = new WebGLInfo( _gl ); + info = new WebGLInfo(); properties = new WebGLProperties(); textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ); cubemaps = new WebGLCubeMaps( _this ); @@ -26644,8 +27339,9 @@ 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 ); indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities ); @@ -26911,6 +27607,7 @@ function WebGLRenderer( parameters = {} ) { cubeuvmaps.dispose(); objects.dispose(); bindingStates.dispose(); + uniformsGroups.dispose(); programCache.dispose(); xr.dispose(); @@ -27027,31 +27724,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; @@ -27068,23 +27782,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 ) { @@ -27136,7 +27833,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 ); @@ -27152,6 +27850,28 @@ function WebGLRenderer( parameters = {} ) { this.compile = function ( scene, camera ) { + function prepare( material, scene, object ) { + + if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) { + + 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(); @@ -27187,13 +27907,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 ); } @@ -27260,11 +27980,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 ) { @@ -27286,7 +28006,7 @@ function WebGLRenderer( parameters = {} ) { _frustum.setFromProjectionMatrix( _projScreenMatrix ); _localClippingEnabled = this.localClippingEnabled; - _clippingEnabled = clipping.init( this.clippingPlanes, _localClippingEnabled, camera ); + _clippingEnabled = clipping.init( this.clippingPlanes, _localClippingEnabled ); currentRenderList = renderLists.get( scene, renderListStack.length ); currentRenderList.init(); @@ -27515,6 +28235,8 @@ function WebGLRenderer( parameters = {} ) { currentRenderState.setupLightsView( camera ); + if ( _clippingEnabled === true ) clipping.setGlobalState( _this.clippingPlanes, camera ); + if ( transmissiveObjects.length > 0 ) renderTransmissionPass( opaqueObjects, scene, camera ); if ( viewport ) state.viewport( _currentViewport.copy( viewport ) ); @@ -27614,7 +28336,7 @@ function WebGLRenderer( parameters = {} ) { material.onBeforeRender( _this, scene, camera, geometry, object, group ); - if ( material.transparent === true && material.side === DoubleSide ) { + if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) { material.side = BackSide; material.needsUpdate = true; @@ -27733,7 +28455,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 @@ -28038,7 +28761,6 @@ function WebGLRenderer( parameters = {} ) { } - if ( refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow ) { materialProperties.receiveShadow = object.receiveShadow; @@ -28046,6 +28768,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 ); @@ -28098,6 +28830,31 @@ function WebGLRenderer( parameters = {} ) { p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix ); 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 ]; + + uniformsGroups.update( group, program ); + uniformsGroups.bind( group, program ); + + } else { + + console.warn( 'THREE.WebGLRenderer: Uniform Buffer Objects can only be used with WebGL 2.' ); + + } + + } + + } + return program; } @@ -28190,6 +28947,9 @@ function WebGLRenderer( parameters = {} ) { _currentActiveMipmapLevel = activeMipmapLevel; let useDefaultFramebuffer = true; + let framebuffer = null; + let isCube = false; + let isRenderTarget3D = false; if ( renderTarget ) { @@ -28212,17 +28972,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; @@ -28463,7 +29215,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 ); @@ -28491,7 +29243,23 @@ function WebGLRenderer( parameters = {} ) { this.initTexture = function ( texture ) { - textures.setTexture2D( texture, 0 ); + if ( texture.isCubeTexture ) { + + textures.setTextureCube( texture, 0 ); + + } else if ( texture.isData3DTexture ) { + + textures.setTexture3D( texture, 0 ); + + } else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) { + + textures.setTexture2DArray( texture, 0 ); + + } else { + + textures.setTexture2D( texture, 0 ); + + } state.unbindTexture(); @@ -28599,9 +29367,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' ) { @@ -28619,9 +29388,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; @@ -28633,11 +29404,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.object.backgroundBlurriness = this.backgroundBlurriness; + if ( this.backgroundIntensity !== 1 ) data.object.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 { @@ -28764,7 +29553,7 @@ class InterleavedBuffer { if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) { - data.arrayBuffers[ this.array.buffer._uuid ] = Array.prototype.slice.call( new Uint32Array( this.array.buffer ) ); + data.arrayBuffers[ this.array.buffer._uuid ] = Array.from( new Uint32Array( this.array.buffer ) ); } @@ -28795,7 +29584,7 @@ class InterleavedBufferAttribute { this.itemSize = itemSize; this.offset = offset; - this.normalized = normalized === true; + this.normalized = normalized; } @@ -28867,6 +29656,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; @@ -28875,6 +29666,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; @@ -28883,6 +29676,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; @@ -28891,6 +29686,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; @@ -28899,25 +29696,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; } @@ -28925,6 +29738,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; @@ -28936,6 +29756,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; @@ -28948,6 +29776,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; @@ -28961,7 +29798,7 @@ class InterleavedBufferAttribute { if ( data === undefined ) { - console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave buffer data.' ); + console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.' ); const array = []; @@ -29003,7 +29840,7 @@ class InterleavedBufferAttribute { if ( data === undefined ) { - console.log( 'THREE.InterleavedBufferAttribute.toJSON(): Serializing an interlaved buffer attribute will deinterleave buffer data.' ); + console.log( 'THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.' ); const array = []; @@ -29019,7 +29856,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, @@ -29030,7 +29867,7 @@ class InterleavedBufferAttribute { } else { - // save as true interlaved attribtue + // save as true interleaved attribute if ( data.interleavedBuffers === undefined ) { @@ -29315,7 +30152,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 ); } @@ -29325,7 +30162,7 @@ class LOD extends Object3D { } - addLevel( object, distance = 0 ) { + addLevel( object, distance = 0, hysteresis = 0 ) { distance = Math.abs( distance ); @@ -29343,7 +30180,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 ); @@ -29357,6 +30194,8 @@ class LOD extends Object3D { } + + getObjectForDistance( distance ) { const levels = this.levels; @@ -29367,7 +30206,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; @@ -29416,7 +30263,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; @@ -29457,7 +30312,8 @@ class LOD extends Object3D { data.object.levels.push( { object: level.object.uuid, - distance: level.distance + distance: level.distance, + hysteresis: level.hysteresis } ); } @@ -29920,16 +30776,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; @@ -29967,6 +30813,7 @@ const _instanceWorldMatrix = /*@__PURE__*/ new Matrix4(); const _instanceIntersects = []; +const _identity = /*@__PURE__*/ new Matrix4(); const _mesh = /*@__PURE__*/ new Mesh(); class InstancedMesh extends Mesh { @@ -29984,6 +30831,12 @@ class InstancedMesh extends Mesh { this.frustumCulled = false; + for ( let i = 0; i < count; i ++ ) { + + this.setMatrixAt( i, _identity ); + + } + } copy( source, recursive ) { @@ -30700,6 +31553,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 ) { @@ -31366,8 +32233,10 @@ function CubicPoly() { // -const tmp = new Vector3(); -const px = new CubicPoly(), py = new CubicPoly(), pz = new CubicPoly(); +const tmp = /*@__PURE__*/ new Vector3(); +const px = /*@__PURE__*/ new CubicPoly(); +const py = /*@__PURE__*/ new CubicPoly(); +const pz = /*@__PURE__*/ new CubicPoly(); class CatmullRomCurve3 extends Curve { @@ -32417,6 +33286,7 @@ class Path extends CurvePath { constructor( points ) { super(); + this.type = 'Path'; this.currentPoint = new Vector2(); @@ -32599,7 +33469,7 @@ class Path extends CurvePath { class LatheGeometry extends BufferGeometry { - constructor( points = [ new Vector2( 0, 0.5 ), new Vector2( 0.5, 0 ), new Vector2( 0, - 0.5 ) ], segments = 12, phiStart = 0, phiLength = Math.PI * 2 ) { + constructor( points = [ new Vector2( 0, - 0.5 ), new Vector2( 0.5, 0 ), new Vector2( 0, 0.5 ) ], segments = 12, phiStart = 0, phiLength = Math.PI * 2 ) { super(); @@ -32799,7 +33669,7 @@ class CapsuleGeometry extends LatheGeometry { class CircleGeometry extends BufferGeometry { - constructor( radius = 1, segments = 8, thetaStart = 0, thetaLength = Math.PI * 2 ) { + constructor( radius = 1, segments = 32, thetaStart = 0, thetaLength = Math.PI * 2 ) { super(); @@ -32883,9 +33753,10 @@ class CircleGeometry extends BufferGeometry { class CylinderGeometry extends BufferGeometry { - constructor( radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) { + constructor( radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) { super(); + this.type = 'CylinderGeometry'; this.parameters = { @@ -33151,7 +34022,7 @@ class CylinderGeometry extends BufferGeometry { class ConeGeometry extends CylinderGeometry { - constructor( radius = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) { + constructor( radius = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) { super( 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); @@ -33233,7 +34104,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 ) { @@ -33542,16 +34413,17 @@ class DodecahedronGeometry extends PolyhedronGeometry { } -const _v0 = new Vector3(); -const _v1$1 = new Vector3(); -const _normal = new Vector3(); -const _triangle = new Triangle(); +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(); + this.type = 'EdgesGeometry'; this.parameters = { @@ -33774,7 +34646,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 = { @@ -33811,11 +34683,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; @@ -33900,9 +34772,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 ); @@ -33957,11 +34829,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 ); - if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && + 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; @@ -33979,15 +34859,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; @@ -33995,14 +34877,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; } @@ -34010,9 +34890,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; } @@ -34020,9 +34899,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; } @@ -34042,9 +34920,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 ); @@ -34082,8 +34960,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; } @@ -34119,8 +34997,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 ); } @@ -34137,26 +35014,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 @@ -34168,14 +35048,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 } @@ -34187,8 +35061,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 @@ -34237,7 +35109,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; @@ -34321,8 +35193,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; @@ -34357,19 +35229,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 } @@ -34426,7 +35298,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 ); @@ -34454,7 +35326,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; @@ -34536,7 +35408,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; @@ -34716,7 +35588,7 @@ class ExtrudeGeometry extends BufferGeometry { const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; const steps = options.steps !== undefined ? options.steps : 1; - let depth = options.depth !== undefined ? options.depth : 1; + const depth = options.depth !== undefined ? options.depth : 1; let bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; let bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 0.2; @@ -34728,15 +35600,6 @@ class ExtrudeGeometry extends BufferGeometry { const uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; - // deprecated options - - if ( options.amount !== undefined ) { - - console.warn( 'THREE.ExtrudeBufferGeometry: amount has been renamed to depth.' ); - depth = options.amount; - - } - // let extrudePts, extrudeByPath = false; @@ -35527,7 +36390,7 @@ class OctahedronGeometry extends PolyhedronGeometry { class RingGeometry extends BufferGeometry { - constructor( innerRadius = 0.5, outerRadius = 1, thetaSegments = 8, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2 ) { + constructor( innerRadius = 0.5, outerRadius = 1, thetaSegments = 32, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2 ) { super(); @@ -35641,6 +36504,7 @@ class ShapeGeometry extends BufferGeometry { constructor( shapes = new Shape( [ new Vector2( 0, 0.5 ), new Vector2( - 0.5, - 0.5 ), new Vector2( 0.5, - 0.5 ) ] ), curveSegments = 12 ) { super(); + this.type = 'ShapeGeometry'; this.parameters = { @@ -35742,7 +36606,7 @@ class ShapeGeometry extends BufferGeometry { } - // incides + // indices for ( let i = 0, l = faces.length; i < l; i ++ ) { @@ -35818,6 +36682,7 @@ class SphereGeometry extends BufferGeometry { constructor( radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI ) { super(); + this.type = 'SphereGeometry'; this.parameters = { @@ -35967,9 +36832,10 @@ class TetrahedronGeometry extends PolyhedronGeometry { class TorusGeometry extends BufferGeometry { - constructor( radius = 1, tube = 0.4, radialSegments = 8, tubularSegments = 6, arc = Math.PI * 2 ) { + constructor( radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48, arc = Math.PI * 2 ) { super(); + this.type = 'TorusGeometry'; this.parameters = { @@ -36074,6 +36940,7 @@ class TorusKnotGeometry extends BufferGeometry { constructor( radius = 1, tube = 0.4, tubularSegments = 64, radialSegments = 8, p = 2, q = 3 ) { super(); + this.type = 'TorusKnotGeometry'; this.parameters = { @@ -36225,6 +37092,7 @@ class TubeGeometry extends BufferGeometry { constructor( path = new QuadraticBezierCurve3( new Vector3( - 1, - 1, 0 ), new Vector3( - 1, 1, 0 ), new Vector3( 1, 1, 0 ) ), tubularSegments = 64, radius = 1, radialSegments = 8, closed = false ) { super(); + this.type = 'TubeGeometry'; this.parameters = { @@ -36409,6 +37277,7 @@ class WireframeGeometry extends BufferGeometry { constructor( geometry = null ) { super(); + this.type = 'WireframeGeometry'; this.parameters = { @@ -36537,44 +37406,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 }); @@ -36795,7 +37645,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; @@ -37225,6 +38075,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; @@ -37239,6 +38100,8 @@ class MeshLambertMaterial extends Material { this.wireframeLinecap = 'round'; this.wireframeLinejoin = 'round'; + this.flatShading = false; + this.fog = true; this.setValues( parameters ); @@ -37263,6 +38126,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; @@ -37277,6 +38151,8 @@ class MeshLambertMaterial extends Material { this.wireframeLinecap = source.wireframeLinecap; this.wireframeLinejoin = source.wireframeLinejoin; + this.flatShading = source.flatShading; + this.fog = source.fog; return this; @@ -37392,370 +38268,339 @@ class LineDashedMaterial extends LineBasicMaterial { } -const materialLib = { - ShadowMaterial, - SpriteMaterial, - RawShaderMaterial, - ShaderMaterial, - PointsMaterial, - MeshPhysicalMaterial, - MeshStandardMaterial, - MeshPhongMaterial, - MeshToonMaterial, - MeshNormalMaterial, - MeshLambertMaterial, - MeshDepthMaterial, - MeshDistanceMaterial, - MeshBasicMaterial, - MeshMatcapMaterial, - LineDashedMaterial, - LineBasicMaterial, - Material -}; - -Material.fromType = function ( type ) { - - return new materialLib[ type ](); - -}; - -const AnimationUtils = { +// same as Array.prototype.slice, but also works on typed arrays +function arraySlice( array, from, to ) { - // same as Array.prototype.slice, but also works on typed arrays - arraySlice: function ( array, from, to ) { + if ( isTypedArray( array ) ) { - if ( AnimationUtils.isTypedArray( array ) ) { + // in ios9 array.subarray(from, undefined) will return empty array + // but array.subarray(from) or array.subarray(from, len) is correct + return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) ); - // 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 ); + return array.slice( from, to ); - }, +} - // converts an array to a specific type - convertArray: function ( array, type, forceClone ) { +// converts an array to a specific type +function convertArray( array, type, forceClone ) { - if ( ! array || // let 'undefined' and 'null' pass - ! forceClone && array.constructor === type ) return array; + if ( ! array || // let 'undefined' and 'null' pass + ! forceClone && array.constructor === type ) return array; - if ( typeof type.BYTES_PER_ELEMENT === 'number' ) { + if ( typeof type.BYTES_PER_ELEMENT === 'number' ) { - return new type( array ); // create typed array + return new type( array ); // create typed array - } - - return Array.prototype.slice.call( array ); // create Array + } - }, + return Array.prototype.slice.call( array ); // create Array - isTypedArray: function ( object ) { +} - return ArrayBuffer.isView( object ) && - ! ( object instanceof DataView ); +function isTypedArray( object ) { - }, + return ArrayBuffer.isView( object ) && + ! ( object instanceof DataView ); - // returns an array by which times and values can be sorted - getKeyframeOrder: function ( times ) { +} - function compareTime( i, j ) { +// returns an array by which times and values can be sorted +function getKeyframeOrder( times ) { - return times[ i ] - times[ j ]; + 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 ); + const n = times.length; + const result = new Array( n ); + for ( let i = 0; i !== n; ++ i ) result[ i ] = i; - return result; + result.sort( compareTime ); - }, + return result; - // uses the array previously returned by 'getKeyframeOrder' to sort data - sortedArray: function ( values, stride, order ) { +} - const nValues = values.length; - const result = new values.constructor( nValues ); +// uses the array previously returned by 'getKeyframeOrder' to sort data +function sortedArray( values, stride, order ) { - for ( let i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) { + const nValues = values.length; + const result = new values.constructor( nValues ); - const srcOffset = order[ i ] * stride; + for ( let i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) { - for ( let j = 0; j !== stride; ++ j ) { + const srcOffset = order[ i ] * stride; - result[ dstOffset ++ ] = values[ srcOffset + j ]; + for ( let j = 0; j !== stride; ++ j ) { - } + result[ dstOffset ++ ] = values[ srcOffset + j ]; } - return result; + } - }, + return result; - // function for parsing AOS keyframe formats - flattenJSON: function ( jsonKeys, times, values, valuePropertyName ) { +} - let i = 1, key = jsonKeys[ 0 ]; +// function for parsing AOS keyframe formats +function flattenJSON( jsonKeys, times, values, valuePropertyName ) { - while ( key !== undefined && key[ valuePropertyName ] === undefined ) { + let i = 1, key = jsonKeys[ 0 ]; - key = jsonKeys[ i ++ ]; + while ( key !== undefined && key[ valuePropertyName ] === undefined ) { - } + key = jsonKeys[ i ++ ]; - if ( key === undefined ) return; // no data + } - let value = key[ valuePropertyName ]; - if ( value === undefined ) return; // no data + if ( key === undefined ) return; // no data - if ( Array.isArray( value ) ) { + let value = key[ valuePropertyName ]; + if ( value === undefined ) return; // no data - do { + if ( Array.isArray( value ) ) { - value = key[ valuePropertyName ]; + do { - if ( value !== undefined ) { + value = key[ valuePropertyName ]; - times.push( key.time ); - values.push.apply( values, value ); // push all elements + if ( value !== undefined ) { - } + times.push( key.time ); + values.push.apply( values, value ); // push all elements - key = jsonKeys[ i ++ ]; + } - } while ( key !== undefined ); + key = jsonKeys[ i ++ ]; - } else if ( value.toArray !== undefined ) { + } while ( key !== undefined ); - // ...assume THREE.Math-ish + } else if ( value.toArray !== undefined ) { - do { + // ...assume THREE.Math-ish - value = key[ valuePropertyName ]; + do { - if ( value !== undefined ) { + value = key[ valuePropertyName ]; - times.push( key.time ); - value.toArray( values, values.length ); + if ( value !== undefined ) { - } + times.push( key.time ); + value.toArray( values, values.length ); - key = jsonKeys[ i ++ ]; + } - } while ( key !== undefined ); + key = jsonKeys[ i ++ ]; - } else { + } while ( key !== undefined ); - // otherwise push as-is + } else { - do { + // otherwise push as-is - value = key[ valuePropertyName ]; + do { - if ( value !== undefined ) { + value = key[ valuePropertyName ]; - times.push( key.time ); - values.push( value ); + if ( value !== undefined ) { - } + times.push( key.time ); + values.push( value ); - key = jsonKeys[ i ++ ]; + } - } while ( key !== undefined ); + key = jsonKeys[ i ++ ]; - } + } while ( key !== undefined ); - }, + } - subclip: function ( sourceClip, name, startFrame, endFrame, fps = 30 ) { +} - const clip = sourceClip.clone(); +function subclip( sourceClip, name, startFrame, endFrame, fps = 30 ) { - clip.name = name; + const clip = sourceClip.clone(); - const tracks = []; + clip.name = name; - for ( let i = 0; i < clip.tracks.length; ++ i ) { + const tracks = []; - const track = clip.tracks[ i ]; - const valueSize = track.getValueSize(); + for ( let i = 0; i < clip.tracks.length; ++ i ) { - const times = []; - const values = []; + const track = clip.tracks[ i ]; + const valueSize = track.getValueSize(); - for ( let j = 0; j < track.times.length; ++ j ) { + const times = []; + const values = []; - const frame = track.times[ j ] * fps; + for ( let j = 0; j < track.times.length; ++ j ) { - if ( frame < startFrame || frame >= endFrame ) continue; + const frame = track.times[ j ] * fps; - times.push( track.times[ j ] ); + if ( frame < startFrame || frame >= endFrame ) continue; - for ( let k = 0; k < valueSize; ++ k ) { + times.push( track.times[ j ] ); - values.push( track.values[ j * valueSize + k ] ); + for ( let k = 0; k < valueSize; ++ k ) { - } + values.push( track.values[ j * valueSize + k ] ); } - if ( times.length === 0 ) continue; + } - track.times = AnimationUtils.convertArray( times, track.times.constructor ); - track.values = AnimationUtils.convertArray( values, track.values.constructor ); + if ( times.length === 0 ) continue; - tracks.push( track ); + track.times = convertArray( times, track.times.constructor ); + track.values = convertArray( values, track.values.constructor ); - } + tracks.push( track ); - clip.tracks = tracks; + } - // find minimum .times value across all tracks in the trimmed clip + clip.tracks = tracks; - let minStartTime = Infinity; + // find minimum .times value across all tracks in the trimmed clip - for ( let i = 0; i < clip.tracks.length; ++ i ) { + let minStartTime = Infinity; - if ( minStartTime > clip.tracks[ i ].times[ 0 ] ) { + for ( let i = 0; i < clip.tracks.length; ++ i ) { - minStartTime = clip.tracks[ i ].times[ 0 ]; + if ( minStartTime > clip.tracks[ i ].times[ 0 ] ) { - } + minStartTime = clip.tracks[ i ].times[ 0 ]; } - // shift all tracks such that clip begins at t=0 + } - for ( let i = 0; i < clip.tracks.length; ++ i ) { + // shift all tracks such that clip begins at t=0 - clip.tracks[ i ].shift( - 1 * minStartTime ); + for ( let i = 0; i < clip.tracks.length; ++ i ) { - } + clip.tracks[ i ].shift( - 1 * minStartTime ); - clip.resetDuration(); + } - return clip; + clip.resetDuration(); - }, + return clip; - makeClipAdditive: function ( targetClip, referenceFrame = 0, referenceClip = targetClip, fps = 30 ) { +} - if ( fps <= 0 ) fps = 30; +function makeClipAdditive( targetClip, referenceFrame = 0, referenceClip = targetClip, fps = 30 ) { - const numTracks = referenceClip.tracks.length; - const referenceTime = referenceFrame / fps; + if ( fps <= 0 ) fps = 30; - // Make each track's values relative to the values at the reference frame - for ( let i = 0; i < numTracks; ++ i ) { + const numTracks = referenceClip.tracks.length; + const referenceTime = referenceFrame / fps; - const referenceTrack = referenceClip.tracks[ i ]; - const referenceTrackType = referenceTrack.ValueTypeName; + // Make each track's values relative to the values at the reference frame + for ( let i = 0; i < numTracks; ++ i ) { - // Skip this track if it's non-numeric - if ( referenceTrackType === 'bool' || referenceTrackType === 'string' ) continue; + const referenceTrack = referenceClip.tracks[ i ]; + const referenceTrackType = referenceTrack.ValueTypeName; - // Find the track in the target clip whose name and type matches the reference track - const targetTrack = targetClip.tracks.find( function ( track ) { + // Skip this track if it's non-numeric + if ( referenceTrackType === 'bool' || referenceTrackType === 'string' ) continue; - return track.name === referenceTrack.name - && track.ValueTypeName === referenceTrackType; + // 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 ( targetTrack === undefined ) continue; - if ( referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) { + let referenceOffset = 0; + const referenceValueSize = referenceTrack.getValueSize(); - referenceOffset = referenceValueSize / 3; + if ( referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) { - } + referenceOffset = referenceValueSize / 3; - let targetOffset = 0; - const targetValueSize = targetTrack.getValueSize(); + } - if ( targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) { + let targetOffset = 0; + const targetValueSize = targetTrack.getValueSize(); - targetOffset = targetValueSize / 3; + if ( targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) { - } + targetOffset = targetValueSize / 3; - const lastIndex = referenceTrack.times.length - 1; - let referenceValue; + } - // Find the value to subtract out of the track - if ( referenceTime <= referenceTrack.times[ 0 ] ) { + const lastIndex = referenceTrack.times.length - 1; + let referenceValue; - // Reference frame is earlier than the first keyframe, so just use the first keyframe - const startIndex = referenceOffset; - const endIndex = referenceValueSize - referenceOffset; - referenceValue = AnimationUtils.arraySlice( referenceTrack.values, startIndex, endIndex ); + // Find the value to subtract out of the track + if ( referenceTime <= referenceTrack.times[ 0 ] ) { - } else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) { + // Reference frame is earlier than the first keyframe, so just use the first keyframe + const startIndex = referenceOffset; + const endIndex = referenceValueSize - referenceOffset; + referenceValue = arraySlice( referenceTrack.values, startIndex, endIndex ); - // Reference frame is after the last keyframe, so just use the last keyframe - const startIndex = lastIndex * referenceValueSize + referenceOffset; - const endIndex = startIndex + referenceValueSize - referenceOffset; - referenceValue = AnimationUtils.arraySlice( referenceTrack.values, startIndex, endIndex ); + } else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) { - } else { + // Reference frame is after the last keyframe, so just use the last keyframe + const startIndex = lastIndex * referenceValueSize + referenceOffset; + const endIndex = startIndex + referenceValueSize - referenceOffset; + referenceValue = arraySlice( referenceTrack.values, startIndex, endIndex ); - // Interpolate to the reference value - const interpolant = referenceTrack.createInterpolant(); - const startIndex = referenceOffset; - const endIndex = referenceValueSize - referenceOffset; - interpolant.evaluate( referenceTime ); - referenceValue = AnimationUtils.arraySlice( interpolant.resultBuffer, startIndex, endIndex ); + } else { - } + // Interpolate to the reference value + const interpolant = referenceTrack.createInterpolant(); + const startIndex = referenceOffset; + const endIndex = referenceValueSize - referenceOffset; + interpolant.evaluate( referenceTime ); + referenceValue = arraySlice( interpolant.resultBuffer, startIndex, endIndex ); - // Conjugate the quaternion - if ( referenceTrackType === 'quaternion' ) { + } - const referenceQuat = new Quaternion().fromArray( referenceValue ).normalize().conjugate(); - referenceQuat.toArray( referenceValue ); + // 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 + } - const numTimes = targetTrack.times.length; - for ( let j = 0; j < numTimes; ++ j ) { + // Subtract the reference value from all of the track values - const valueStart = j * targetValueSize + targetOffset; + const numTimes = targetTrack.times.length; + for ( let j = 0; j < numTimes; ++ j ) { - if ( referenceTrackType === 'quaternion' ) { + const valueStart = j * targetValueSize + targetOffset; - // Multiply the conjugate for quaternion track types - Quaternion.multiplyQuaternionsFlat( - targetTrack.values, - valueStart, - referenceValue, - 0, - targetTrack.values, - valueStart - ); + if ( referenceTrackType === 'quaternion' ) { - } else { + // Multiply the conjugate for quaternion track types + Quaternion.multiplyQuaternionsFlat( + targetTrack.values, + valueStart, + referenceValue, + 0, + targetTrack.values, + valueStart + ); - const valueEnd = targetValueSize - targetOffset * 2; + } else { - // Subtract each value for all other numeric track types - for ( let k = 0; k < valueEnd; ++ k ) { + const valueEnd = targetValueSize - targetOffset * 2; - targetTrack.values[ valueStart + k ] -= referenceValue[ k ]; + // Subtract each value for all other numeric track types + for ( let k = 0; k < valueEnd; ++ k ) { - } + targetTrack.values[ valueStart + k ] -= referenceValue[ k ]; } @@ -37763,13 +38608,25 @@ const AnimationUtils = { } - targetClip.blendMode = AdditiveAnimationBlendMode; + } - return targetClip; + targetClip.blendMode = AdditiveAnimationBlendMode; - } + return targetClip; -}; +} + +var AnimationUtils = /*#__PURE__*/Object.freeze({ + __proto__: null, + arraySlice: arraySlice, + convertArray: convertArray, + flattenJSON: flattenJSON, + getKeyframeOrder: getKeyframeOrder, + isTypedArray: isTypedArray, + makeClipAdditive: makeClipAdditive, + sortedArray: sortedArray, + subclip: subclip +}); /** * Abstract base class of interpolants over parametric samples. @@ -38222,8 +39079,8 @@ class KeyframeTrack { this.name = name; - this.times = AnimationUtils.convertArray( times, this.TimeBufferType ); - this.values = AnimationUtils.convertArray( values, this.ValueBufferType ); + this.times = convertArray( times, this.TimeBufferType ); + this.values = convertArray( values, this.ValueBufferType ); this.setInterpolation( interpolation || this.DefaultInterpolation ); @@ -38249,8 +39106,8 @@ class KeyframeTrack { json = { 'name': track.name, - 'times': AnimationUtils.convertArray( track.times, Array ), - 'values': AnimationUtils.convertArray( track.values, Array ) + 'times': convertArray( track.times, Array ), + 'values': convertArray( track.values, Array ) }; @@ -38444,8 +39301,8 @@ class KeyframeTrack { } const stride = this.getValueSize(); - this.times = AnimationUtils.arraySlice( times, from, to ); - this.values = AnimationUtils.arraySlice( this.values, from * stride, to * stride ); + this.times = arraySlice( times, from, to ); + this.values = arraySlice( this.values, from * stride, to * stride ); } @@ -38506,7 +39363,7 @@ class KeyframeTrack { if ( values !== undefined ) { - if ( AnimationUtils.isTypedArray( values ) ) { + if ( isTypedArray( values ) ) { for ( let i = 0, n = values.length; i !== n; ++ i ) { @@ -38535,8 +39392,8 @@ class KeyframeTrack { optimize() { // times or values may be shared with other tracks, so overwriting is unsafe - const times = AnimationUtils.arraySlice( this.times ), - values = AnimationUtils.arraySlice( this.values ), + const times = arraySlice( this.times ), + values = arraySlice( this.values ), stride = this.getValueSize(), smoothInterpolation = this.getInterpolation() === InterpolateSmooth, @@ -38629,8 +39486,8 @@ class KeyframeTrack { if ( writeIndex !== times.length ) { - this.times = AnimationUtils.arraySlice( times, 0, writeIndex ); - this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride ); + this.times = arraySlice( times, 0, writeIndex ); + this.values = arraySlice( values, 0, writeIndex * stride ); } else { @@ -38645,8 +39502,8 @@ class KeyframeTrack { clone() { - const times = AnimationUtils.arraySlice( this.times, 0 ); - const values = AnimationUtils.arraySlice( this.values, 0 ); + const times = arraySlice( this.times, 0 ); + const values = arraySlice( this.values, 0 ); const TypedKeyframeTrack = this.constructor; const track = new TypedKeyframeTrack( this.name, times, values ); @@ -38841,9 +39698,9 @@ class AnimationClip { values.push( 0, 1, 0 ); - const order = AnimationUtils.getKeyframeOrder( times ); - times = AnimationUtils.sortedArray( times, 1, order ); - values = AnimationUtils.sortedArray( values, 1, order ); + 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. @@ -38954,7 +39811,7 @@ class AnimationClip { const times = []; const values = []; - AnimationUtils.flattenJSON( animationKeys, times, values, propertyName ); + flattenJSON( animationKeys, times, values, propertyName ); // empty keys are filtered out, so check again if ( times.length !== 0 ) { @@ -39199,7 +40056,7 @@ function parseKeyframeTrack( json ) { const times = [], values = []; - AnimationUtils.flattenJSON( json.keys, times, values, 'value' ); + flattenJSON( json.keys, times, values, 'value' ); json.times = times; json.values = values; @@ -39399,7 +40256,7 @@ class LoadingManager { } -const DefaultLoadingManager = new LoadingManager(); +const DefaultLoadingManager = /*@__PURE__*/ new LoadingManager(); class Loader { @@ -39470,6 +40327,17 @@ class Loader { const loading = {}; +class HttpError extends Error { + + constructor( message, response ) { + + super( message ); + this.response = response; + + } + +} + class FileLoader extends Loader { constructor( manager ) { @@ -39565,7 +40433,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; @@ -39613,7 +40484,7 @@ class FileLoader extends Loader { } else { - throw Error( `fetch for "${response.url}" responded with ${response.status}: ${response.statusText}` ); + throw new HttpError( `fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`, response ); } @@ -40261,7 +41132,7 @@ class HemisphereLight extends Light { this.type = 'HemisphereLight'; - this.position.copy( Object3D.DefaultUp ); + this.position.copy( Object3D.DEFAULT_UP ); this.updateMatrix(); this.groundColor = new Color( groundColor ); @@ -40351,8 +41222,7 @@ class LightShadow { 0.0, 0.0, 0.0, 1.0 ); - shadowMatrix.multiply( shadowCamera.projectionMatrix ); - shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); + shadowMatrix.multiply( _projScreenMatrix$1 ); } @@ -40468,7 +41338,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 ); @@ -40476,7 +41346,7 @@ class SpotLight extends Light { this.type = 'SpotLight'; - this.position.copy( Object3D.DefaultUp ); + this.position.copy( Object3D.DEFAULT_UP ); this.updateMatrix(); this.target = new Object3D(); @@ -40484,7 +41354,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(); @@ -40620,7 +41492,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 ); @@ -40629,7 +41501,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(); @@ -40693,7 +41565,7 @@ class DirectionalLight extends Light { this.type = 'DirectionalLight'; - this.position.copy( Object3D.DefaultUp ); + this.position.copy( Object3D.DEFAULT_UP ); this.updateMatrix(); this.target = new Object3D(); @@ -41130,7 +42002,7 @@ class MaterialLoader extends Loader { } - const material = Material.fromType( json.type ); + const material = MaterialLoader.createMaterialFromType( json.type ); if ( json.uuid !== undefined ) material.uuid = json.uuid; if ( json.name !== undefined ) material.name = json.name; @@ -41196,6 +42068,7 @@ class MaterialLoader extends Loader { if ( json.alphaToCoverage !== undefined ) material.alphaToCoverage = json.alphaToCoverage; if ( json.premultipliedAlpha !== undefined ) material.premultipliedAlpha = json.premultipliedAlpha; + if ( json.forceSinglePass !== undefined ) material.forceSinglePass = json.forceSinglePass; if ( json.visible !== undefined ) material.visible = json.visible; @@ -41269,6 +42142,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 ) { @@ -41280,10 +42154,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; @@ -41370,6 +42240,33 @@ class MaterialLoader extends Loader { } + static createMaterialFromType( type ) { + + const materialLib = { + ShadowMaterial, + SpriteMaterial, + RawShaderMaterial, + ShaderMaterial, + PointsMaterial, + MeshPhysicalMaterial, + MeshStandardMaterial, + MeshPhongMaterial, + MeshToonMaterial, + MeshNormalMaterial, + MeshLambertMaterial, + MeshDepthMaterial, + MeshDistanceMaterial, + MeshBasicMaterial, + MeshMatcapMaterial, + LineDashedMaterial, + LineBasicMaterial, + Material + }; + + return new materialLib[ type ](); + + } + } class LoaderUtils { @@ -41469,15 +42366,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; @@ -41741,6 +42632,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; @@ -41915,13 +42808,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: @@ -41967,40 +42853,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 ] ); - - } + if ( cache[ data.uuid ] === undefined ) { - 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 ]; + } } @@ -42332,6 +43192,7 @@ class ObjectLoader extends Loader { if ( data.flipY !== undefined ) texture.flipY = data.flipY; + if ( data.generateMipmaps !== undefined ) texture.generateMipmaps = data.generateMipmaps; if ( data.premultiplyAlpha !== undefined ) texture.premultiplyAlpha = data.premultiplyAlpha; if ( data.unpackAlignment !== undefined ) texture.unpackAlignment = data.unpackAlignment; @@ -42453,6 +43314,9 @@ class ObjectLoader extends Loader { } + if ( data.backgroundBlurriness !== undefined ) object.backgroundBlurriness = data.backgroundBlurriness; + if ( data.backgroundIntensity !== undefined ) object.backgroundIntensity = data.backgroundIntensity; + break; case 'PerspectiveCamera': @@ -42687,7 +43551,7 @@ class ObjectLoader extends Loader { if ( child !== undefined ) { - object.addLevel( child, level.distance ); + object.addLevel( child, level.distance, level.hysteresis ); } @@ -42725,15 +43589,6 @@ class ObjectLoader extends Loader { } - /* DEPRECATED */ - - setTexturePath( value ) { - - console.warn( 'THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().' ); - return this.setResourcePath( value ); - - } - } const TEXTURE_MAPPING = { @@ -42857,9 +43712,9 @@ class ImageBitmapLoader extends Loader { let _context; -const AudioContext = { +class AudioContext { - getContext: function () { + static getContext() { if ( _context === undefined ) { @@ -42869,15 +43724,15 @@ const AudioContext = { return _context; - }, + } - setContext: function ( value ) { + static setContext( value ) { _context = value; } -}; +} class AudioLoader extends Loader { @@ -43442,8 +44297,13 @@ class Audio extends Object3D { this._progress = 0; - this.source.stop(); - this.source.onended = null; + if ( this.source !== null ) { + + this.source.stop(); + this.source.onended = null; + + } + this.isPlaying = false; return this; @@ -44159,18 +45019,18 @@ const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace( '\\.', '' ) + ']'; // Parent directories, delimited by '/' or ':'. Currently unused, but must // be matched to parse the rest of the track name. -const _directoryRe = /((?:WC+[\/:])*)/.source.replace( 'WC', _wordChar ); +const _directoryRe = /*@__PURE__*/ /((?:WC+[\/:])*)/.source.replace( 'WC', _wordChar ); // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. -const _nodeRe = /(WCOD+)?/.source.replace( 'WCOD', _wordCharOrDot ); +const _nodeRe = /*@__PURE__*/ /(WCOD+)?/.source.replace( 'WCOD', _wordCharOrDot ); // Object on target node, and accessor. May not contain reserved // characters. Accessor may contain any character except closing bracket. -const _objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', _wordChar ); +const _objectRe = /*@__PURE__*/ /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', _wordChar ); // Property and accessor. May not contain reserved characters. Accessor may // contain any non-bracket characters. -const _propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', _wordChar ); +const _propertyRe = /*@__PURE__*/ /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', _wordChar ); const _trackRe = new RegExp( '' + '^' @@ -44181,7 +45041,7 @@ const _trackRe = new RegExp( '' + '$' ); -const _supportedObjectNames = [ 'material', 'materials', 'bones' ]; +const _supportedObjectNames = [ 'material', 'materials', 'bones', 'map' ]; class Composite { @@ -44256,7 +45116,7 @@ class PropertyBinding { this.path = path; this.parsedPath = parsedPath || PropertyBinding.parseTrackName( path ); - this.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName ) || rootNode; + this.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName ); this.rootNode = rootNode; @@ -44572,7 +45432,7 @@ class PropertyBinding { if ( ! targetObject ) { - targetObject = PropertyBinding.findNode( this.rootNode, parsedPath.nodeName ) || this.rootNode; + targetObject = PropertyBinding.findNode( this.rootNode, parsedPath.nodeName ); this.node = targetObject; @@ -44645,6 +45505,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 ) { @@ -45560,14 +46446,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; + + } } @@ -45915,7 +46802,7 @@ class AnimationAction { } -const _controlInterpolantsResultBuffer = /*@__PURE__*/ new Float32Array( 1 ); +const _controlInterpolantsResultBuffer = new Float32Array( 1 ); class AnimationMixer extends EventDispatcher { @@ -46679,20 +47566,101 @@ class Uniform { constructor( value ) { - if ( typeof value === 'string' ) { + 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(); + + this.isUniformsGroup = true; + + Object.defineProperty( this, 'id', { value: id ++ } ); + + this.name = ''; + + 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 ) { - console.warn( 'THREE.Uniform: Type parameter is no longer needed.' ); - value = arguments[ 1 ]; + 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() ); } - this.value = value; + return this; } clone() { - return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() ); + return new this.constructor().copy( this ); } @@ -46749,6 +47717,8 @@ class GLBufferAttribute { this.isGLBufferAttribute = true; + this.name = ''; + this.buffer = buffer; this.type = type; this.itemSize = itemSize; @@ -47367,14 +48337,16 @@ 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 = [ @@ -47417,7 +48389,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 ); @@ -47530,6 +48503,13 @@ class SkeletonHelper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } @@ -47563,7 +48543,6 @@ class PointLightHelper extends Mesh { super( geometry, material ); this.light = light; - this.light.updateMatrixWorld(); this.color = color; @@ -47609,6 +48588,8 @@ class PointLightHelper extends Mesh { update() { + this.light.updateWorldMatrix( true, false ); + if ( this.color !== undefined ) { this.material.color.set( this.color ); @@ -47647,14 +48628,16 @@ 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 ); @@ -47706,6 +48689,8 @@ class HemisphereLightHelper extends Object3D { } + this.light.updateWorldMatrix( true, false ); + mesh.lookAt( _vector$1.setFromMatrixPosition( this.light.matrixWorld ).negate() ); } @@ -47751,11 +48736,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 ); @@ -47763,32 +48755,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 ++ ) { @@ -47828,6 +48824,13 @@ class PolarGridHelper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } const _v1 = /*@__PURE__*/ new Vector3(); @@ -47839,14 +48842,16 @@ 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(); @@ -47884,6 +48889,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 ); @@ -47931,72 +48939,64 @@ class CameraHelper extends LineSegments { const pointMap = {}; - // colors - - const colorFrustum = new Color( 0xffaa00 ); - const colorCone = new Color( 0xff0000 ); - const colorUp = new Color( 0x00aaff ); - const colorTarget = new Color( 0xffffff ); - const colorCross = new Color( 0x333333 ); - // near - addLine( 'n1', 'n2', colorFrustum ); - addLine( 'n2', 'n4', colorFrustum ); - addLine( 'n4', 'n3', colorFrustum ); - addLine( 'n3', 'n1', colorFrustum ); + addLine( 'n1', 'n2' ); + addLine( 'n2', 'n4' ); + addLine( 'n4', 'n3' ); + addLine( 'n3', 'n1' ); // far - addLine( 'f1', 'f2', colorFrustum ); - addLine( 'f2', 'f4', colorFrustum ); - addLine( 'f4', 'f3', colorFrustum ); - addLine( 'f3', 'f1', colorFrustum ); + addLine( 'f1', 'f2' ); + addLine( 'f2', 'f4' ); + addLine( 'f4', 'f3' ); + addLine( 'f3', 'f1' ); // sides - addLine( 'n1', 'f1', colorFrustum ); - addLine( 'n2', 'f2', colorFrustum ); - addLine( 'n3', 'f3', colorFrustum ); - addLine( 'n4', 'f4', colorFrustum ); + addLine( 'n1', 'f1' ); + addLine( 'n2', 'f2' ); + addLine( 'n3', 'f3' ); + addLine( 'n4', 'f4' ); // cone - addLine( 'p', 'n1', colorCone ); - addLine( 'p', 'n2', colorCone ); - addLine( 'p', 'n3', colorCone ); - addLine( 'p', 'n4', colorCone ); + addLine( 'p', 'n1' ); + addLine( 'p', 'n2' ); + addLine( 'p', 'n3' ); + addLine( 'p', 'n4' ); // up - addLine( 'u1', 'u2', colorUp ); - addLine( 'u2', 'u3', colorUp ); - addLine( 'u3', 'u1', colorUp ); + addLine( 'u1', 'u2' ); + addLine( 'u2', 'u3' ); + addLine( 'u3', 'u1' ); // target - addLine( 'c', 't', colorTarget ); - addLine( 'p', 'c', colorCross ); + addLine( 'c', 't' ); + addLine( 'p', 'c' ); // cross - addLine( 'cn1', 'cn2', colorCross ); - addLine( 'cn3', 'cn4', colorCross ); + addLine( 'cn1', 'cn2' ); + addLine( 'cn3', 'cn4' ); - addLine( 'cf1', 'cf2', colorCross ); - addLine( 'cf3', 'cf4', colorCross ); + addLine( 'cf1', 'cf2' ); + addLine( 'cf3', 'cf4' ); - function addLine( a, b, color ) { + function addLine( a, b ) { - addPoint( a, color ); - addPoint( b, color ); + addPoint( a ); + addPoint( b ); } - function addPoint( id, color ) { + function addPoint( id ) { vertices.push( 0, 0, 0 ); - colors.push( color.r, color.g, color.b ); + colors.push( 0, 0, 0 ); if ( pointMap[ id ] === undefined ) { @@ -48025,6 +49025,73 @@ class CameraHelper extends LineSegments { this.update(); + // colors + + const colorFrustum = new Color( 0xffaa00 ); + const colorCone = new Color( 0xff0000 ); + const colorUp = new Color( 0x00aaff ); + const colorTarget = new Color( 0xffffff ); + 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 + + 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() { @@ -48185,7 +49252,6 @@ class BoxHelper extends LineSegments { this.geometry.computeBoundingSphere(); - } setFromObject( object ) { @@ -48207,6 +49273,13 @@ class BoxHelper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } class Box3Helper extends LineSegments { @@ -48249,6 +49322,13 @@ class Box3Helper extends LineSegments { } + dispose() { + + this.geometry.dispose(); + this.material.dispose(); + + } + } class PlaneHelper extends Line { @@ -48257,7 +49337,7 @@ class PlaneHelper extends Line { const color = hex; - const positions = [ 1, - 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 ]; + const positions = [ 1, - 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, - 1, 0, 1, 1, 0 ]; const geometry = new BufferGeometry(); geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); @@ -48271,7 +49351,7 @@ class PlaneHelper extends Line { this.size = size; - const positions2 = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, - 1, 1, 1, - 1, 1 ]; + const positions2 = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ]; const geometry2 = new BufferGeometry(); geometry2.setAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); @@ -48283,20 +49363,27 @@ class PlaneHelper extends Line { updateMatrixWorld( force ) { - let scale = - this.plane.constant; + this.position.set( 0, 0, 0 ); - if ( Math.abs( scale ) < 1e-8 ) scale = 1e-8; // sign does not matter - - this.scale.set( 0.5 * this.size, 0.5 * this.size, scale ); - - this.children[ 0 ].material.side = ( scale < 0 ) ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here + this.scale.set( 0.5 * this.size, 0.5 * this.size, 1 ); this.lookAt( this.plane.normal ); + 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(); @@ -48390,6 +49477,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 { @@ -48507,7 +49603,7 @@ class ShapePath { } - toShapes( isCCW, noHoles ) { + toShapes( isCCW ) { function toShapesNoHoles( inSubpaths ) { @@ -48593,9 +49689,6 @@ class ShapePath { const subPaths = this.subPaths; if ( subPaths.length === 0 ) return []; - if ( noHoles === true ) return toShapesNoHoles( subPaths ); - - let solid, tmpPath, tmpShape; const shapes = []; @@ -48741,240 +49834,417 @@ class ShapePath { // Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf -class DataUtils { +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) + + if ( e < - 27 ) { - // float32 to float16 + baseTable[ i ] = 0x0000; + baseTable[ i | 0x100 ] = 0x8000; + shiftTable[ i ] = 24; + shiftTable[ i | 0x100 ] = 24; - static toHalfFloat( val ) { + // small number (denorm) - if ( Math.abs( val ) > 65504 ) console.warn( 'THREE.DataUtils.toHalfFloat(): Value out of range.' ); + } else if ( e < - 14 ) { - val = clamp( val, - 65504, 65504 ); + baseTable[ i ] = 0x0400 >> ( - e - 14 ); + baseTable[ i | 0x100 ] = ( 0x0400 >> ( - e - 14 ) ) | 0x8000; + shiftTable[ i ] = - e - 1; + shiftTable[ i | 0x100 ] = - e - 1; - _floatView[ 0 ] = val; - const f = _uint32View[ 0 ]; - const e = ( f >> 23 ) & 0x1ff; - return _baseTable[ e ] + ( ( f & 0x007fffff ) >> _shiftTable[ e ] ); + // 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) + + } else if ( e < 128 ) { + + baseTable[ i ] = 0x7c00; + baseTable[ i | 0x100 ] = 0xfc00; + shiftTable[ i ] = 24; + 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 + // 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 + while ( ( m & 0x00800000 ) === 0 ) { - static fromHalfFloat( val ) { + m <<= 1; + e -= 0x00800000; // decrement exponent - const m = val >> 10; - _uint32View[ 0 ] = _mantissaTable[ _offsetTable[ m ] + ( val & 0x3ff ) ] + _exponentTable[ m ]; - return _floatView[ 0 ]; + } + + 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, + baseTable: baseTable, + shiftTable: shiftTable, + mantissaTable: mantissaTable, + exponentTable: exponentTable, + offsetTable: offsetTable + }; + } -// float32 to float16 helpers +// float32 to float16 -const _buffer = new ArrayBuffer( 4 ); -const _floatView = new Float32Array( _buffer ); -const _uint32View = new Uint32Array( _buffer ); +function toHalfFloat( val ) { -const _baseTable = new Uint32Array( 512 ); -const _shiftTable = new Uint32Array( 512 ); + if ( Math.abs( val ) > 65504 ) console.warn( 'THREE.DataUtils.toHalfFloat(): Value out of range.' ); -for ( let i = 0; i < 256; ++ i ) { + val = clamp( val, - 65504, 65504 ); - const e = i - 127; + _tables.floatView[ 0 ] = val; + const f = _tables.uint32View[ 0 ]; + const e = ( f >> 23 ) & 0x1ff; + return _tables.baseTable[ e ] + ( ( f & 0x007fffff ) >> _tables.shiftTable[ e ] ); - // very small number (0, -0) +} - if ( e < - 27 ) { +// float16 to float32 - _baseTable[ i ] = 0x0000; - _baseTable[ i | 0x100 ] = 0x8000; - _shiftTable[ i ] = 24; - _shiftTable[ i | 0x100 ] = 24; +function fromHalfFloat( val ) { - // small number (denorm) + const m = val >> 10; + _tables.uint32View[ 0 ] = _tables.mantissaTable[ _tables.offsetTable[ m ] + ( val & 0x3ff ) ] + _tables.exponentTable[ m ]; + return _tables.floatView[ 0 ]; - } 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; +var DataUtils = /*#__PURE__*/Object.freeze({ + __proto__: null, + fromHalfFloat: fromHalfFloat, + toHalfFloat: toHalfFloat +}); - // normal number +// r144 - } else if ( e <= 15 ) { +class BoxBufferGeometry extends BoxGeometry { - _baseTable[ i ] = ( e + 15 ) << 10; - _baseTable[ i | 0x100 ] = ( ( e + 15 ) << 10 ) | 0x8000; - _shiftTable[ i ] = 13; - _shiftTable[ i | 0x100 ] = 13; + constructor( width, height, depth, widthSegments, heightSegments, depthSegments ) { - // large number (Infinity, -Infinity) + console.warn( 'THREE.BoxBufferGeometry has been renamed to THREE.BoxGeometry.' ); + super( width, height, depth, widthSegments, heightSegments, depthSegments ); - } else if ( e < 128 ) { - _baseTable[ i ] = 0x7c00; - _baseTable[ i | 0x100 ] = 0xfc00; - _shiftTable[ i ] = 24; - _shiftTable[ i | 0x100 ] = 24; + } - // stay (NaN, Infinity, -Infinity) +} - } else { +// r144 - _baseTable[ i ] = 0x7c00; - _baseTable[ i | 0x100 ] = 0xfc00; - _shiftTable[ i ] = 13; - _shiftTable[ i | 0x100 ] = 13; +class CapsuleBufferGeometry extends CapsuleGeometry { + + constructor( radius, length, capSegments, radialSegments ) { + + console.warn( 'THREE.CapsuleBufferGeometry has been renamed to THREE.CapsuleGeometry.' ); + super( radius, length, capSegments, radialSegments ); } } -// float16 to float32 helpers +// 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 ); -const _mantissaTable = new Uint32Array( 2048 ); -const _exponentTable = new Uint32Array( 64 ); -const _offsetTable = new Uint32Array( 64 ); + } + +} -for ( let i = 1; i < 1024; ++ i ) { +// r144 - let m = i << 13; // zero pad mantissa bits - let e = 0; // zero exponent +class ConeBufferGeometry extends ConeGeometry { - // normalized - while ( ( m & 0x00800000 ) === 0 ) { + constructor( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { - m <<= 1; - e -= 0x00800000; // decrement exponent + console.warn( 'THREE.ConeBufferGeometry has been renamed to THREE.ConeGeometry.' ); + super( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); } - m &= ~ 0x00800000; // clear leading 1 bit - e += 0x38800000; // adjust bias +} + +// r144 - _mantissaTable[ i ] = m | e; +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 ); + + } } -for ( let i = 1024; i < 2048; ++ i ) { +// r144 + +class DodecahedronBufferGeometry extends DodecahedronGeometry { - _mantissaTable[ i ] = 0x38000000 + ( ( i - 1024 ) << 13 ); + constructor( radius, detail ) { + + console.warn( 'THREE.DodecahedronBufferGeometry has been renamed to THREE.DodecahedronGeometry.' ); + super( radius, detail ); + + } } -for ( let i = 1; i < 31; ++ i ) { +// r144 + +class ExtrudeBufferGeometry extends ExtrudeGeometry { - _exponentTable[ i ] = i << 23; + constructor( shapes, options ) { + + console.warn( 'THREE.ExtrudeBufferGeometry has been renamed to THREE.ExtrudeGeometry.' ); + super( shapes, options ); + + } } -_exponentTable[ 31 ] = 0x47800000; -_exponentTable[ 32 ] = 0x80000000; -for ( let i = 33; i < 63; ++ i ) { +// r144 + +class IcosahedronBufferGeometry extends IcosahedronGeometry { + + constructor( radius, detail ) { - _exponentTable[ i ] = 0x80000000 + ( ( i - 32 ) << 23 ); + console.warn( 'THREE.IcosahedronBufferGeometry has been renamed to THREE.IcosahedronGeometry.' ); + super( radius, detail ); + + } } -_exponentTable[ 63 ] = 0xc7800000; +// r144 -for ( let i = 1; i < 64; ++ i ) { +class LatheBufferGeometry extends LatheGeometry { - if ( i !== 32 ) { + constructor( points, segments, phiStart, phiLength ) { - _offsetTable[ i ] = 1024; + console.warn( 'THREE.LatheBufferGeometry has been renamed to THREE.LatheGeometry.' ); + super( points, segments, phiStart, phiLength ); } } -// r133, c5bb5434555a3c3ddd784944a0a124f996fc721b +// r144 -class ParametricGeometry extends BufferGeometry { +class OctahedronBufferGeometry extends OctahedronGeometry { - constructor() { + constructor( radius, detail ) { - console.error( 'THREE.ParametricGeometry has been moved to /examples/jsm/geometries/ParametricGeometry.js' ); - super(); + console.warn( 'THREE.OctahedronBufferGeometry has been renamed to THREE.OctahedronGeometry.' ); + super( radius, detail ); } } -// r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 +// r144 -class TextGeometry extends BufferGeometry { +class PlaneBufferGeometry extends PlaneGeometry { - constructor() { + constructor( width, height, widthSegments, heightSegments ) { - console.error( 'THREE.TextGeometry has been moved to /examples/jsm/geometries/TextGeometry.js' ); - super(); + 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 ); } } -// r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 +// r144 + +class RingBufferGeometry extends RingGeometry { -function FontLoader() { + constructor( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { - console.error( 'THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js' ); + console.warn( 'THREE.RingBufferGeometry has been renamed to THREE.RingGeometry.' ); + super( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ); + + } } -// r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92 +// r144 + +class ShapeBufferGeometry extends ShapeGeometry { -function Font() { + constructor( shapes, curveSegments ) { - console.error( 'THREE.Font has been moved to /examples/jsm/loaders/FontLoader.js' ); + console.warn( 'THREE.ShapeBufferGeometry has been renamed to THREE.ShapeGeometry.' ); + super( shapes, curveSegments ); + + } } -// r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0 +// r144 + +class SphereBufferGeometry extends SphereGeometry { -function ImmediateRenderObject() { + constructor( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { - console.error( 'THREE.ImmediateRenderObject has been removed.' ); + console.warn( 'THREE.SphereBufferGeometry has been renamed to THREE.SphereGeometry.' ); + super( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ); + + } } -// r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17 +// r144 -class WebGLMultisampleRenderTarget extends WebGLRenderTarget { +class TetrahedronBufferGeometry extends TetrahedronGeometry { - constructor( width, height, options ) { + constructor( radius, detail ) { - 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.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 ); } } -// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce +// r144 -class DataTexture2DArray extends DataArrayTexture { +class TorusKnotBufferGeometry extends TorusKnotGeometry { - constructor( data, width, height, depth ) { + constructor( radius, tube, tubularSegments, radialSegments, p, q ) { - console.warn( 'THREE.DataTexture2DArray has been renamed to DataArrayTexture.' ); - super( data, width, height, depth ); + console.warn( 'THREE.TorusKnotBufferGeometry has been renamed to THREE.TorusKnotGeometry.' ); + super( radius, tube, tubularSegments, radialSegments, p, q ); } } -// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce +// r144 -class DataTexture3D extends Data3DTexture { +class TubeBufferGeometry extends TubeGeometry { - constructor( data, width, height, depth ) { + constructor( path, tubularSegments, radius, radialSegments, closed ) { - console.warn( 'THREE.DataTexture3D has been renamed to Data3DTexture.' ); - super( data, width, height, depth ); + console.warn( 'THREE.TubeBufferGeometry has been renamed to THREE.TubeGeometry.' ); + super( path, tubularSegments, radius, radialSegments, closed ); } @@ -49002,4 +50272,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, 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, 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, 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, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, 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, 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, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, 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, TwoPassDoubleSide, 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, WebGLRenderTarget, WebGLRenderer, WebGLUtils, WireframeGeometry, WrapAroundEnding, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, _SRGBAFormat, sRGBEncoding }; diff --git a/docs/api/ar/audio/Audio.html b/docs/api/ar/audio/Audio.html index acdd9729d82d94..bac0abded5ec3c 100644 --- a/docs/api/ar/audio/Audio.html +++ b/docs/api/ar/audio/Audio.html @@ -89,7 +89,7 @@

[property:Number offset]

[property:Number duration]

يتجاوز مدة الصوت. مثل المعلمة *duration* لـ[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). الافتراضي هو *undefined* لتشغيل المخزن المؤقت بالكامل.

-

[property:String source]

+

[property:AudioNode source]

[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode AudioBufferSourceNode] تم إنشاؤها باستخدام [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createBufferSource AudioContext.createBufferSource]().

[property:String sourceType]

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/audio/Audio.html b/docs/api/en/audio/Audio.html index d66f1a2c7b3a8f..a2e3db410cf608 100644 --- a/docs/api/en/audio/Audio.html +++ b/docs/api/en/audio/Audio.html @@ -91,7 +91,7 @@

[property:Number offset]

[property:Number duration]

Overrides the duration of the audio. Same as the `duration` parameter of [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). Default is `undefined` to play the whole buffer.

-

[property:String source]

+

[property:AudioNode source]

An [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode AudioBufferSourceNode] created using [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createBufferSource AudioContext.createBufferSource]().

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 0aac77fd3a1ae0..c9d6d95eb32b50 100644 --- a/docs/api/en/core/BufferGeometry.html +++ b/docs/api/en/core/BufferGeometry.html @@ -138,7 +138,8 @@

[property:Boolean isBufferGeometry]

[property:Object morphAttributes]

- Hashmap of [page:BufferAttribute]s holding details of the geometry's morph targets. + Hashmap of [page:BufferAttribute]s holding details of the geometry's morph targets.
+ Note: Once the geometry has been rendered, the morph attribute data cannot be changed. You will have to call [page:.dispose](), and create a new instance of [name].

[property:Boolean morphTargetsRelative]

@@ -169,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.

@@ -192,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.
@@ -223,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] )

@@ -246,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. @@ -282,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. @@ -292,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/GLBufferAttribute.html b/docs/api/en/core/GLBufferAttribute.html index cd5412cf295f60..9ce59f944b011e 100644 --- a/docs/api/en/core/GLBufferAttribute.html +++ b/docs/api/en/core/GLBufferAttribute.html @@ -23,9 +23,9 @@

[name]

Constructor

[name]( [param:WebGLBuffer buffer], [param:GLenum type], [param:Integer itemSize], [param:Integer elementSize], [param:Integer count] )

- `buffer` — Must be a WebGLBuffer. + `buffer` — Must be a [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer].
- `type` — One of WebGL Data Types. + `type` — One of [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types WebGL Data Types].
`itemSize` — The number of values of the array that should be associated with a particular vertex. For instance, if this @@ -48,7 +48,7 @@

Properties

[property:WebGLBuffer buffer]

- The current WebGLBuffer instance. + The current [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer] instance.

[property:Integer count]

@@ -56,6 +56,11 @@

[property:Integer count]

The expected number of vertices in VBO.

+

[property:Boolean isGLBufferAttribute]

+

+ Read-only. Always `true`. +

+

[property:Integer itemSize]

How many values make up each item (vertex). @@ -69,9 +74,14 @@

[property:Integer elementSize]

See above (constructor) for a list of known type sizes.

+

[property:String name]

+

+ Optional name for this attribute instance. Default is an empty string. +

+

[property:GLenum type]

- A WebGL Data Type + A [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types WebGL Data Type] describing the underlying VBO contents.

@@ -79,11 +89,6 @@

[property:GLenum type]

using the `setType` method.

-

[property:Boolean isGLBufferAttribute]

-

- Read-only. Always `true`. -

-

Methods

[method:this setBuffer]( buffer )

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..8a3a6c9674b0dc 100644 --- a/docs/api/en/core/Object3D.html +++ b/docs/api/en/core/Object3D.html @@ -75,7 +75,7 @@

[property:Matrix4 matrix]

[property:Boolean matrixAutoUpdate]

When this is set, it calculates the matrix of position, (rotation or quaternion) and - scale every frame and also recalculates the matrixWorld property. Default is [page:Object3D.DefaultMatrixAutoUpdate] (true). + scale every frame and also recalculates the matrixWorld property. Default is [page:Object3D.DEFAULT_MATRIX_AUTO_UPDATE] (true).

[property:Matrix4 matrixWorld]

@@ -84,6 +84,13 @@

[property:Matrix4 matrixWorld]

the local transform [page:.matrix].

+

[property:Boolean matrixWorldAutoUpdate]

+

+ 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. + Default is [page:Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE] (true). +

+

[property:Boolean matrixWorldNeedsUpdate]

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

[property:Vector3 scale]

[property:Vector3 up]

This is used by the [page:.lookAt lookAt] method, for example, to determine the orientation of the result.
- Default is [page:Object3D.DefaultUp] - that is, `( 0, 1, 0 )`. + Default is [page:Object3D.DEFAULT_UP] - that is, `( 0, 1, 0 )`.

[property:Object userData]

@@ -187,25 +194,29 @@

[property:Boolean visible]

Static Properties

Static properties and methods are defined per class rather than per instance of that class. - This means that changing [page:Object3D.DefaultUp] or [page:Object3D.DefaultMatrixAutoUpdate] + This means that changing [page:Object3D.DEFAULT_UP] or [page:Object3D.DEFAULT_MATRIX_AUTO_UPDATE] will change the values of [page:.up up] and [page:.matrixAutoUpdate matrixAutoUpdate] for `every` instance of Object3D (or derived classes) created after the change has been made (already created Object3Ds will not be affected).

-

[property:Vector3 DefaultUp]

+

[property:Vector3 DEFAULT_UP]

The default [page:.up up] direction for objects, also used as the default position for [page:DirectionalLight], [page:HemisphereLight] and [page:Spotlight] (which creates lights shining from the top down).
Set to ( 0, 1, 0 ) by default.

-

[property:Boolean DefaultMatrixAutoUpdate]

+

[property:Boolean DEFAULT_MATRIX_AUTO_UPDATE]

The default setting for [page:.matrixAutoUpdate matrixAutoUpdate] for newly created Object3Ds.

+

[property:Boolean DEFAULT_MATRIX_WORLD_AUTO_UPDATE]

+

+ The default setting for [page:.matrixWorldAutoUpdate matrixWorldAutoUpdate] for newly created Object3Ds.
+

Methods

@@ -271,6 +282,14 @@

[method:Object3D getObjectByProperty]( [param:String name], [param:Any value Searches through an object and its children, starting with the object itself, and returns the first with a property that matches the value given.

+

[method:Object3D getObjectsByProperty]( [param:String name], [param:Any value] )

+

+ name -- the property name to search for.
+ value -- value of the given property.

+ + Searches through an object and its children, starting with the object itself, and returns all the objects with a property that matches the value given. +

+

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

[page:Vector3 target] — the result will be copied into this Vector3.

@@ -318,7 +337,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 +483,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/core/Raycaster.html b/docs/api/en/core/Raycaster.html index 5174cd65d55175..980448ae062014 100644 --- a/docs/api/en/core/Raycaster.html +++ b/docs/api/en/core/Raycaster.html @@ -65,7 +65,7 @@

Examples

[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_raycast_texture Raycast to a Texture] + [example:webgl_raycaster_texture Raycast to a Texture]

Constructor

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/Path.html b/docs/api/en/extras/core/Path.html index 74679146baefad..0a7f878cd54eb5 100644 --- a/docs/api/en/extras/core/Path.html +++ b/docs/api/en/extras/core/Path.html @@ -52,7 +52,7 @@

[name]( [param:Array points] )

Properties

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

-

[property:Array currentPoint]

+

[property:Vector2 currentPoint]

The current offset of the path. Any new [page:Curve] added will start here.

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/geometries/CircleGeometry.html b/docs/api/en/geometries/CircleGeometry.html index 2827406b0dd068..1825ac3c360947 100644 --- a/docs/api/en/geometries/CircleGeometry.html +++ b/docs/api/en/geometries/CircleGeometry.html @@ -50,7 +50,7 @@

Constructor

[name]([param:Float radius], [param:Integer segments], [param:Float thetaStart], [param:Float thetaLength])

radius — Radius of the circle, default = 1.
- segments — Number of segments (triangles), minimum = 3, default = 8.
+ segments — Number of segments (triangles), minimum = 3, default = 32.
thetaStart — Start angle for first segment, default = 0 (three o'clock position).
thetaLength — The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.

diff --git a/docs/api/en/geometries/ConeGeometry.html b/docs/api/en/geometries/ConeGeometry.html index 57d1660018c3d8..6653ea1dff7211 100644 --- a/docs/api/en/geometries/ConeGeometry.html +++ b/docs/api/en/geometries/ConeGeometry.html @@ -45,7 +45,7 @@

[name]([param:Float radius], [param:Float height], [param:Integer radialSegm

radius — Radius of the cone base. Default is 1.
height — Height of the cone. Default is 1.
- radialSegments — Number of segmented faces around the circumference of the cone. Default is 8
+ radialSegments — Number of segmented faces around the circumference of the cone. Default is 32
heightSegments — Number of rows of faces along the height of the cone. Default is 1.
openEnded — A Boolean indicating whether the base of the cone is open or capped. Default is false, meaning capped.
thetaStart — Start angle for first segment, default = 0 (three o'clock position).
diff --git a/docs/api/en/geometries/CylinderGeometry.html b/docs/api/en/geometries/CylinderGeometry.html index d9fb24cd896a23..4c6c295dd52433 100644 --- a/docs/api/en/geometries/CylinderGeometry.html +++ b/docs/api/en/geometries/CylinderGeometry.html @@ -46,7 +46,7 @@

[name]([param:Float radiusTop], [param:Float radiusBottom], [param:Float hei radiusTop — Radius of the cylinder at the top. Default is 1.
radiusBottom — Radius of the cylinder at the bottom. Default is 1.
height — Height of the cylinder. Default is 1.
- radialSegments — Number of segmented faces around the circumference of the cylinder. Default is 8
+ radialSegments — Number of segmented faces around the circumference of the cylinder. Default is 32
heightSegments — Number of rows of faces along the height of the cylinder. Default is 1.
openEnded — A Boolean indicating whether the ends of the cylinder are open or capped. Default is false, meaning capped.
thetaStart — Start angle for first segment, default = 0 (three o'clock position).
diff --git a/docs/api/en/geometries/LatheGeometry.html b/docs/api/en/geometries/LatheGeometry.html index 1d5e627a1918e6..d8686ba890b47d 100644 --- a/docs/api/en/geometries/LatheGeometry.html +++ b/docs/api/en/geometries/LatheGeometry.html @@ -48,7 +48,7 @@

Constructor

[name]([param:Array points], [param:Integer segments], [param:Float phiStart], [param:Float phiLength])

- points — Array of Vector2s. The x-coordinate of each point must be greater than zero. Default is an array with (0,0.5), (0.5,0) and (0,-0.5) which creates a simple diamond shape.
+ points — Array of Vector2s. The x-coordinate of each point must be greater than zero. Default is an array with (0,-0.5), (0.5,0) and (0,0.5) which creates a simple diamond shape.
segments — the number of circumference segments to generate. Default is 12.
phiStart — the starting angle in radians. Default is 0.
phiLength — the radian (0 to 2PI) range of the lathed section 2PI is a closed lathe, less than 2PI is a portion. Default is 2PI. diff --git a/docs/api/en/geometries/RingGeometry.html b/docs/api/en/geometries/RingGeometry.html index 0047a9b7353f74..4dde063dfa73b5 100644 --- a/docs/api/en/geometries/RingGeometry.html +++ b/docs/api/en/geometries/RingGeometry.html @@ -45,7 +45,7 @@

[name]([param:Float innerRadius], [param:Float outerRadius], [param:Integer

innerRadius — Default is 0.5.
outerRadius — Default is 1.
- thetaSegments — Number of segments. A higher number means the ring will be more round. Minimum is 3. Default is 8.
+ thetaSegments — Number of segments. A higher number means the ring will be more round. Minimum is 3. Default is 32.
phiSegments — Minimum is 1. Default is 1.
thetaStart — Starting angle. Default is 0.
thetaLength — Central angle. Default is Math.PI * 2. diff --git a/docs/api/en/geometries/TorusGeometry.html b/docs/api/en/geometries/TorusGeometry.html index 0c4ef072df49bf..3d30968e7eb299 100644 --- a/docs/api/en/geometries/TorusGeometry.html +++ b/docs/api/en/geometries/TorusGeometry.html @@ -45,8 +45,8 @@

[name]([param:Float radius], [param:Float tube], [param:Integer radialSegmen

radius - Radius of the torus, from the center of the torus to the center of the tube. Default is 1.
tube — Radius of the tube. Default is 0.4.
- radialSegments — Default is 8
- tubularSegments — Default is 6.
+ radialSegments — Default is 12
+ tubularSegments — Default is 48.
arc — Central angle. Default is Math.PI * 2.

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 f72c790dd3a8aa..27953560b4ab3d 100644 --- a/docs/api/en/helpers/CameraHelper.html +++ b/docs/api/en/helpers/CameraHelper.html @@ -12,8 +12,8 @@

[name]

- This helps with visualizing what a camera contains in its frustum.
- It visualizes the frustum of a camera using a [page:LineSegments]. + This helps with visualizing what a camera contains in its frustum. It visualizes the frustum of a camera using a [page:LineSegments].

+ [name] must be a child of the scene.

Code Example

@@ -61,7 +61,12 @@

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] )

+

+ Defines the colors of the helper.

[method:undefined update]()

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/AmbientLight.html b/docs/api/en/lights/AmbientLight.html index 1dc991101f2443..db210f505f034e 100644 --- a/docs/api/en/lights/AmbientLight.html +++ b/docs/api/en/lights/AmbientLight.html @@ -24,11 +24,6 @@

Code Example

scene.add( light );
-

Examples

-

- [example:webgl_animation_skinning_blending animation / skinning / blending ] -

-

Constructor

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

diff --git a/docs/api/en/lights/DirectionalLight.html b/docs/api/en/lights/DirectionalLight.html index f2f309bd7d01da..1eee76d0374beb 100644 --- a/docs/api/en/lights/DirectionalLight.html +++ b/docs/api/en/lights/DirectionalLight.html @@ -81,7 +81,7 @@

[property:Boolean isDirectionalLight]

[property:Vector3 position]

- This is set equal to [page:Object3D.DefaultUp] (0, 1, 0), so that the light shines from the top down. + This is set equal to [page:Object3D.DEFAULT_UP] (0, 1, 0), so that the light shines from the top down.

[property:DirectionalLightShadow shadow]

@@ -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/HemisphereLight.html b/docs/api/en/lights/HemisphereLight.html index a4d11031367010..fd0c82e544a7f2 100644 --- a/docs/api/en/lights/HemisphereLight.html +++ b/docs/api/en/lights/HemisphereLight.html @@ -69,7 +69,7 @@

[property:Boolean isHemisphereLight]

[property:Vector3 position]

- This is set equal to [page:Object3D.DefaultUp] (0, 1, 0), so that the light shines from the top down. + This is set equal to [page:Object3D.DEFAULT_UP] (0, 1, 0), so that the light shines from the top down.

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..1eb0b9b16912a6 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].

@@ -52,12 +51,18 @@

Properties

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

+ +

[property:Boolean castShadow]

+

+ If set to `true` light will cast dynamic shadows. *Warning*: This is expensive and + requires tweaking to get shadows looking right. See the [page:PointLightShadow] for details. + The default is `false`. +

[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 +118,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..103bffd75901e6 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.

@@ -126,7 +126,7 @@

[property:Float penumbra]

[property:Vector3 position]

- This is set equal to [page:Object3D.DefaultUp] (0, 1, 0), so that the light shines from the top down. + This is set equal to [page:Object3D.DEFAULT_UP] (0, 1, 0), so that the light shines from the top down.

[property:Float 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..bd18a541b15c02 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`. @@ -128,6 +128,15 @@

[property:Boolean depthWrite]

When drawing 2D overlays it can be useful to disable the depth writing in order to layer several things together without creating z-index artifacts.

+

[property:Boolean forceSinglePass]

+

+ Whether double-sided, transparent objects should be rendered with a single pass or not. Default is `false`.

+ + The engine renders double-sided, transparent objects with two draw calls (back faces first, then front faces) to mitigate transparency artifacts. + There are scenarios however where this approach produces no quality gains but still doubles draw calls e.g. when rendering flat vegetation like grass sprites. + In these cases, set the `forceSinglePass` flag to `false` to disable the two pass rendering to avoid performance issues. +

+

[property:Boolean isMaterial]

Read-only flag to check if a given object is of type [name]. @@ -260,7 +269,7 @@

[property:Integer side]

Defines which side of faces will be rendered - front, back or both. Default is [page:Materials THREE.FrontSide]. - Other options are [page:Materials THREE.BackSide] and [page:Materials THREE.DoubleSide]. + Other options are [page:Materials THREE.BackSide] or [page:Materials THREE.DoubleSide].

[property:Boolean toneMapped]

@@ -292,12 +301,13 @@

[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]

Defines whether vertex coloring is used. Default is `false`. + The engine supports RGB and RGBA vertex colors depending on whether a three (RGB) or four (RGBA) component color buffer attribute is used.

[property:Boolean visible]

@@ -323,8 +333,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/MeshBasicMaterial.html b/docs/api/en/materials/MeshBasicMaterial.html index 675971fa0dd6f0..f0beacc102f32b 100644 --- a/docs/api/en/materials/MeshBasicMaterial.html +++ b/docs/api/en/materials/MeshBasicMaterial.html @@ -93,7 +93,10 @@

[property:Float lightMapIntensity]

Intensity of the baked light. Default is 1.

[property:Texture map]

-

The color map. Default is null.

+

+ The color map. May optionally include an alpha channel, typically combined with + [page:Material.transparent .transparent] or [page:Material.alphaTest .alphaTest]. Default is null. +

[property:Float reflectivity]

diff --git a/docs/api/en/materials/MeshDepthMaterial.html b/docs/api/en/materials/MeshDepthMaterial.html index 8b3819f67ce69e..3d3d7b2362b10f 100644 --- a/docs/api/en/materials/MeshDepthMaterial.html +++ b/docs/api/en/materials/MeshDepthMaterial.html @@ -82,7 +82,10 @@

[property:Boolean fog]

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

[property:Texture map]

-

The color map. Default is null.

+

+ The color map. May optionally include an alpha channel, typically combined with + [page:Material.transparent .transparent] or [page:Material.alphaTest .alphaTest]. Default is null. +

[property:Boolean wireframe]

Render geometry as wireframe. Default is false (i.e. render as smooth shaded).

diff --git a/docs/api/en/materials/MeshDistanceMaterial.html b/docs/api/en/materials/MeshDistanceMaterial.html index e978afb60baceb..7d8da62ba281a2 100644 --- a/docs/api/en/materials/MeshDistanceMaterial.html +++ b/docs/api/en/materials/MeshDistanceMaterial.html @@ -93,7 +93,10 @@

[property:Boolean fog]

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

[property:Texture map]

-

The color map. Default is null.

+

+ The color map. May optionally include an alpha channel, typically combined with + [page:Material.transparent .transparent] or [page:Material.alphaTest .alphaTest]. Default is null. +

[property:Float nearDistance]

diff --git a/docs/api/en/materials/MeshLambertMaterial.html b/docs/api/en/materials/MeshLambertMaterial.html index 64d376fc6e58a9..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`.

@@ -120,7 +151,31 @@

[property:Float lightMapIntensity]

Intensity of the baked light. Default is 1.

[property:Texture map]

-

The color map. Default is null.

+

+ The color map. May optionally include an alpha channel, typically combined with + [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/MeshMatcapMaterial.html b/docs/api/en/materials/MeshMatcapMaterial.html index 0eb7d6e4b8ad72..2256c752029d6b 100644 --- a/docs/api/en/materials/MeshMatcapMaterial.html +++ b/docs/api/en/materials/MeshMatcapMaterial.html @@ -104,7 +104,11 @@

[property:Boolean fog]

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

[property:Texture map]

-

The color map. Default is null. The texture map color is modulated by the diffuse [page:.color].

+

+ The color map. May optionally include an alpha channel, typically combined with + [page:Material.transparent .transparent] or [page:Material.alphaTest .alphaTest]. Default is null. + The texture map color is modulated by the diffuse [page:.color]. +

[property:Texture matcap]

The matcap map. Default is null.

diff --git a/docs/api/en/materials/MeshPhongMaterial.html b/docs/api/en/materials/MeshPhongMaterial.html index 298e7262e70eb1..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. @@ -157,7 +151,11 @@

[property:Float lightMapIntensity]

Intensity of the baked light. Default is 1.

[property:Texture map]

-

The color map. Default is null. The texture map color is modulated by the diffuse [page:.color].

+

+ The color map. May optionally include an alpha channel, typically combined with + [page:Material.transparent .transparent] or [page:Material.alphaTest .alphaTest]. Default is null. + The texture map color is modulated by the diffuse [page:.color]. +

[property:Texture normalMap]

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 6bd0c9a8b855cd..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.

    @@ -192,7 +186,11 @@

    [property:Float lightMapIntensity]

    Intensity of the baked light. Default is 1.

    [property:Texture map]

    -

    The color map. Default is null. The texture map color is modulated by the diffuse [page:.color].

    +

    + The color map. May optionally include an alpha channel, typically combined with + [page:Material.transparent .transparent] or [page:Material.alphaTest .alphaTest]. Default is null. + The texture map color is modulated by the diffuse [page:.color]. +

    [property:Float metalness]

    diff --git a/docs/api/en/materials/MeshToonMaterial.html b/docs/api/en/materials/MeshToonMaterial.html index a715345f18aa49..38a3ca9dbbb3bc 100644 --- a/docs/api/en/materials/MeshToonMaterial.html +++ b/docs/api/en/materials/MeshToonMaterial.html @@ -134,7 +134,11 @@

    [property:Float lightMapIntensity]

    Intensity of the baked light. Default is 1.

    [property:Texture map]

    -

    The color map. Default is null. The texture map color is modulated by the diffuse [page:.color].

    +

    + The color map. May optionally include an alpha channel, typically combined with + [page:Material.transparent .transparent] or [page:Material.alphaTest .alphaTest]. Default is null. + The texture map color is modulated by the diffuse [page:.color]. +

    [property:Texture normalMap]

    diff --git a/docs/api/en/materials/PointsMaterial.html b/docs/api/en/materials/PointsMaterial.html index bea067e056f9f3..b2fb947e3befce 100644 --- a/docs/api/en/materials/PointsMaterial.html +++ b/docs/api/en/materials/PointsMaterial.html @@ -85,7 +85,11 @@

    [property:Boolean fog]

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

    [property:Texture map]

    -

    Sets the color of the points using data from a [page:Texture].

    +

    + Sets the color of the points using data from a [page:Texture]. + May optionally include an alpha channel, typically combined with + [page:Material.transparent .transparent] or [page:Material.alphaTest .alphaTest]. +

    [property:Number size]

    Defines the size of the points in pixels. Default is 1.0.
    @@ -96,6 +100,7 @@

    [property:Boolean sizeAttenuation]

    Methods

    +

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

    Source

    diff --git a/docs/api/en/materials/SpriteMaterial.html b/docs/api/en/materials/SpriteMaterial.html index 359e70f341a891..de780a7bc14038 100644 --- a/docs/api/en/materials/SpriteMaterial.html +++ b/docs/api/en/materials/SpriteMaterial.html @@ -26,7 +26,7 @@

    Code Example

    Examples

    - [example:webgl_raycast_sprite WebGL / raycast / sprite]
    + [example:webgl_raycaster_sprite WebGL / raycast / sprite]
    [example:webgl_sprites WebGL / sprites]
    [example:svg_sandbox SVG / sandbox]

    @@ -71,7 +71,10 @@

    [property:Boolean isSpriteMaterial]

    [property:Texture map]

    -

    The texture map. Default is null.

    +

    + The color map. May optionally include an alpha channel, typically combined with + [page:Material.transparent .transparent] or [page:Material.alphaTest .alphaTest]. Default is null. +

    [property:Radians rotation]

    The rotation of the sprite in radians. Default is 0.

    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/Matrix4.html b/docs/api/en/math/Matrix4.html index e47221b3f98865..ca6db3fda85fdc 100644 --- a/docs/api/en/math/Matrix4.html +++ b/docs/api/en/math/Matrix4.html @@ -215,7 +215,7 @@

    [method:this makeRotationAxis]( [param:Vector3 axis], [param:Float theta] )< Sets this matrix as rotation transform around [page:Vector3 axis] by [page:Float theta] radians.
    - This is a somewhat controversial but mathematically sound alternative to rotating via [page:Quaternions]. + This is a somewhat controversial but mathematically sound alternative to rotating via [page:Quaternion Quaternions]. See the discussion [link:https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199 here].

    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 7c38b521dc9d57..044b2cc7dc090b 100644 --- a/docs/api/en/objects/InstancedMesh.html +++ b/docs/api/en/objects/InstancedMesh.html @@ -21,7 +21,6 @@

    Examples

    [example:webgl_instancing_dynamic WebGL / instancing / dynamic]
    - [example:webgl_instancing_modified WebGL / instancing / modified]
    [example:webgl_instancing_performance WebGL / instancing / performance]
    [example:webgl_instancing_scatter WebGL / instancing / scatter]
    [example:webgl_instancing_raycast WebGL / instancing / raycast] @@ -70,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/Mesh.html b/docs/api/en/objects/Mesh.html index fddb3c43fbdc52..87c8bd8ee4cbfc 100644 --- a/docs/api/en/objects/Mesh.html +++ b/docs/api/en/objects/Mesh.html @@ -72,6 +72,12 @@

    Methods

    [method:Mesh clone]()

    Returns a clone of this [name] object and its descendants.

    +

    [method:Vector3 getVertexPosition]( [param:Integer index], [param:Vector3 target] )

    +

    + Get the local-space position of the vertex at the given index, taking into account the + current animation state of both morph targets and skinning. +

    +

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

    Get intersections between a casted ray and this mesh. 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/objects/SkinnedMesh.html b/docs/api/en/objects/SkinnedMesh.html index fa06628a4f953b..7f6ba86d19e5e4 100644 --- a/docs/api/en/objects/SkinnedMesh.html +++ b/docs/api/en/objects/SkinnedMesh.html @@ -158,7 +158,7 @@

    [method:undefined pose]()

    [method:Vector3 boneTransform]( [param:Integer index], [param:Vector3 target] )

    Calculates the position of the vertex at the given index relative to the current bone transformations. - Target vector must be initialized with the vetrex coordinates prior to the transformation: + Target vector must be initialized with the vertex coordinates prior to the transformation: const target = new THREE.Vector3(); target.fromBufferAttribute( mesh.geometry.attributes.position, index ); 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 27a97c8f7da61d..ee359f7ab1aee3 100644 --- a/docs/api/en/renderers/WebGLRenderTarget.html +++ b/docs/api/en/renderers/WebGLRenderTarget.html @@ -23,9 +23,9 @@

    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.
    - options - (optional object that holds texture parameters for an auto-generated target + [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. For an explanation of the texture parameters see [page:Texture Texture]. The following are @@ -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 a0be922c96eb9e..2ba3ee452b921e 100644 --- a/docs/api/en/renderers/WebGLRenderer.html +++ b/docs/api/en/renderers/WebGLRenderer.html @@ -33,8 +33,7 @@

    [name]( [param:Object parameters] )

    Default is null.
    [page:String precision] - Shader precision. Can be `"highp"`, `"mediump"` or `"lowp"`. - Defaults to `"highp"` if supported by the device. See the note in "Things to Avoid" - [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices here].
    + Defaults to `"highp"` if supported by the device.
    [page:Boolean alpha] - controls the default clear alpha value. When set to `true`, the value is `0`. Otherwise it's `1`. Default is `false`.
    @@ -311,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]()

    @@ -408,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/FramebufferTexture.html b/docs/api/en/textures/FramebufferTexture.html index 9f3840dfd159be..5f04b916b1bc1b 100644 --- a/docs/api/en/textures/FramebufferTexture.html +++ b/docs/api/en/textures/FramebufferTexture.html @@ -15,7 +15,34 @@

    [name]

    This class can only be used in combination with [page:WebGLRenderer.copyFramebufferToTexture]().

    + + const pixelRatio = window.devicePixelRatio; + const textureSize = 128 * pixelRatio; + + // instantiate a framebuffer texture + const frameTexture = new FramebufferTexture( textureSize, textureSize, RGBAFormat ); + + // calculate start position for copying part of the frame data + const vector = new Vector2(); + vector.x = ( window.innerWidth * pixelRatio / 2 ) - ( textureSize / 2 ); + vector.y = ( window.innerHeight * pixelRatio / 2 ) - ( textureSize / 2 ); + + // render the scene + renderer.clear(); + renderer.render( scene, camera ); + + // copy part of the rendered frame into the framebuffer texture + renderer.copyFramebufferToTexture( vector, frameTexture ); + + +

    Examples

    + +

    + [example:webgl_framebuffer_texture] +

    +

    Constructor

    +

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

    [page:Number width] -- The width of the texture.
    @@ -31,11 +58,34 @@

    Properties

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

    +

    [property:Boolean generateMipmaps]

    +

    + Whether to generate mipmaps for the [name]. Default value is `false`. +

    +

    [property:Boolean isFramebufferTexture]

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

    +

    [property:number magFilter]

    +

    + How the texture is sampled when a texel covers more than one pixel. The default is + [page:Textures THREE.NearestFilter], which uses the value of the closest texel. +

    + + See [page:Textures texture constants] for details. +

    + +

    [property:number minFilter]

    +

    + How the texture is sampled when a texel covers less than one pixel. The default is + [page:Textures THREE.NearestFilter], which uses the value of the closest texel. +

    + + See [page:Textures texture constants] for details. +

    +

    [property:Boolean needsUpdate]

    diff --git a/docs/api/en/textures/Source.html b/docs/api/en/textures/Source.html index 51fa8f5c5b956e..59aeffff1af60d 100644 --- a/docs/api/en/textures/Source.html +++ b/docs/api/en/textures/Source.html @@ -27,6 +27,11 @@

    [property:Any data]

    The actual data of a texture. The type of this property depends on the texture that uses this instance.

    +

    [property:Boolean isSource]

    +

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

    +

    [property:Boolean needsUpdate]

    Set this to `true` to trigger a data upload to the GPU next time the source is used. @@ -40,7 +45,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..46121542b9034b --- /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:AudioNode 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..27d04eaf266ad7 --- /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 = 32.
    + 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..91b8d6cd05ede2 --- /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 32.
    + 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..6ddbd557ca3812 --- /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 32.
    + 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..fc30ff85cd7271 --- /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 32.
    + 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..468fdbb1c632b2 --- /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 12
    + tubularSegments — La valeur par défaut est 48.
    + 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..34fdec70561131 --- /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:AudioNode 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..799cfd40f81ceb --- /dev/null +++ b/docs/api/it/core/GLBufferAttribute.html @@ -0,0 +1,120 @@ + + + + + + + + + +

    [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 [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer]. +
    + `type` — Uno dei [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types 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 [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer]. +

    + +

    [property:Integer count]

    +

    + Il numero previsto di vertici in VBO. +

    + +

    [property:Boolean isGLBufferAttribute]

    +

    + Solo lettura. Sempre `true`. +

    + +

    [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:String name]

    +

    + Un nome opzionale per questa istanza dell'attributo. Il valore predefinito è una stringa vuota. +

    + +

    [property:GLenum type]

    +

    + Un [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types WebGL Data Type] + che descrive i contenuti VBO. +

    +

    + Imposta questa proprietà insieme a `elementSize`. Il modo consigliato è + di usare il metodo `setType`. +

    + +

    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..d79e8063ccc6c6 --- /dev/null +++ b/docs/api/it/core/Object3D.html @@ -0,0 +1,512 @@ + + + + + + + + + +

    [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.DEFAULT_MATRIX_AUTO_UPDATE] (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]

    +

    + 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. + Default is [page:Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE] (true). +

    + +

    [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.DEFAULT_UP] - 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.DEFAULT_UP] o [page:Object3D.DEFAULT_MATRIX_AUTO_UPDATE] + 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 DEFAULT_UP]

    +

    + 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 DEFAULT_MATRIX_AUTO_UPDATE]

    +

    + L'impostazione predefinita per [page:.matrixAutoUpdate matrixAutoUpdate] per Object3D appena creati.
    +

    + +

    [property:Boolean DEFAULT_MATRIX_WORLD_AUTO_UPDATE]

    +

    + L'impostazione predefinita per[page:.matrixWorldAutoUpdate matrixWorldAutoUpdate] 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:Object3D getObjectsByProperty]( [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 tutti gli oggetti 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..42f8ba3612e38e --- /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 è 32.
    + 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..a45860c470368f --- /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 è 32.
    + 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..909a2daa482d3d --- /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 è 32
    + 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..0b7ed9d7e6538a --- /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 è 32.
    + 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..6a2459237c60c8 --- /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 è 12.
    • +
    • radialSegments — Il valore predefinito è 48.
    • +
    • 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..7b14b3916751ee --- /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].

    + [name] must be a child of the scene. +

    + +

    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..2ae38720b818f0 --- /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.DEFAULT_UP] (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..02a7346114511d --- /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.DEFAULT_UP] (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..106ac7f0563171 --- /dev/null +++ b/docs/api/it/lights/PointLight.html @@ -0,0 +1,136 @@ + + + + + + + + + + [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: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. Vedi + [page:PointLightShadow] per i dettagli. Il valore predefinito è `false`. +

    + +

    [property:Float decay]

    +

    + La quantità di luce che si attenua lungo la distanza della luce. L'impostazione predefinita + è `2`.
    + Nel contesto di un rendering fisicamente corretto, il valore predefinito non deve essere modificato. +

    + +

    [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..1ada80b1ad9afb --- /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.DEFAULT_UP] (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..65f7196c0960d0 --- /dev/null +++ b/docs/api/it/materials/Material.html @@ -0,0 +1,419 @@ + + + + + + + + + +

    [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 forceSinglePass]

    +

    + Whether double-sided, transparent objects should be rendered with a single pass or not. Default is `false`.

    + + The engine renders double-sided, transparent objects with two draw calls (back faces first, then front faces) to mitigate transparency artifacts. + There are scenarios however where this approach produces no quality gains but still doubles draw calls e.g. when rendering flat vegetation like grass sprites. + In these cases, set the `forceSinglePass` flag to `false` to disable the two pass rendering to avoid performance issues. +

    + +

    [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`. + The engine supports RGB and RGBA vertex colors depending on whether a three (RGB) or four (RGBA) component color buffer attribute is used. +

    + +

    [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..46ebce6a0352cc --- /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] — Angolo di rotazione in radianti. I valori positivi ruotano in senso antiorario.

    + + Imposta questa matrice come una trasformazione rotazionale 2D di [page:Float teta] radianti. + La matrice risultante sarà: + +cos(θ) -sin(θ) 0 +sin(θ) cos(θ) 0 +0 0 1 + +

    + +

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

    +

    + [page:Float x] - la quantità da scalare sull'asse X.
    + [page:Float y] - la quantità da scalare sull'asse Y.
    + + Imposta questa matrice come una trasformazione di scala 2D: + +x, 0, 0, +0, y, 0, +0, 0, 1 + +

    + +

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

    +

    + [page:Float x] - la quantità da translare sull'asse X.
    + [page:Float y] - la quantità da translare sull'asse Y.
    + + Imposta questa matrice come una trasformazione di traslazione 2D: + +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. I valori positivi ruotano in senso antiorario
    + [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..e79c38b86a0a89 --- /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] - Soglia utilizzata per evitare il flickering ai confini del LOD, come frazione della distanza. +

    + +

    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] - Soglia utilizzata per evitare il flickering ai confini del LOD, come frazione della distanza. Il valore predefinito è 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..a296827b874510 --- /dev/null +++ b/docs/api/it/renderers/webxr/WebXRManager.html @@ -0,0 +1,153 @@ + + + + + + + + + + +

    [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] — Indica se il fattore di scala del framebuffer deve essere ridotto al + limite nativo se il valore risulta superiore alle capacità del dispositivo. Il valore predefinito è `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..8a4e0eb1531788 --- /dev/null +++ b/docs/api/it/textures/Source.html @@ -0,0 +1,65 @@ + + + + + + + + + +

    [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 isSource]

    +

    + Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. +

    + +

    [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/audio/Audio.html b/docs/api/ko/audio/Audio.html index 3658a27374a930..e47e9a7364772d 100644 --- a/docs/api/ko/audio/Audio.html +++ b/docs/api/ko/audio/Audio.html @@ -89,7 +89,7 @@

    [property:Number offset]

    [property:Number duration]

    오디오 길이를 오버라이드합니다. [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start]()의 *duration* 파라미터와 동일. 전체 버퍼 재생을 위한 기본값은 *undefined*입니다.

    -

    [property:String source]

    +

    [property:AudioNode source]

    [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createBufferSource AudioContext.createBufferSource]()로 생성된 [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode AudioBufferSourceNode]입니다. 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 6765bee4c3487b..89ca5fdb7eb163 100644 --- a/docs/api/ko/core/BufferGeometry.html +++ b/docs/api/ko/core/BufferGeometry.html @@ -134,7 +134,8 @@

    [property:Boolean isBufferGeometry]

    [property:Object morphAttributes]

    - [page:BufferAttribute]의 해쉬맵은 기하학의 모프 타겟에 대한 세부정보를 담고 있습니다. + [page:BufferAttribute]의 해쉬맵은 기하학의 모프 타겟에 대한 세부정보를 담고 있습니다.
    + Note: Once the geometry has been rendered, the morph attribute data cannot be changed. You will have to call [page:.dispose](), and create a new instance of [name].

    [property:Boolean morphTargetsRelative]

    @@ -238,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/GLBufferAttribute.html b/docs/api/ko/core/GLBufferAttribute.html index ab0b0eb476833a..753eb339d3e205 100644 --- a/docs/api/ko/core/GLBufferAttribute.html +++ b/docs/api/ko/core/GLBufferAttribute.html @@ -20,9 +20,9 @@

    [name]

    생성자

    [name]( [param:WebGLBuffer buffer], [param:GLenum type], [param:Integer itemSize], [param:Integer elementSize], [param:Integer count] )

    - *buffer* — 반드시 WebGLBuffer여야 합니다. + *buffer* — 반드시 [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer]여야 합니다.
    - *type* — WebGL 데이터 타입 중 하나. + *type* — [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types WebGL] 데이터 타입 중 하나.
    *itemSize* — 특정 꼭짓점가 연관되어야 하는 배열의 값의 수. 예를 들어 이 속성이 3-컴포넌트 벡터(예: 위치, 법선 또는 색상)를 저장하는 경우 ( itemSize는 3이어야 합니다. @@ -44,7 +44,7 @@

    프로퍼티

    [property:WebGLBuffer buffer]

    - 현재의 WebGLBuffer 인스턴스. + 현재의 [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer] 인스턴스.

    [property:Integer count]

    @@ -52,6 +52,11 @@

    [property:Integer count]

    VBO의 꼭짓점 수.

    +

    [property:Boolean isGLBufferAttribute]

    +

    + 읽기 전용. 언제나 *true*입니다. +

    +

    [property:Integer itemSize]

    각 항목을 구성하는 값의 크기 (꼭짓점). @@ -65,20 +70,20 @@

    [property:Integer elementSize]

    알려진 타입 크기 리스트는 위의 (생성자)를 참고.

    +

    [property:String name]

    +

    + 이 속성 인스턴스의 임시 이름. 기본값은 빈 문자열입니다. +

    +

    [property:GLenum type]

    - 기저의 VBO 컨텐츠를 묘사하는 WebGL Data Type + 기저의 VBO 컨텐츠를 묘사하는 [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types WebGL Data Type] .

    *elementSize*와 함께 이 속성을 설정합니다. 추천하는 방법은 *setType* 메서드를 사용하는 것입니다.

    -

    [property:Boolean isGLBufferAttribute]

    -

    - 읽기 전용. 언제나 *true*입니다. -

    -

    메서드

    [method:this setBuffer]( buffer )

    diff --git a/docs/api/ko/core/Object3D.html b/docs/api/ko/core/Object3D.html index eac76952508da2..99c9331cdaf861 100644 --- a/docs/api/ko/core/Object3D.html +++ b/docs/api/ko/core/Object3D.html @@ -75,7 +75,7 @@

    [property:Matrix4 matrix]

    [property:Boolean matrixAutoUpdate]

    이 값을 설정하면 위치의 매트릭스를 계산하고 (회전 및 쿼터니언), 매 프레임마다 확대/축소하고 matrixWorld 프로퍼티를 재계산합니다. - 기본값은 [page:Object3D.DefaultMatrixAutoUpdate] (true)입니다. + 기본값은 [page:Object3D.DEFAULT_MATRIX_AUTO_UPDATE] (true)입니다.

    [property:Matrix4 matrixWorld]

    @@ -83,6 +83,13 @@

    [property:Matrix4 matrixWorld]

    객체의 글로벌 변형입니다. Object3D가 부모를 가지고 있지 않다면, 로컬 변형 [page:.matrix]와 동일합니다.

    +

    [property:Boolean matrixWorldAutoUpdate]

    +

    + 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. + Default is [page:Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE] (true). +

    +

    [property:Boolean matrixWorldNeedsUpdate]

    이 값을 설정하면 When this is set, it calculates the 해당 프레임의 matrixWorld를 계산하고 이 프로퍼티를 false로 초기화합니다. @@ -157,7 +164,7 @@

    [property:Vector3 scale]

    [property:Vector3 up]

    [page:.lookAt lookAt] 메서드에서 사용되며, 결과의 방향을 결정합니다.
    - 기본값은 [page:Object3D.DefaultUp]값, ( 0, 1, 0 )입니다. + 기본값은 [page:Object3D.DEFAULT_UP]값, ( 0, 1, 0 )입니다.

    [property:Object userData]

    @@ -180,24 +187,28 @@

    [property:Boolean visible]

    정적 프로퍼티

    정적 프로퍼티와 메서드는 해당 클래스의 인스턴스가 아니라 클래스 별로 정의됩니다. - 이는 [page:Object3D.DefaultUp] 혹은 [page:Object3D.DefaultMatrixAutoUpdate]를 변경하면 + 이는 [page:Object3D.DEFAULT_UP] 혹은 [page:Object3D.DEFAULT_MATRIX_AUTO_UPDATE]를 변경하면 변경이 이루어진 시점 이후의(이미 만들어진 Object3Ds는 영향을 받지 않습니다) 모든 Object3D(및 파생 클래스)의 [page:.up up]과 [page:.matrixAutoUpdate matrixAutoUpdate] 값을 변경시킬 것입니다.

    -

    [property:Vector3 DefaultUp]

    +

    [property:Vector3 DEFAULT_UP]

    The default 오브젝트의 기본값 [page:.up up] 방향이며 [page:DirectionalLight], [page:HemisphereLight] 및 [page:Spotlight]의 기본 위치값으로도 사용됩니다(위에서 아래로 내려오는 빛을 만듭니다).
    기본값으로 ( 0, 1, 0 ) 을 설정합니다.

    -

    [property:Boolean DefaultMatrixAutoUpdate]

    +

    [property:Boolean DEFAULT_MATRIX_AUTO_UPDATE]

    새로 만들어진 Object3D의 [page:.matrixAutoUpdate matrixAutoUpdate] 기본 세팅입니다.

    +

    [property:Boolean DEFAULT_MATRIX_WORLD_AUTO_UPDATE]

    +

    + 새로 만들어진 Object3D의 [page:.matrixWorldAutoUpdate matrixWorldAutoUpdate] 기본 세팅입니다.
    +

    메서드

    @@ -260,6 +271,14 @@

    [method:Object3D getObjectByProperty]( [param:String name], [param:Any value 객체 자신부터 시작하여 객체와 객체 자식 항목을 검색하고 일치하는 값의 첫 번째 항목을 리턴합니다.

    +

    [method:Object3D getObjectsByProperty]( [param:String name], [param:Any value] )

    +

    + name -- 검색하고자하는 이름 프로퍼티.
    + value -- 프로퍼티의 값.

    + + 개체 자체부터 시작하여 개체와 해당 자식을 검색하고 일치하는 값의 모든 개체를 반환합니다. +

    +

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

    [page:Vector3 target] — 결과값은 이 Vector3에 복제됩니다.

    @@ -307,7 +326,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/core/Raycaster.html b/docs/api/ko/core/Raycaster.html index 539b4414f90124..578707eee354f8 100644 --- a/docs/api/ko/core/Raycaster.html +++ b/docs/api/ko/core/Raycaster.html @@ -64,7 +64,7 @@

    예제

    [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_raycast_texture Raycast to a Texture] + [example:webgl_raycaster_texture Raycast to a Texture]

    생성자

    diff --git a/docs/api/ko/extras/core/Path.html b/docs/api/ko/extras/core/Path.html index 6b91b2a3688626..a391e57cc3a980 100644 --- a/docs/api/ko/extras/core/Path.html +++ b/docs/api/ko/extras/core/Path.html @@ -51,7 +51,7 @@

    [name]( [param:Array points] )

    프로퍼티

    일반 프로퍼티는 기본 [page:CurvePath] 클래스를 참고하세요.

    -

    [property:Array currentPoint]

    +

    [property:Vector2 currentPoint]

    path의 현재 오프셋입니다. 새 [page:Curve]들은 여기서부터 시작될 것입니다.

    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..12d054bccc45b2 --- /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:AudioNode 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/audio/Audio.html b/docs/api/zh/audio/Audio.html index ffd41ea453afac..a126708032a184 100644 --- a/docs/api/zh/audio/Audio.html +++ b/docs/api/zh/audio/Audio.html @@ -89,7 +89,7 @@

    [property:Number offset]

    [property:Number duration]

    覆盖音频的持续时间。与[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start]()中的*duration*属性相同。默认为*undefined*,以用于播放整个buffer。

    -

    [property:String source]

    +

    [property:AudioNode source]

    使用 [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createBufferSource AudioContext.createBufferSource]()创建的[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode AudioBufferSourceNode].

    [property:String sourceType]

    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 1cc52e6d73a38d..5551016ce4fa88 100644 --- a/docs/api/zh/core/BufferGeometry.html +++ b/docs/api/zh/core/BufferGeometry.html @@ -130,7 +130,8 @@

    [property:Boolean isBufferGeometry]

    [property:Object morphAttributes]

    - 存储 [page:BufferAttribute] 的 Hashmap,存储了几何体 morph targets 的细节信息。 + 存储 [page:BufferAttribute] 的 Hashmap,存储了几何体 morph targets 的细节信息。
    + Note: Once the geometry has been rendered, the morph attribute data cannot be changed. You will have to call [page:.dispose](), and create a new instance of [name].

    [property:Boolean morphTargetsRelative]

    @@ -231,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/GLBufferAttribute.html b/docs/api/zh/core/GLBufferAttribute.html index 34f580caebbb56..ac1a4f02545502 100644 --- a/docs/api/zh/core/GLBufferAttribute.html +++ b/docs/api/zh/core/GLBufferAttribute.html @@ -23,9 +23,9 @@

    [name]

    Constructor

    [name]( [param:WebGLBuffer buffer], [param:GLenum type], [param:Integer itemSize], [param:Integer elementSize], [param:Integer count] )

    - *buffer* — Must be a WebGLBuffer. + *buffer* — Must be a [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer].
    - *type* — One of WebGL Data Types. + *type* — One of [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types WebGL Data Types].
    *itemSize* — The number of values of the array that should be associated with a particular vertex. For instance, if this @@ -48,7 +48,7 @@

    Properties

    [property:WebGLBuffer buffer]

    - The current WebGLBuffer instance. + The current [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer] instance.

    [property:Integer count]

    @@ -56,6 +56,11 @@

    [property:Integer count]

    The expected number of vertices in VBO.

    +

    [property:Boolean isGLBufferAttribute]

    +

    + Read-only. Always *true*. +

    +

    [property:Integer itemSize]

    How many values make up each item (vertex). @@ -69,9 +74,14 @@

    [property:Integer elementSize]

    See above (constructor) for a list of known type sizes.

    +

    [property:String name]

    +

    + 该 attribute 实例的别名,默认值为空字符串。 +

    +

    [property:GLenum type]

    - A WebGL Data Type + A [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types WebGL Data Type] describing the underlying VBO contents.

    @@ -79,11 +89,6 @@

    [property:GLenum type]

    using the *setType* method.

    -

    [property:Boolean isGLBufferAttribute]

    -

    - Read-only. Always *true*. -

    -

    Methods

    [method:this setBuffer]( buffer )

    diff --git a/docs/api/zh/core/Object3D.html b/docs/api/zh/core/Object3D.html index ba94517b2e4cca..3494bc2d5ca4af 100644 --- a/docs/api/zh/core/Object3D.html +++ b/docs/api/zh/core/Object3D.html @@ -72,7 +72,7 @@

    [property:Matrix4 matrix]

    [property:Boolean matrixAutoUpdate]

    - 当这个属性设置了之后,它将计算每一帧的位移、旋转(四元变换)和缩放矩阵,并重新计算matrixWorld属性。默认值是[page:Object3D.DefaultMatrixAutoUpdate] (true)。 + 当这个属性设置了之后,它将计算每一帧的位移、旋转(四元变换)和缩放矩阵,并重新计算matrixWorld属性。默认值是[page:Object3D.DEFAULT_MATRIX_AUTO_UPDATE] (true)。

    [property:Matrix4 matrixWorld]

    @@ -80,6 +80,13 @@

    [property:Matrix4 matrixWorld]

    物体的世界变换。若这个Object3D没有父级,则它将和local transform [page:.matrix](局部变换矩阵)相同。

    +

    [property:Boolean matrixWorldAutoUpdate]

    +

    + 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. + Default is [page:Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE] (true). +

    +

    [property:Boolean matrixWorldNeedsUpdate]

    当这个属性设置了之后,它将计算在那一帧中的matrixWorld,并将这个值重置为false。默认值为*false*。 @@ -156,7 +163,7 @@

    [property:Vector3 scale]

    [property:Vector3 up]

    这个属性由[page:.lookAt lookAt]方法所使用,例如,来决定结果的朝向。 - 默认值是[page:Object3D.DefaultUp],即( 0, 1, 0 )。 + 默认值是[page:Object3D.DEFAULT_UP],即( 0, 1, 0 )。

    [property:Object userData]

    @@ -180,22 +187,26 @@

    [property:Boolean visible]

    静态属性

    静态属性和方法由每个类所定义,并非由每个类的实例所定义。 - 也就是说,改变[page:Object3D.DefaultUp]或[page:Object3D.DefaultMatrixAutoUpdate]的值, + 也就是说,改变[page:Object3D.DEFAULT_UP]或[page:Object3D.DEFAULT_MATRIX_AUTO_UPDATE]的值, 将改变每个在此之后由Object3D类(或派生类)创建的实例中的[page:.up up]和[page:.matrixAutoUpdate matrixAutoUpdate]的值。(已经创建好的Object3D不会受到影响)。

    -

    [property:Vector3 DefaultUp]

    +

    [property:Vector3 DEFAULT_UP]

    默认的物体的[page:.up up]方向,同时也作为[page:DirectionalLight]、[page:HemisphereLight]和[page:Spotlight](自顶向下创建的灯光)的默认方向。 默认设为( 0, 1, 0 )。

    -

    [property:Boolean DefaultMatrixAutoUpdate]

    +

    [property:Boolean DEFAULT_MATRIX_AUTO_UPDATE]

    - [page:.matrixAutoUpdate matrixAutoUpdate]的默认设置,用于新创建的Object3D。
    + [page:.matrixAutoUpdate matrixAutoUpdate]的默认设置,用于新创建的Object3D。

    +

    [property:Boolean DEFAULT_MATRIX_WORLD_AUTO_UPDATE]

    +

    + [page:.matrixWorldAutoUpdate matrixWorldAutoUpdate]的默认设置,用于新创建的Object3D。
    +

    方法

    @@ -257,6 +268,13 @@

    [method:Object3D getObjectByProperty]( [param:String name], [param:Any value 从该对象开始,搜索一个对象及其子级,返回第一个给定的属性中包含有匹配的值的子对象。

    +

    [method:Object3D getObjectsByProperty]( [param:String name], [param:Any value] )

    +

    + name —— 将要用于查找的属性的名称。
    + value —— 给定的属性的值。

    + 从此对象开始,搜索一个对象及其子对象,返回包含给定属性的匹配值的所有子对象。 +

    +

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

    [page:Vector3 target] — 结果将被复制到这个Vector3中。

    @@ -298,7 +316,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/core/Raycaster.html b/docs/api/zh/core/Raycaster.html index fc08c61bda8c89..d2dbfa32e9be71 100644 --- a/docs/api/zh/core/Raycaster.html +++ b/docs/api/zh/core/Raycaster.html @@ -62,7 +62,7 @@

    例子

    [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_raycast_texture Raycast to a Texture] + [example:webgl_raycaster_texture Raycast to a Texture]

    diff --git a/docs/api/zh/extras/core/Path.html b/docs/api/zh/extras/core/Path.html index 23073dcf3ebf12..0098081c3b61a0 100644 --- a/docs/api/zh/extras/core/Path.html +++ b/docs/api/zh/extras/core/Path.html @@ -51,7 +51,7 @@

    [name]( [param:Array points] )

    属性

    共有属性请参见其基类[page:CurvePath]。

    -

    [property:Array currentPoint]

    +

    [property:Vector2 currentPoint]

    路径当前的偏移量,任何新被加入的[page:Curve]将会从这里开始。

    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/geometries/CircleGeometry.html b/docs/api/zh/geometries/CircleGeometry.html index d8dff2a805c7dc..31b303075fe44e 100644 --- a/docs/api/zh/geometries/CircleGeometry.html +++ b/docs/api/zh/geometries/CircleGeometry.html @@ -45,7 +45,7 @@

    构造器

    [name]([param:Float radius], [param:Integer segments], [param:Float thetaStart], [param:Float thetaLength])

    radius — 圆形的半径,默认值为1
    - segments — 分段(三角面)的数量,最小值为3,默认值为8。
    + segments — 分段(三角面)的数量,最小值为3,默认值为32。
    thetaStart — 第一个分段的起始角度,默认为0。(three o'clock position)
    thetaLength — 圆形扇区的中心角,通常被称为“θ”(西塔)。默认值是2*Pi,这使其成为一个完整的圆。

    diff --git a/docs/api/zh/geometries/ConeGeometry.html b/docs/api/zh/geometries/ConeGeometry.html index 9d69200672b870..66403fd58dd4ca 100644 --- a/docs/api/zh/geometries/ConeGeometry.html +++ b/docs/api/zh/geometries/ConeGeometry.html @@ -45,7 +45,7 @@

    [name]([param:Float radius], [param:Float height], [param:Integer radialSegm

    radius — 圆锥底部的半径,默认值为1。
    height — 圆锥的高度,默认值为1。
    - radialSegments — 圆锥侧面周围的分段数,默认为8。
    + radialSegments — 圆锥侧面周围的分段数,默认为32。
    heightSegments — 圆锥侧面沿着其高度的分段数,默认值为1。
    openEnded — 一个Boolean值,指明该圆锥的底面是开放的还是封顶的。默认值为false,即其底面默认是封顶的。
    thetaStart — 第一个分段的起始角度,默认为0。(three o'clock position)
    diff --git a/docs/api/zh/geometries/CylinderGeometry.html b/docs/api/zh/geometries/CylinderGeometry.html index c59c495235efe3..2640a394b2437a 100644 --- a/docs/api/zh/geometries/CylinderGeometry.html +++ b/docs/api/zh/geometries/CylinderGeometry.html @@ -46,7 +46,7 @@

    [name]([param:Float radiusTop], [param:Float radiusBottom], [param:Float hei radiusTop — 圆柱的顶部半径,默认值是1。
    radiusBottom — 圆柱的底部半径,默认值是1。
    height — 圆柱的高度,默认值是1。
    - radialSegments — 圆柱侧面周围的分段数,默认为8。
    + radialSegments — 圆柱侧面周围的分段数,默认为32。
    heightSegments — 圆柱侧面沿着其高度的分段数,默认值为1。
    openEnded — 一个Boolean值,指明该圆锥的底面是开放的还是封顶的。默认值为false,即其底面默认是封顶的。
    thetaStart — 第一个分段的起始角度,默认为0。(three o'clock position)
    diff --git a/docs/api/zh/geometries/LatheGeometry.html b/docs/api/zh/geometries/LatheGeometry.html index 6821fe5514c22e..6e3489a12e3aa4 100644 --- a/docs/api/zh/geometries/LatheGeometry.html +++ b/docs/api/zh/geometries/LatheGeometry.html @@ -48,7 +48,7 @@

    构造器

    [name]([param:Array points], [param:Integer segments], [param:Float phiStart], [param:Float phiLength])

    - points — 一个Vector2对象数组。每个点的X坐标必须大于0。 Default is an array with (0,0.5), (0.5,0) and (0,-0.5) which creates a simple diamond shape.
    + points — 一个Vector2对象数组。每个点的X坐标必须大于0。 Default is an array with (0,-0.5), (0.5,0) and (0,0.5) which creates a simple diamond shape.
    segments — 要生成的车削几何体圆周分段的数量,默认值是12。
    phiStart — 以弧度表示的起始角度,默认值为0。
    phiLength — 车削部分的弧度(0-2PI)范围,2PI将是一个完全闭合的、完整的车削几何体,小于2PI是部分的车削。默认值是2PI。 diff --git a/docs/api/zh/geometries/RingGeometry.html b/docs/api/zh/geometries/RingGeometry.html index f0e07a958ec61e..0c6c8d2a1e1593 100644 --- a/docs/api/zh/geometries/RingGeometry.html +++ b/docs/api/zh/geometries/RingGeometry.html @@ -45,7 +45,7 @@

    [name]([param:Float innerRadius], [param:Float outerRadius], [param:Integer

    innerRadius — 内部半径,默认值为0.5。
    outerRadius — 外部半径,默认值为1。
    - thetaSegments — 圆环的分段数。这个值越大,圆环就越圆。最小值为3,默认值为8。
    + thetaSegments — 圆环的分段数。这个值越大,圆环就越圆。最小值为3,默认值为32。
    phiSegments — 最小值为1,默认值为8。
    thetaStart — 起始角度,默认值为0。
    thetaLength — 圆心角,默认值为Math.PI * 2。 diff --git a/docs/api/zh/geometries/TorusGeometry.html b/docs/api/zh/geometries/TorusGeometry.html index d691b12fc28ec4..5de8d1c5dfc4d8 100644 --- a/docs/api/zh/geometries/TorusGeometry.html +++ b/docs/api/zh/geometries/TorusGeometry.html @@ -45,8 +45,8 @@

    [name]([param:Float radius], [param:Float tube], [param:Integer radialSegmen

    radius - 环面的半径,从环面的中心到管道横截面的中心。默认值是1。
    tube — 管道的半径,默认值为0.4。
    - radialSegments — 管道横截面的分段数,默认值为8。
    - tubularSegments — 管道的分段数,默认值为6。
    + radialSegments — 管道横截面的分段数,默认值为12。
    + tubularSegments — 管道的分段数,默认值为48。
    arc — 圆环的圆心角(单位是弧度),默认值为Math.PI * 2。

    diff --git a/docs/api/zh/helpers/CameraHelper.html b/docs/api/zh/helpers/CameraHelper.html index 3f061da309c4bb..d060340a7fac3d 100644 --- a/docs/api/zh/helpers/CameraHelper.html +++ b/docs/api/zh/helpers/CameraHelper.html @@ -12,8 +12,8 @@

    [name]

    - 用于模拟相机视锥体的辅助对象.
    - 它使用 [page:LineSegments] 来模拟相机视锥体. + 用于模拟相机视锥体的辅助对象.它使用 [page:LineSegments] 来模拟相机视锥体.

    + [name] must be a child of the scene.

    代码示例

    @@ -63,12 +63,18 @@

    [property:Object matrixAutoUpdate]

    - - -

    方法

    请到基类 [page:LineSegments] 页面查看公共方法.

    +

    [method:undefined dispose]()

    +

    + 用于辅助对象销毁内部创建的 [page:Line.material material] 和 [page:Line.geometry geometry] 。 +

    + +

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

    +

    + 定义辅助对象的颜色。 +

    [method:undefined update]()

    基于相机的投影矩阵更新辅助对象.

    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/AmbientLight.html b/docs/api/zh/lights/AmbientLight.html index 96cd16240edf59..8f954543fdc8b5 100644 --- a/docs/api/zh/lights/AmbientLight.html +++ b/docs/api/zh/lights/AmbientLight.html @@ -24,11 +24,6 @@

    代码示例

    scene.add( light );
    -

    例子

    -

    - [example:webgl_animation_skinning_blending animation / skinning / blending ] -

    -

    构造函数

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

    diff --git a/docs/api/zh/lights/DirectionalLight.html b/docs/api/zh/lights/DirectionalLight.html index 467baa8e9127ce..8ab0787b88a0bd 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] 下面的目标属性。

    @@ -77,7 +76,7 @@

    [property:Boolean isDirectionalLight]

    [property:Vector3 position]

    - 假如这个值设置等于 [page:Object3D.DefaultUp] (0, 1, 0),那么光线将会从上往下照射。 + 假如这个值设置等于 [page:Object3D.DEFAULT_UP] (0, 1, 0),那么光线将会从上往下照射。

    [property:DirectionalLightShadow shadow]

    diff --git a/docs/api/zh/lights/HemisphereLight.html b/docs/api/zh/lights/HemisphereLight.html index 65c37f9e9cf519..725daee2d8b6b1 100644 --- a/docs/api/zh/lights/HemisphereLight.html +++ b/docs/api/zh/lights/HemisphereLight.html @@ -75,7 +75,7 @@

    [property:Boolean isHemisphereLight]

    [property:Vector3 position]

    - 假如这个值设置等于 [page:Object3D.DefaultUp] (0, 1, 0),那么光线将会从上往下照射。 + 假如这个值设置等于 [page:Object3D.DEFAULT_UP] (0, 1, 0),那么光线将会从上往下照射。

    diff --git a/docs/api/zh/lights/PointLight.html b/docs/api/zh/lights/PointLight.html index 0c0254477715c6..21533147169e6e 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)。

    @@ -54,11 +52,17 @@

    属性(Properties)

    公共属性请查看基类[page:Light Light]。

    +

    [property:Boolean castShadow]

    +

    + If set to `true` light will cast dynamic shadows. *Warning*: This is expensive and + requires tweaking to get shadows looking right. See the [page:PointLightShadow] for details. + The default is `false`. +

    +

    [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..e67fc3e3308f62 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]

    @@ -101,7 +101,7 @@

    [property:Float penumbra]

    [property:Vector3 position]

    - 假如这个值设置等于 [page:Object3D.DefaultUp] (0, 1, 0),那么光线将会从上往下照射。 + 假如这个值设置等于 [page:Object3D.DEFAULT_UP] (0, 1, 0),那么光线将会从上往下照射。

    [property:Float power]

    @@ -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..7ad8b698bfd047 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*. @@ -107,10 +107,19 @@

    [property:Boolean depthWrite]

    在绘制2D叠加时,将多个事物分层在一起而不创建z-index时,禁用深度写入会很有用。

    -

    [property:Boolean isMaterial]

    -

    - 检查这个对象是否为材质[name]的只读标记. -

    +

    [property:Boolean forceSinglePass]

    +

    +Whether double-sided, transparent objects should be rendered with a single pass or not. Default is `false`.

    + +The engine renders double-sided, transparent objects with two draw calls (back faces first, then front faces) to mitigate transparency artifacts. +There are scenarios however where this approach produces no quality gains but still doubles draw calls e.g. when rendering flat vegetation like grass sprites. +In these cases, set the `forceSinglePass` flag to `false` to disable the two pass rendering to avoid performance issues. +

    + +

    [property:Boolean isMaterial]

    +

    + 检查这个对象是否为材质[name]的只读标记. +

    [property:Boolean stencilWrite]

    @@ -226,7 +235,7 @@

    [property:Integer shadowSide]

    [property:Integer side]

    定义将要渲染哪一面 - 正面,背面或两者。 - 默认为[page:Materials THREE.FrontSide]。其他选项有[page:Materials THREE.BackSide]和[page:Materials THREE.DoubleSide]。 + 默认为[page:Materials THREE.FrontSide]。其他选项有[page:Materials THREE.BackSide] 和 [page:Materials THREE.DoubleSide]。

    [property:Boolean toneMapped]

    @@ -258,6 +267,7 @@

    [property:Integer version]

    [property:Boolean vertexColors]

    是否使用顶点着色。默认值为false。 +The engine supports RGB and RGBA vertex colors depending on whether a three (RGB) or four (RGBA) component color buffer attribute is used.

    [property:Boolean visible]

    diff --git a/docs/api/zh/materials/MeshBasicMaterial.html b/docs/api/zh/materials/MeshBasicMaterial.html index f4f3ac3a68b815..5ae2247bb0a9fa 100644 --- a/docs/api/zh/materials/MeshBasicMaterial.html +++ b/docs/api/zh/materials/MeshBasicMaterial.html @@ -83,7 +83,10 @@

    [property:Float lightMapIntensity]

    烘焙光的强度。默认值为1。

    [property:Texture map]

    -

    颜色贴图。默认为null。

    +

    + 颜色贴图。可以选择包括一个alpha通道,通常与[page:Material.transparent .transparent] + 或[page:Material.alphaTest .alphaTest]。默认为null。 +

    [property:Float reflectivity]

    环境贴图对表面的影响程度; 见[page:.combine]。默认值为1,有效范围介于0(无反射)和1(完全反射)之间。 diff --git a/docs/api/zh/materials/MeshDepthMaterial.html b/docs/api/zh/materials/MeshDepthMaterial.html index 2b6ee684b0a484..38c2c5180a9c4c 100644 --- a/docs/api/zh/materials/MeshDepthMaterial.html +++ b/docs/api/zh/materials/MeshDepthMaterial.html @@ -68,7 +68,10 @@

    [property:Float displacementBias]

    [property:Texture map]

    -

    颜色贴图。默认为null。

    +

    + 颜色贴图。可以选择包括一个alpha通道,通常与[page:Material.transparent .transparent] + 或[page:Material.alphaTest .alphaTest]。默认为null。 +

    [property:Boolean wireframe]

    将几何体渲染为线框。默认值为*false*(即渲染为平滑着色)。

    diff --git a/docs/api/zh/materials/MeshDistanceMaterial.html b/docs/api/zh/materials/MeshDistanceMaterial.html index 866a41cacb5365..ae675804cce854 100644 --- a/docs/api/zh/materials/MeshDistanceMaterial.html +++ b/docs/api/zh/materials/MeshDistanceMaterial.html @@ -79,7 +79,10 @@

    [property:Float farDistance]

    [property:Texture map]

    -

    颜色贴图。默认为null。

    +

    + 颜色贴图。可以选择包括一个alpha通道,通常与[page:Material.transparent .transparent] + 或[page:Material.alphaTest .alphaTest]。默认为null。 +

    [property:Float nearDistance]

    diff --git a/docs/api/zh/materials/MeshLambertMaterial.html b/docs/api/zh/materials/MeshLambertMaterial.html index cf9070221c85a4..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*。

    @@ -102,7 +124,25 @@

    [property:Float lightMapIntensity]

    烘焙光的强度。默认值为1。

    [property:Texture map]

    -

    颜色贴图。默认为null。

    +

    + 颜色贴图。可以选择包括一个alpha通道,通常与[page:Material.transparent .transparent] + 或[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/MeshMatcapMaterial.html b/docs/api/zh/materials/MeshMatcapMaterial.html index fb8d1f246c6492..503bd22d5fb613 100644 --- a/docs/api/zh/materials/MeshMatcapMaterial.html +++ b/docs/api/zh/materials/MeshMatcapMaterial.html @@ -88,7 +88,11 @@

    [property:Boolean fog]

    材质是否受雾影响。默认为*true*。

    [property:Texture map]

    -

    颜色贴图。默认为null。纹理贴图颜色由漫反射颜色[page:.color]调节。

    +

    + 颜色贴图。可以选择包括一个alpha通道,通常与[page:Material.transparent .transparent] + 或[page:Material.alphaTest .alphaTest]。默认为null。 + 纹理贴图颜色由漫反射颜色[page:.color]调节。 +

    [property:Texture matcap]

    matcap贴图,默认为null。

    diff --git a/docs/api/zh/materials/MeshPhongMaterial.html b/docs/api/zh/materials/MeshPhongMaterial.html index 486de01ddf9216..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]上使用此材质时,性能通常会更高 ,但会牺牲一些图形精度。

    @@ -126,7 +124,11 @@

    [property:Float lightMapIntensity]

    烘焙光的强度。默认值为1。

    [property:Texture map]

    -

    颜色贴图。默认为null。纹理贴图颜色由漫反射颜色[page:.color]调节。

    +

    + 颜色贴图。可以选择包括一个alpha通道,通常与[page:Material.transparent .transparent] + 或[page:Material.alphaTest .alphaTest]。默认为null。 + 纹理贴图颜色由漫反射颜色[page:.color]调节。 +

    [property:Texture normalMap]

    用于创建法线贴图的纹理。RGB值会影响每个像素片段的曲面法线,并更改颜色照亮的方式。法线贴图不会改变曲面的实际形状,只会改变光照。 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 34c912161cfdd7..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]成员的这些文章: @@ -159,7 +154,11 @@

    [property:Float lightMapIntensity]

    烘焙光的强度。默认值为1。

    [property:Texture map]

    -

    颜色贴图。默认为null。纹理贴图颜色由漫反射颜色[page:.color]调节。

    +

    + 颜色贴图。可以选择包括一个alpha通道,通常与[page:Material.transparent .transparent] + 或[page:Material.alphaTest .alphaTest]。默认为null。 + 纹理贴图颜色由漫反射颜色[page:.color]调节。 +

    [property:Float metalness]

    材质与金属的相似度。非金属材质,如木材或石材,使用0.0,金属使用1.0,通常没有中间值。 diff --git a/docs/api/zh/materials/MeshToonMaterial.html b/docs/api/zh/materials/MeshToonMaterial.html index a80af1f11d355b..47ee650af449d3 100644 --- a/docs/api/zh/materials/MeshToonMaterial.html +++ b/docs/api/zh/materials/MeshToonMaterial.html @@ -134,7 +134,11 @@

    [property:Float lightMapIntensity]

    Intensity of the baked light. Default is 1.

    [property:Texture map]

    -

    The color map. Default is null. The texture map color is modulated by the diffuse [page:.color].

    +

    + The color map. May optionally include an alpha channel, typically combined with + [page:Material.transparent .transparent] or [page:Material.alphaTest .alphaTest]. Default is null. + The texture map color is modulated by the diffuse [page:.color]. +

    [property:Texture normalMap]

    diff --git a/docs/api/zh/materials/PointsMaterial.html b/docs/api/zh/materials/PointsMaterial.html index 052dbb6967ff7a..8693b118da28f1 100644 --- a/docs/api/zh/materials/PointsMaterial.html +++ b/docs/api/zh/materials/PointsMaterial.html @@ -82,7 +82,10 @@

    [property:Boolean fog]

    材质是否受雾影响。默认为*true*。

    [property:Texture map]

    -

    使用[page:Texture]中的数据设置点的颜色。

    +

    + 使用来自[page:Texture]的数据设置点的颜色。可以选择包括一个alpha通道,通常与 + [page:Material.transparent .transparent]或[page:Material.alphaTest .alphaTest]。 +

    [property:Number size]

    设置点的大小。默认值为1.0。
    diff --git a/docs/api/zh/materials/SpriteMaterial.html b/docs/api/zh/materials/SpriteMaterial.html index af8ae59aa28ec1..cbde13526ec74b 100644 --- a/docs/api/zh/materials/SpriteMaterial.html +++ b/docs/api/zh/materials/SpriteMaterial.html @@ -26,7 +26,7 @@

    代码示例

    例子

    - [example:webgl_raycast_sprite WebGL / raycast / sprite]
    + [example:webgl_raycaster_sprite WebGL / raycast / sprite]
    [example:webgl_sprites WebGL / sprites]
    [example:svg_sandbox SVG / sandbox]

    @@ -69,7 +69,10 @@

    [property:Boolean isSpriteMaterial]

    [property:Texture map]

    -

    颜色贴图。默认为null。

    +

    + 颜色贴图。可以选择包括一个alpha通道,通常与[page:Material.transparent .transparent] + 或[page:Material.alphaTest .alphaTest]。默认为null。 +

    [property:Radians rotation]

    sprite的转动,以弧度为单位。默认值为0。

    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/Matrix4.html b/docs/api/zh/math/Matrix4.html index cbc59fd36ee259..5761969003e7df 100644 --- a/docs/api/zh/math/Matrix4.html +++ b/docs/api/zh/math/Matrix4.html @@ -199,7 +199,7 @@

    [method:this makeRotationAxis]( [param:Vector3 axis], [param:Float theta] )< 设置当前矩阵为围绕轴 [page:Vector3 axis] 旋转量为 [page:Float theta]弧度。
    - 这是一种有点争议但在数学上可以替代通过四元数[page:Quaternions]旋转的办法。 请参阅此处[link:https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199 here]的讨论。 + 这是一种有点争议但在数学上可以替代通过四元数[page:Quaternion Quaternions]旋转的办法。 请参阅此处[link:https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199 here]的讨论。

    [method:this makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )

    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/InstancedMesh.html b/docs/api/zh/objects/InstancedMesh.html index 9b07956af15f3a..da3ccaf99fa3bc 100644 --- a/docs/api/zh/objects/InstancedMesh.html +++ b/docs/api/zh/objects/InstancedMesh.html @@ -20,7 +20,6 @@

    示例

    [example:webgl_instancing_dynamic WebGL / instancing / dynamic]
    - [example:webgl_instancing_modified WebGL / instancing / modified]
    [example:webgl_instancing_performance WebGL / instancing / performance]
    [example:webgl_instancing_scatter WebGL / instancing / scatter]
    [example:webgl_instancing_raycast WebGL / instancing / raycast] 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 45bf74f5b38f44..57f8e119da9ed6 100644 --- a/docs/api/zh/renderers/WebGLRenderer.html +++ b/docs/api/zh/renderers/WebGLRenderer.html @@ -28,7 +28,7 @@

    [name]( [param:Object parameters] )

    [page:WebGLRenderingContext context] - 可用于将渲染器附加到已有的渲染环境([link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext RenderingContext])中。默认值是null
    [page:String precision] - 着色器精度. 可以是 *"highp"*, *"mediump"* 或者 *"lowp"*. - 如果设备支持,默认为*"highp"* . 点击[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices here] 查看"应该避免的事"
    + 如果设备支持,默认为*"highp"* .
    [page:Boolean alpha] - controls the default clear alpha value. When set to *true*, the value is *0*. Otherwise it's *1*. Default is *false*.
    @@ -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 ee2b475c5478da..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; @@ -113,25 +116,25 @@

    [name]( [param:WebGLRenderer renderer], [param:String cacheKey], [param:Obje

    属性

    [property:String name]

    -

    The name of the respective shader program.

    +

    相应着色器程序的名称。

    [property:String id]

    -

    The identifier of this instance.

    +

    该实例的 id 标识。

    [property:String cacheKey]

    -

    This key enables the reusability of a single [name] for different materials.

    +

    启用这个 key 之后,能够实现单个 WebGLProgram 不同材料的可重用性。

    [property:Integer usedTimes]

    -

    How many times this instance is used for rendering render items.

    +

    此实例用于渲染渲染项的次数。

    [property:Object program]

    -

    The actual shader program.

    +

    实际的着色器程序。

    [property:WebGLShader vertexShader]

    -

    The vertex shader.

    +

    顶点着色器。

    [property:WebGLShader fragmentShader]

    -

    The fragment shader.

    +

    片元着色器。

    方法

    @@ -147,7 +150,7 @@

    [method:Object getAttributes]()

    [method:undefined destroy]()

    - Destroys an instance of [name]. + 销毁 WebGLProgram 的实例。

    源码

    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..b35f409bd9bf10 100644 --- a/docs/api/zh/textures/Source.html +++ b/docs/api/zh/textures/Source.html @@ -1,5 +1,5 @@ - + @@ -13,20 +13,25 @@

    [name]

    Represents the data source of a texture.

    -

    Constructor

    +

    构造函数

    [name]( [param:Any data] )

    [page:Any data] -- The data definition of a texture. Default is *null*.

    -

    Properties

    +

    属性

    [property:Any data]

    The actual data of a texture. The type of this property depends on the texture that uses this instance.

    +

    [property:Boolean isCubeTexture]

    +

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

    +

    [property:Boolean needsUpdate]

    Set this to *true* to trigger a data upload to the GPU next time the source is used. @@ -40,10 +45,10 @@

    [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

    +

    方法

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

    @@ -51,7 +56,7 @@

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

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

    -

    Source

    +

    源代码

    [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] 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/animations/MMDPhysics.html b/docs/examples/en/animations/MMDPhysics.html index 531808752655c5..148256b5c5c937 100644 --- a/docs/examples/en/animations/MMDPhysics.html +++ b/docs/examples/en/animations/MMDPhysics.html @@ -10,7 +10,7 @@

    [name]

    A Physics handler for `MMD` resources.

    - [name] calculates Physics for model loaded by [page:MMDLoader] with ammo.js (Bullet-based JavaScript Physics engine). + [name] calculates Physics for model loaded by [page:MMDLoader] with [link:https://github.com/kripken/ammo.js/ ammo.js] (Bullet-based JavaScript Physics engine).

    Code Example

    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/ColladaExporter.html b/docs/examples/en/exporters/ColladaExporter.html index 6f5c0039253cf9..6cc323cda2dc46 100644 --- a/docs/examples/en/exporters/ColladaExporter.html +++ b/docs/examples/en/exporters/ColladaExporter.html @@ -12,7 +12,7 @@

    [name]

    An exporter for `Collada`.

    - Collada is a + [link:https://www.khronos.org/collada/ Collada] is a file format for robust representation of scenes, materials, animations, and other 3D content in an xml format. This exporter only supports exporting geometry, materials, textures, and scene hierarchy.

    @@ -23,7 +23,7 @@

    Code Example

    // Instantiate an exporter const exporter = new ColladaExporter(); - // Parse the input and generate the ply output + // Parse the input and generate the collada ( .dae ) output const data = exporter.parse( scene, null, options ); downloadFile( data );
    diff --git a/docs/examples/en/exporters/DRACOExporter.html b/docs/examples/en/exporters/DRACOExporter.html new file mode 100644 index 00000000000000..60c15a554b1b83 --- /dev/null +++ b/docs/examples/en/exporters/DRACOExporter.html @@ -0,0 +1,74 @@ + + + + + + + + + +

    [name]

    + +

    + An exporter to compress geometry with the Draco library.

    + [link:https://google.github.io/draco/ Draco] is an open source library for compressing and + decompressing 3D meshes and point clouds. Compressed geometry can be significantly smaller, + at the cost of additional decoding time on the client device. +

    + +

    + Standalone Draco files have a `.drc` extension, and contain vertex positions, + normals, colors, and other attributes. Draco files *do not* contain materials, + textures, animation, or node hierarchies – to use these features, embed Draco geometry + inside of a glTF file. A normal glTF file can be converted to a Draco-compressed glTF file + using [link:https://github.com/AnalyticalGraphicsInc/gltf-pipeline glTF-Pipeline]. +

    + +

    Code Example

    + + + // Instantiate a exporter + const exporter = new DRACOExporter(); + + // Parse the input and generate the DRACO encoded output + const binaryData = exporter.parse( mesh, options ); + + +

    Examples

    + +

    + [example:misc_exporter_draco] +

    + +

    Constructor

    + +

    [name]()

    +

    + Creates a new [name]. +

    + +

    Methods

    + +

    [method:Int8Array parse]( [param:Mesh object] | [param:Points object], [param:Object options] )

    + +

    + [page:Mesh object] | [page:Points object] — Mesh or Points to encode.
    + [page:Options options] — Optional export options
    +

      +
    • decodeSpeed - int. Indicates how to tune the encoder regarding decode speed (0 gives better speed but worst quality). Default is 5
    • +
    • encodeSpeed - int. Indicates how to tune the encoder parameters (0 gives better speed but worst quality). Default is 5.
    • +
    • encoderMethod - int. Either sequential (very little compression) or Edgebreaker. Edgebreaker traverses the triangles of the mesh in a deterministic, spiral-like way which provides most of the benefits of this data format. Default is DRACOExporter.MESH_EDGEBREAKER_ENCODING.
    • +
    • quantization - Array of int. Indicates the presision of each type of data stored in the draco file in the order (POSITION, NORMAL, COLOR, TEX_COORD, GENERIC). Default is [ 16, 8, 8, 8, 8 ]
    • +
    • exportUvs - bool. Default is true.
    • +
    • exportNormals - bool. Default is true.
    • +
    • exportColor - bool. Default is false.
    • +
    +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/DRACOExporter.js examples/jsm/exporters/DRACOExporter.js] +

    + + diff --git a/docs/examples/en/exporters/EXRExporter.html b/docs/examples/en/exporters/EXRExporter.html index 95d1da3a9e3a22..cf8f90e2f83769 100644 --- a/docs/examples/en/exporters/EXRExporter.html +++ b/docs/examples/en/exporters/EXRExporter.html @@ -12,8 +12,8 @@

    [name]

    An exporter for `EXR`.

    - EXR ( Extended Dynamic Range) is an - open format specification + [link:https://www.openexr.com/ EXR] ( Extended Dynamic Range) is an + [link:https://github.com/AcademySoftwareFoundation/openexr open format specification] for professional-grade image storage format of the motion picture industry. The purpose of format is to accurately and efficiently represent high-dynamic-range scene-linear image data and associated metadata. The library is widely used in host application software where accuracy diff --git a/docs/examples/en/exporters/GLTFExporter.html b/docs/examples/en/exporters/GLTFExporter.html index 170fcd820bceec..f343e909c3c61b 100644 --- a/docs/examples/en/exporters/GLTFExporter.html +++ b/docs/examples/en/exporters/GLTFExporter.html @@ -12,8 +12,8 @@

    [name]

    An exporter for `glTF` 2.0.

    - glTF (GL Transmission Format) is an - open format specification + [link:https://www.khronos.org/gltf glTF] (GL Transmission Format) is an + [link:https://github.com/KhronosGroup/glTF/tree/master/specification/2.0 open format specification] for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf) or binary (.glb) format. External files store textures (.jpg, .png) and additional binary data (.bin). A glTF asset may deliver one or more scenes, including meshes, materials, @@ -29,7 +29,16 @@

    Extensions

    • KHR_lights_punctual
    • +
    • KHR_materials_clearcoat
    • +
    • KHR_materials_emissive_strength
    • +
    • KHR_materials_ior
    • +
    • KHR_materials_iridescence
    • +
    • KHR_materials_specular
    • +
    • KHR_materials_sheen
    • +
    • KHR_materials_transmission
    • KHR_materials_unlit
    • +
    • KHR_materials_volume
    • +
    • KHR_mesh_quantization
    • KHR_texture_transform
    @@ -117,11 +126,9 @@

    [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.
    • -
    • forceIndices - bool. Generate indices for non-index geometry and export with them. Default is false.
    • includeCustomExtensions - bool. Export custom glTF extensions defined on an object's `userData.gltfExtensions` property. Default is false.

    diff --git a/docs/examples/en/exporters/OBJExporter.html b/docs/examples/en/exporters/OBJExporter.html index 4f532c2aad871d..441466cbb7a818 100644 --- a/docs/examples/en/exporters/OBJExporter.html +++ b/docs/examples/en/exporters/OBJExporter.html @@ -10,7 +10,7 @@

    [name]

    - An exporter for the OBJ file format. + An exporter for the [link:https://en.wikipedia.org/wiki/Wavefront_.obj_file OBJ] file format.

    [name] is not able to export material data into MTL files so only geometry data are supported. diff --git a/docs/examples/en/exporters/PLYExporter.html b/docs/examples/en/exporters/PLYExporter.html index a7419001afd0ed..e06d08497b8895 100644 --- a/docs/examples/en/exporters/PLYExporter.html +++ b/docs/examples/en/exporters/PLYExporter.html @@ -12,7 +12,7 @@

    [name]

    An exporter for `PLY`.

    - PLY (Polygon or Stanford Triangle Format) is a + [link:https://en.wikipedia.org/wiki/PLY_(file_format) PLY] (Polygon or Stanford Triangle Format) is a file format for efficient delivery and loading of simple, static 3D content in a dense format. Both binary and ascii formats are supported. PLY can store vertex positions, colors, normals and uv coordinates. No textures or texture references are saved. diff --git a/docs/examples/en/exporters/STLExporter.html b/docs/examples/en/exporters/STLExporter.html new file mode 100644 index 00000000000000..0ac6ef38dc43fb --- /dev/null +++ b/docs/examples/en/exporters/STLExporter.html @@ -0,0 +1,64 @@ + + + + + + + + + +

    [name]

    + +

    + An exporter for the STL file format.

    + [link:https://en.wikipedia.org/wiki/STL_(file_format) STL] files describe only the surface geometry + of a three-dimensional object without any representation of color, texture or other common model attributes. + The STL format specifies both ASCII and binary representations, with binary being more compact. + STL files contain no scale information or indexes, and the units are arbitrary. +

    + +

    Code Example

    + + + // Instantiate an exporter + const exporter = new STLExporter(); + + // Configure export options + const options = { binary: true } + + // Parse the input and generate the STL encoded output + const result = exporter.parse( mesh, options ); + + +

    Examples

    + +

    + [example:misc_exporter_stl] +

    + +

    Constructor

    + +

    [name]()

    +

    + Creates a new [name]. +

    + +

    Methods

    + +

    [method:Object parse]( [param:Object3D scene], [param:Object options] )

    + +

    + [page:Object3D scene] — Scene, Mesh, or other Object3D based class containing Meshes to encode.
    + [page:Options options] — Optional export options
    +

      +
    • binary - bool. Return an ASCII encoded string or binary data buffer. Default is `false`.
    • +
    +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/STLExporter.js examples/jsm/exporters/STLExporter.js] +

    + + 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/3DMLoader.html b/docs/examples/en/loaders/3DMLoader.html index ba74521359aa94..ef38f63083c2b4 100644 --- a/docs/examples/en/loaders/3DMLoader.html +++ b/docs/examples/en/loaders/3DMLoader.html @@ -14,7 +14,7 @@

    [name]

    A loader for Rhinoceros 3d files and objects.

    Rhinoceros is a 3D modeler used to create, edit, analyze, document, render, animate, and translate NURBS curves, surfaces, breps, extrusions, point clouds, as well as polygon meshes and SubD objects. [link:https://github.com/mcneel/rhino3dm rhino3dm.js] is compiled to WebAssembly from the open source geometry library [link:https://github.com/mcneel/opennurbs openNURBS]. - The loader currently uses rhino3dm.js 0.15.0-beta. + The loader currently uses [link:https://www.npmjs.com/package/rhino3dm/v/0.15.0-beta rhino3dm.js 0.15.0-beta.]

    Supported Conversions

    @@ -180,7 +180,7 @@

    [method:undefined parse]( [param:ArrayBuffer buffer], [param:Function onLoad

    Parse a File3dm ArrayBuffer and call the `onLoad` function with the resulting Object3d. - See this example for further reference. + See [link:https://github.com/mcneel/rhino-developer-samples/tree/7/rhino3dm/js/SampleParse3dmObjects this example] for further reference.

    diff --git a/docs/examples/en/loaders/DRACOLoader.html b/docs/examples/en/loaders/DRACOLoader.html index 596521fe1edbd2..0b29dbeccccf96 100644 --- a/docs/examples/en/loaders/DRACOLoader.html +++ b/docs/examples/en/loaders/DRACOLoader.html @@ -38,7 +38,7 @@

    Code Example

    const loader = new DRACOLoader(); // Specify path to a folder containing WASM/JS decoding libraries. - loader.setDecoderPath( '/examples/js/libs/draco/' ); + loader.setDecoderPath( '/examples/jsm/libs/draco/' ); // Optional: Pre-fetch Draco WASM/JS module. loader.preload(); @@ -78,12 +78,7 @@

    Examples

    Browser compatibility

    -

    DRACOLoader relies on ES6 [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promises], - which are not supported in IE11. To use the loader in IE11, you must - [link:https://github.com/stefanpenner/es6-promise include a polyfill] - providing a Promise replacement. DRACOLoader will automatically use - either the JS or the WASM decoding library, based on browser - capabilities.

    +

    DRACOLoader will automatically use either the JS or the WASM decoding library, based on browser capabilities.



    diff --git a/docs/examples/en/loaders/GLTFLoader.html b/docs/examples/en/loaders/GLTFLoader.html index 99e67d46bd4ee0..3a1995d658cc74 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
  • @@ -83,7 +83,7 @@

    Code Example

    // Optional: Provide a DRACOLoader instance to decode compressed mesh data const dracoLoader = new DRACOLoader(); - dracoLoader.setDecoderPath( '/examples/js/libs/draco/' ); + dracoLoader.setDecoderPath( '/examples/jsm/libs/draco/' ); loader.setDRACOLoader( dracoLoader ); // Load a glTF resource @@ -123,13 +123,6 @@

    Examples

    [example:webgl_loader_gltf]

    -

    Browser compatibility

    - -

    GLTFLoader relies on ES6 [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promises], - which are not supported in IE11. To use the loader in IE11, you must - [link:https://github.com/stefanpenner/es6-promise include a polyfill] - providing a Promise replacement.

    -

    Textures

    Textures containing color information (.map, .emissiveMap, and .specularMap) always use sRGB colorspace in @@ -211,7 +204,7 @@

    [method:this setDRACOLoader]( [param:DRACOLoader dracoLoader] )

    [page:DRACOLoader dracoLoader] — Instance of THREE.DRACOLoader, to be used for decoding assets compressed with the KHR_draco_mesh_compression extension.

    - Refer to this [link:https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/draco#readme readme] for the details of Draco and its decoder. + Refer to this [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/libs/draco#readme readme] for the details of Draco and its decoder.

    [method:this setKTX2Loader]( [param:KTX2Loader ktx2Loader] )

    @@ -221,13 +214,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/KTX2Loader.html b/docs/examples/en/loaders/KTX2Loader.html index 03013238b4f4d3..4db6185de96970 100644 --- a/docs/examples/en/loaders/KTX2Loader.html +++ b/docs/examples/en/loaders/KTX2Loader.html @@ -23,7 +23,7 @@

    [name]

    This loader parses the KTX 2.0 container and transcodes to a supported GPU compressed texture format. The required WASM transcoder and JS wrapper are available from the - [link:https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/basis examples/js/libs/basis] + [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/libs/basis examples/jsm/libs/basis] directory.

    @@ -31,7 +31,7 @@

    Code Example

    var ktx2Loader = new THREE.KTX2Loader(); - ktx2Loader.setTranscoderPath( 'examples/js/libs/basis/' ); + ktx2Loader.setTranscoderPath( 'examples/jsm/libs/basis/' ); ktx2Loader.detectSupport( renderer ); ktx2Loader.load( 'diffuse.ktx2', function ( texture ) { @@ -57,8 +57,7 @@

    Examples

    Browser compatibility

    - See notes for [page:BasisTextureLoader]. This loader relies on ES6 Promises and Web Assembly, which are not - supported in IE11. + This loader relies on Web Assembly which is not supported in older browsers.


    @@ -82,7 +81,7 @@

    Methods

    [method:CompressedTexture load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    - [page:String url] — A string containing the path/URL of the `.basis` file.
    + [page:String url] — A string containing the path/URL of the `.ktx2` file.
    [page:Function onLoad] — A function to be called after the loading is successfully completed.
    [page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes. If the server does not set the Content-Length header; .[page:Integer total] will be 0.
    [page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.
    @@ -106,7 +105,7 @@

    [method:this setTranscoderPath]( [param:String path] )

    The WASM transcoder and JS wrapper are available from the - [link:https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/basis examples/js/libs/basis] + [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/libs/basis examples/jsm/libs/basis] directory.

    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/OBJLoader.html b/docs/examples/en/loaders/OBJLoader.html index 32fa8a46f5758d..626828a3b5ac6f 100644 --- a/docs/examples/en/loaders/OBJLoader.html +++ b/docs/examples/en/loaders/OBJLoader.html @@ -12,7 +12,7 @@

    [name]

    A loader for loading a `.obj` resource.
    - The OBJ file format is a simple data-format + The [link:https://en.wikipedia.org/wiki/Wavefront_.obj_file OBJ file format] is a simple data-format that represents 3D geometry in a human readable format as the position of each vertex, the UV position of each texture coordinate vertex, vertex normals, and the faces that make each polygon defined as a list of vertices, and texture vertices. 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/loaders/PDBLoader.html b/docs/examples/en/loaders/PDBLoader.html index 3b5770e2803c8d..4d38e2dd635ea6 100644 --- a/docs/examples/en/loaders/PDBLoader.html +++ b/docs/examples/en/loaders/PDBLoader.html @@ -12,7 +12,7 @@

    [name]

    A loader for loading a `.pdb` resource.
    - The Protein Data Bank file format is a textual file describing the three-dimensional structures of molecules. + The [link:http://en.wikipedia.org/wiki/Protein_Data_Bank_(file_format) Protein Data Bank] file format is a textual file describing the three-dimensional structures of molecules.

    Code Example

    diff --git a/docs/examples/en/loaders/PRWMLoader.html b/docs/examples/en/loaders/PRWMLoader.html index 691d35c5a9664d..dbdd39e19083a8 100644 --- a/docs/examples/en/loaders/PRWMLoader.html +++ b/docs/examples/en/loaders/PRWMLoader.html @@ -16,7 +16,7 @@

    [name]

    JavaScript and WebGL with a strong focus on fast parsing (from 1ms to 0.1ms in Chrome 59 on a MBP Late 2013). The parsing of PRWM file is especially fast when the endianness of the file is the same as the endianness of the client platform. More information - on this here. + on this [link:https://github.com/kchapelier/PRWM here].

    Code Example

    diff --git a/docs/examples/en/loaders/SVGLoader.html b/docs/examples/en/loaders/SVGLoader.html index 023209aada1e6b..53fddfdf936fa6 100644 --- a/docs/examples/en/loaders/SVGLoader.html +++ b/docs/examples/en/loaders/SVGLoader.html @@ -12,7 +12,7 @@

    [name]

    A loader for loading a `.svg` resource.
    - Scalable Vector Graphics is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation. + [link:https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Scalable Vector Graphics] is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation.

    Code Example

    diff --git a/docs/examples/en/loaders/TGALoader.html b/docs/examples/en/loaders/TGALoader.html index 304ea3410cdf02..6616f918d1f7d7 100644 --- a/docs/examples/en/loaders/TGALoader.html +++ b/docs/examples/en/loaders/TGALoader.html @@ -12,7 +12,7 @@

    [name]

    A loader for loading a `.tga` resource.
    - TGA is a raster graphics, image file format. + [link:https://en.wikipedia.org/wiki/Truevision_TGA TGA] is a raster graphics, image file format.

    Code Example

    diff --git a/docs/examples/en/math/convexhull/VertexList.html b/docs/examples/en/math/convexhull/VertexList.html index 375fd28b901736..0355a2e644533b 100644 --- a/docs/examples/en/math/convexhull/VertexList.html +++ b/docs/examples/en/math/convexhull/VertexList.html @@ -42,10 +42,10 @@

    [method:VertexNode first]()

    [method:VertexNode last]()

    Returns the tail reference.

    -

    [[method:this clear]()

    +

    [method:this clear]()

    Clears the linked list.

    -

    [[method:this insertBefore]( [param:Vertex target], [param:Vertex vertex] )

    +

    [method:this insertBefore]( [param:Vertex target], [param:Vertex vertex] )

    [page:Vertex target] - The target vertex. It's assumed that this vertex belongs to the linked list.
    [page:Vertex vertex] - The vertex to insert.

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

    [[method:this insertBefore]( [param:Vertex target], [param:Vertex vertex] )< Inserts a vertex before a target vertex.

    -

    [[method:this insertAfter]( [param:Vertex target], [param:Vertex vertex] )

    +

    [method:this insertAfter]( [param:Vertex target], [param:Vertex vertex] )

    [page:Vertex target] - The target vertex. It's assumed that this vertex belongs to the linked list.
    [page:Vertex vertex] - The vertex to insert.

    @@ -61,28 +61,28 @@

    [[method:this insertAfter]( [param:Vertex target], [param:Vertex vertex] )after a target vertex.

    -

    [[method:this append]( [param:Vertex vertex] )

    +

    [method:this append]( [param:Vertex vertex] )

    [page:Vertex vertex] - The vertex to append.

    Appends a vertex to the end of the linked list.

    -

    [[method:this appendChain]( [param:Vertex vertex] )

    +

    [method:this appendChain]( [param:Vertex vertex] )

    [page:Vertex vertex] - The head vertex of a chain of vertices.

    Appends a chain of vertices where the given vertex is the head.

    -

    [[method:this remove]( [param:Vertex vertex] )

    +

    [method:this remove]( [param:Vertex vertex] )

    [page:Vertex vertex] - The vertex to remove.

    Removes a vertex from the linked list.

    -

    [[method:this removeSubList]( [param:Vertex a], [param:Vertex b] )

    +

    [method:this removeSubList]( [param:Vertex a], [param:Vertex b] )

    [page:Vertex a] - The head of the sublist.
    [page:Vertex b] - The tail of the sublist.

    diff --git a/docs/examples/en/postprocessing/EffectComposer.html b/docs/examples/en/postprocessing/EffectComposer.html index 6ca3f20c27b0cf..db89c9451d3b6d 100644 --- a/docs/examples/en/postprocessing/EffectComposer.html +++ b/docs/examples/en/postprocessing/EffectComposer.html @@ -59,7 +59,7 @@

    [property:Array passes]

    An array representing the (ordered) chain of post-processing passes.

    -

    [property:WebGLRendererTarget readBuffer]

    +

    [property:WebGLRenderTarget readBuffer]

    A reference to the internal read buffer. Passes usually read the previous render result from this buffer.

    @@ -74,7 +74,7 @@

    [property:Boolean renderToScreen]

    Whether the final pass is rendered to the screen (default framebuffer) or not.

    -

    [property:WebGLRendererTarget writeBuffer]

    +

    [property:WebGLRenderTarget writeBuffer]

    A reference to the internal write buffer. Passes usually write their result into this buffer.

    @@ -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/CameraUtils.html b/docs/examples/en/utils/CameraUtils.html index 4f332810923f37..ebcbe0dae6e614 100644 --- a/docs/examples/en/utils/CameraUtils.html +++ b/docs/examples/en/utils/CameraUtils.html @@ -14,7 +14,7 @@

    [name]

    Methods

    -

    [method:undefined frameCorners]( [param:PerspectiveCamera camera] [param:Vector3 bottomLeftCorner], [param:Vector3 bottomRightCorner], [param:Vector3 topLeftCorner], [param:boolean estimateViewFrustum] )

    +

    [method:undefined frameCorners]( [param:PerspectiveCamera camera], [param:Vector3 bottomLeftCorner], [param:Vector3 bottomRightCorner], [param:Vector3 topLeftCorner], [param:boolean estimateViewFrustum] )

    Set a PerspectiveCamera's projectionMatrix and quaternion to exactly frame the corners of an arbitrary rectangle using [link:https://web.archive.org/web/20191110002841/http://csc.lsu.edu/~kooima/articles/genperspective/index.html Kooima's Generalized Perspective Projection formulation]. NOTE: This function ignores the standard parameters; do not call updateProjectionMatrix() after this! toJSON will also not capture the off-axis matrix generated by this function. diff --git a/docs/examples/en/utils/SceneUtils.html b/docs/examples/en/utils/SceneUtils.html index d8e8e34446bece..6a46df2bcf7878 100644 --- a/docs/examples/en/utils/SceneUtils.html +++ b/docs/examples/en/utils/SceneUtils.html @@ -40,6 +40,39 @@

    [method:Group createMultiMaterialObject]( [param:BufferGeometry geometry], [ This is mostly useful for objects that need both a material and a wireframe implementation.

    +

    [method:T reduceVertices]( [param:Object3D object], [param:function func], [param:T initialValue] )

    +

    + object -- The object to traverse (uses [page:Object3D.traverseVisible traverseVisible] internally).
    + func -- The binary function applied for the reduction. Must have the signature: (value: T, vertex: Vector3): T.
    + initialValue -- The value to initialize the reduction with. This is required + as it also sets the reduction type, which is not required to be Vector3. +

    +

    + Akin to Array.prototype.reduce(), but operating on the vertices of all the + visible descendant objects, in world space. Additionally, it can operate as a + transform-reduce, returning a different type T than the Vector3 input. This + can be useful for e.g. fitting a viewing frustum to the scene. +

    + +

    [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/animations/MMDPhysics.html b/docs/examples/zh/animations/MMDPhysics.html index ae818c9e4291d2..d4519c9d7b17d3 100644 --- a/docs/examples/zh/animations/MMDPhysics.html +++ b/docs/examples/zh/animations/MMDPhysics.html @@ -10,7 +10,7 @@

    [name]

    A Physics handler for MMD resources.

    - [name] calculates Physics for model loaded by [page:MMDLoader] with ammo.js (Bullet-based JavaScript Physics engine). + [name] calculates Physics for model loaded by [page:MMDLoader] with [link:https://github.com/kripken/ammo.js/ ammo.js] (Bullet-based JavaScript Physics engine).

    代码示例

    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/ColladaExporter.html b/docs/examples/zh/exporters/ColladaExporter.html index 1f586323b6b20b..1ca5da5a67a309 100644 --- a/docs/examples/zh/exporters/ColladaExporter.html +++ b/docs/examples/zh/exporters/ColladaExporter.html @@ -12,7 +12,7 @@

    [name]

    An exporter for *Collada*.

    - Collada is a + [link:https://www.khronos.org/collada/ Collada] is a file format for robust representation of scenes, materials, animations, and other 3D content in an xml format. This exporter only supports exporting geometry, materials, textures, and scene hierarchy.

    @@ -23,7 +23,7 @@

    代码示例

    // Instantiate an exporter const exporter = new ColladaExporter(); - // Parse the input and generate the ply output + // Parse the input and generate the collada ( .dae ) output const data = exporter.parse( scene, null, options ); downloadFile( data );
    diff --git a/docs/examples/zh/exporters/GLTFExporter.html b/docs/examples/zh/exporters/GLTFExporter.html index 8ac4cdfc25cfc8..930c44380ea038 100644 --- a/docs/examples/zh/exporters/GLTFExporter.html +++ b/docs/examples/zh/exporters/GLTFExporter.html @@ -10,10 +10,10 @@

    [name]

    - An exporter for *glTF* 2.0. + An exporter for `glTF` 2.0.

    - glTF (GL Transmission Format) is an - open format specification + [link:https://www.khronos.org/gltf glTF] (GL Transmission Format) is an + [link:https://github.com/KhronosGroup/glTF/tree/master/specification/2.0 open format specification] for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf) or binary (.glb) format. External files store textures (.jpg, .png) and additional binary data (.bin). A glTF asset may deliver one or more scenes, including meshes, materials, @@ -29,10 +29,18 @@

    Extensions

    • KHR_lights_punctual
    • +
    • KHR_materials_clearcoat
    • +
    • KHR_materials_emissive_strength
    • +
    • KHR_materials_ior
    • +
    • KHR_materials_iridescence
    • +
    • KHR_materials_specular
    • +
    • KHR_materials_sheen
    • +
    • KHR_materials_transmission
    • KHR_materials_unlit
    • +
    • KHR_materials_volume
    • +
    • KHR_mesh_quantization
    • KHR_texture_transform
    -

    The following glTF 2.0 extension is supported by an external user plugin

    @@ -73,7 +81,7 @@

    例子

    [example:misc_exporter_gltf]

    -

    Constructor

    +

    构造函数

    [name]()

    @@ -82,7 +90,7 @@

    [name]()

    Creates a new [name].

    -

    Methods

    +

    方法

    [method:undefined parse]( [param:Object3D input], [param:Function onCompleted], [param:Function onError], [param:Object options] )

    @@ -117,11 +125,9 @@

    [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.
    • -
    • forceIndices - bool. Generate indices for non-index geometry and export with them. Default is false.
    • includeCustomExtensions - bool. Export custom glTF extensions defined on an object's userData.gltfExtensions property. Default is false.

    diff --git a/docs/examples/zh/exporters/PLYExporter.html b/docs/examples/zh/exporters/PLYExporter.html index ccb451f98dce91..35a852e0aafecc 100644 --- a/docs/examples/zh/exporters/PLYExporter.html +++ b/docs/examples/zh/exporters/PLYExporter.html @@ -12,7 +12,7 @@

    [name]

    An exporter for *PLY*.

    - PLY (Polygon or Stanford Triangle Format) is a + [link:https://en.wikipedia.org/wiki/PLY_(file_format) PLY] (Polygon or Stanford Triangle Format) is a file format for efficient delivery and loading of simple, static 3D content in a dense format. Both binary and ascii formats are supported. PLY can store vertex positions, colors, normals and uv coordinates. No textures or texture references are saved. diff --git a/docs/examples/zh/loaders/DRACOLoader.html b/docs/examples/zh/loaders/DRACOLoader.html index 5377e9d39438cf..ac87d678dc862f 100644 --- a/docs/examples/zh/loaders/DRACOLoader.html +++ b/docs/examples/zh/loaders/DRACOLoader.html @@ -33,7 +33,7 @@

    代码示例

    const loader = new DRACOLoader(); // Specify path to a folder containing WASM/JS decoding libraries. - loader.setDecoderPath( '/examples/js/libs/draco/' ); + loader.setDecoderPath( '/examples/jsm/libs/draco/' ); // Optional: Pre-fetch Draco WASM/JS module. loader.preload(); @@ -73,12 +73,7 @@

    例子

    Browser compatibility

    -

    DRACOLoader relies on ES6 [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promises], - which are not supported in IE11. To use the loader in IE11, you must - [link:https://github.com/stefanpenner/es6-promise include a polyfill] - providing a Promise replacement. DRACOLoader will automatically use - either the JS or the WASM decoding library, based on browser - capabilities.

    +

    DRACOLoader will automatically use either the JS or the WASM decoding library, based on browser capabilities.



    diff --git a/docs/examples/zh/loaders/GLTFLoader.html b/docs/examples/zh/loaders/GLTFLoader.html index b564dce24120da..2506626783f9bd 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
  • @@ -82,7 +82,7 @@

    代码示例

    // Optional: Provide a DRACOLoader instance to decode compressed mesh data const dracoLoader = new DRACOLoader(); - dracoLoader.setDecoderPath( '/examples/js/libs/draco/' ); + dracoLoader.setDecoderPath( '/examples/jsm/libs/draco/' ); loader.setDRACOLoader( dracoLoader ); // Load a glTF resource @@ -122,12 +122,6 @@

    例子

    [example:webgl_loader_gltf]

    -

    浏览器兼容性

    - -

    GLTFLoader 依赖 ES6 [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promises], - 这一特性不支持IE11。若要在IE11中使用该加载器,你必须引入polyfill([link:https://github.com/stefanpenner/es6-promise include a polyfill]) - 来提供一个Promise的替代方案。

    -

    纹理

    纹理中包含的颜色信息(.map, .emissiveMap, 和 .specularMap)在glTF中总是使用sRGB颜色空间,而顶点颜色和材质属性(.color, .emissive, .specular) @@ -206,7 +200,7 @@

    [method:this setDRACOLoader]( [param:DRACOLoader dracoLoader] )

    [page:DRACOLoader dracoLoader] — THREE.DRACOLoader的实例,用于解码使用KHR_draco_mesh_compression扩展压缩过的文件。

    - 请参阅[link:https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/draco#readme readme]来了解Draco及其解码器的详细信息。 + 请参阅[link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/libs/draco#readme readme]来了解Draco及其解码器的详细信息。

    [method:undefined parse]( [param:ArrayBuffer data], [param:String path], [param:Function onLoad], [param:Function onError] )

    diff --git a/docs/examples/zh/loaders/OBJLoader.html b/docs/examples/zh/loaders/OBJLoader.html index 94c7111699e79f..8d42bc74ddc52a 100644 --- a/docs/examples/zh/loaders/OBJLoader.html +++ b/docs/examples/zh/loaders/OBJLoader.html @@ -12,7 +12,7 @@

    OBJ加载器([name])

    用于加载 .obj 资源的加载器。
    - OBJ 文件格式是一种简单的数据格式, + [link:https://en.wikipedia.org/wiki/Wavefront_.obj_file OBJ 文件格式]是一种简单的数据格式, 这种格式以人类可读的形式来表示3D几何体,即每个顶点的位置、每个纹理坐标顶点的UV位置、顶点法线、 将使每个多边形定义为顶点列表的面以及纹理顶点。

    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/loaders/PDBLoader.html b/docs/examples/zh/loaders/PDBLoader.html index 4ccd2565524414..a246fe35e7da9c 100644 --- a/docs/examples/zh/loaders/PDBLoader.html +++ b/docs/examples/zh/loaders/PDBLoader.html @@ -12,7 +12,7 @@

    [name]

    A loader for loading a .pdb resource.
    - The Protein Data Bank file format is a textual file describing the three-dimensional structures of molecules. + The [link:http://en.wikipedia.org/wiki/Protein_Data_Bank_(file_format) Protein Data Bank] file format is a textual file describing the three-dimensional structures of molecules.

    代码示例

    diff --git a/docs/examples/zh/loaders/PRWMLoader.html b/docs/examples/zh/loaders/PRWMLoader.html index 3058ccc706c371..bb3ca6f0a9b5fb 100644 --- a/docs/examples/zh/loaders/PRWMLoader.html +++ b/docs/examples/zh/loaders/PRWMLoader.html @@ -16,7 +16,7 @@

    [name]

    JavaScript and WebGL with a strong focus on fast parsing (from 1ms to 0.1ms in Chrome 59 on a MBP Late 2013). The parsing of PRWM file is especially fast when the endianness of the file is the same as the endianness of the client platform. More information - on this here. + on this [link:https://github.com/kchapelier/PRWM here].

    代码示例

    diff --git a/docs/examples/zh/loaders/SVGLoader.html b/docs/examples/zh/loaders/SVGLoader.html index a589fc2971d0d4..272b58a21d4a1e 100644 --- a/docs/examples/zh/loaders/SVGLoader.html +++ b/docs/examples/zh/loaders/SVGLoader.html @@ -12,7 +12,7 @@

    [name]

    A loader for loading a .svg resource.
    - Scalable Vector Graphics is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation. + [link:https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Scalable Vector Graphics] is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation.

    代码示例

    diff --git a/docs/examples/zh/loaders/TGALoader.html b/docs/examples/zh/loaders/TGALoader.html index 2c0761f12a5e75..38fbd7e67570e2 100644 --- a/docs/examples/zh/loaders/TGALoader.html +++ b/docs/examples/zh/loaders/TGALoader.html @@ -12,7 +12,7 @@

    [name]

    A loader for loading a .tga resource.
    - TGA is a raster graphics, image file format. + [link:https://en.wikipedia.org/wiki/Truevision_TGA TGA] is a raster graphics, image file format.

    代码示例

    diff --git a/docs/examples/zh/postprocessing/EffectComposer.html b/docs/examples/zh/postprocessing/EffectComposer.html index eb5689e1b3d00b..89a07bb649eb0e 100644 --- a/docs/examples/zh/postprocessing/EffectComposer.html +++ b/docs/examples/zh/postprocessing/EffectComposer.html @@ -58,7 +58,7 @@

    [property:Array passes]

    一个用于表示后期处理过程链(包含顺序)的数组。

    -

    [property:WebGLRendererTarget readBuffer]

    +

    [property:WebGLRenderTarget readBuffer]

    内部读缓冲区的引用。过程一般从该缓冲区读取先前的渲染结果。

    @@ -73,7 +73,7 @@

    [property:Boolean renderToScreen]

    最终过程是否被渲染到屏幕(默认帧缓冲区)。

    -

    [property:WebGLRendererTarget writeBuffer]

    +

    [property:WebGLRenderTarget writeBuffer]

    内部写缓冲区的引用。过程常将它们的渲染结果写入该缓冲区。

    @@ -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..82213ad02af8c0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -29,13 +29,17 @@

    three.js

    -
    +
    @@ -50,7 +54,7 @@

    three.js

    const panel = document.getElementById( 'panel' ); const content = document.getElementById( 'content' ); const expandButton = document.getElementById( 'expandButton' ); - const exitSearchButton = document.getElementById( 'exitSearchButton' ); + const clearSearchButton = document.getElementById( 'clearSearchButton' ); const panelScrim = document.getElementById( 'panelScrim' ); const filterInput = document.getElementById( 'filterInput' ); let iframe = document.querySelector( 'iframe' ); @@ -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 ) { @@ -161,11 +165,11 @@

    three.js

    }; - exitSearchButton.onclick = function () { + clearSearchButton.onclick = function () { filterInput.value = ''; updateFilter(); - panel.classList.remove( 'searchFocused' ); + filterInput.focus(); }; @@ -470,16 +474,32 @@

    three.js

    // First separate the member (if existing) from the page name, // then identify the subpage's URL and set it as URL fragment (re-adding the member) + const pageURL = getPageURL( pageName ); + + if ( pageURL ) { + + window.location.hash = pageURL; + + createNewIframe(); + + } + + } + + function getPageURL( pageName ) { + const splitPageName = decomposePageName( pageName, '.', '.' ); const currentProperties = pageProperties[ splitPageName[ 0 ] ]; if ( currentProperties ) { - window.location.hash = currentProperties.pageURL + splitPageName[ 1 ]; - - createNewIframe(); + return currentProperties.pageURL + splitPageName[ 1 ]; + + } else { + return null; + } } diff --git a/docs/list.json b/docs/list.json index 74df8c4b5f39ca..6e1612d655d642 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", @@ -391,10 +392,12 @@ "Exporters": { "ColladaExporter": "examples/en/exporters/ColladaExporter", + "DRACOExporter": "examples/en/exporters/DRACOExporter", "EXRExporter": "examples/en/exporters/EXRExporter", "GLTFExporter": "examples/en/exporters/GLTFExporter", "OBJExporter": "examples/en/exporters/OBJExporter", - "PLYExporter": "examples/en/exporters/PLYExporter" + "PLYExporter": "examples/en/exporters/PLYExporter", + "STLExporter": "examples/en/exporters/STLExporter" }, "Math": { @@ -814,6 +817,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 +831,7 @@ }, - "示例": { + "Addons": { "动画": { "CCDIKSolver": "examples/zh/animations/CCDIKSolver", @@ -1063,7 +1067,7 @@ }, - "예제": { + "Addons": { "컨트롤": { "DragControls": "examples/ko/controls/DragControls", @@ -1079,32 +1083,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/buildTools/Testing-with-NPM.html b/docs/manual/ar/buildTools/Testing-with-NPM.html index 02e270e0f4aace..b21cadbdb2cb67 100644 --- a/docs/manual/ar/buildTools/Testing-with-NPM.html +++ b/docs/manual/ar/buildTools/Testing-with-NPM.html @@ -123,7 +123,7 @@

    أضف three.js

    $ npm install three@0.84.0 --save - (0.84.0 في هذا المثال). - حفظ يجعل هذا تبعية لهذا المشروع ، بدلاً من dev تبعية. انظر المستندات هنا [link:https://docs.npmjs.com/cli/v8/configuring-npm/package-json here] لمزيد من المعلومات. + (0.84.0 في هذا المثال). - حفظ يجعل هذا تبعية لهذا المشروع ، بدلاً من dev تبعية. انظر المستندات [link:https://docs.npmjs.com/cli/v8/configuring-npm/package-json هنا] لمزيد من المعلومات. @@ -173,12 +173,12 @@

    أضف الرمز الخاص بك

  • اكتب اختبارًا للسلوك المتوقع لشفرتك ، وضعه تحت test/. هنا مثال من مشروع حقيقي - [link:https://github.com/air/encounter/blob/master/test/Physics-test.js Here]. + [link:https://github.com/air/encounter/blob/master/test/Physics-test.js هنا].
  • قم بتصدير الكود الوظيفي الخاص بك بطريقة يمكن للعقدة js رؤيتها ، لاستخدامها مع طلب. - شاهده هنا [link:https://github.com/air/encounter/blob/master/js/Physics.js here]. + شاهده [link:https://github.com/air/encounter/blob/master/js/Physics.js هنا].
  • 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-update-things.html b/docs/manual/ar/introduction/How-to-update-things.html index c4069205a6d719..552910bcd7738f 100644 --- a/docs/manual/ar/introduction/How-to-update-things.html +++ b/docs/manual/ar/introduction/How-to-update-things.html @@ -111,7 +111,7 @@

    BufferGeometry

    هنا مثال يعرض خطًا متحركًا يمكن تكييفه مع حالة الاستخدام الخاصة بك. - [link:https://jsfiddle.net/xvnctbL0/2/ Here is a fiddle] + [link:https://jsfiddle.net/t4m85pLr/1/ Here is a fiddle]

    أمثلة

    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 2dd408cbd70a8f..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> @@ -163,16 +176,11 @@

    خرائط الإستيراد

    Node.js

    - قد يكون استخدام three.js في Node.js أمرًا صعبًا ، وذلك لسببين: -

    - -

    - أولاً ، نظرًا لأن three.js مصممة للويب ، فإنها تعتمد على المتصفح وواجهات برمجة تطبيقات DOM التي لا تتواجد دائمًا في Node.js. يمكن حل بعض هذه المشكلات باستخدام (shims) مثل [link:https://github.com/stackgl/headless-gl headless-gl]، أو عن طريق استبدال مكونات مثل [page:TextureLoader] ببدائل مخصصة. قد تتشابك واجهات برمجة تطبيقات DOM الأخرى بعمق مع الكود الذي يستخدمها ، وسيكون من الصعب حلها. نرحب بطلبات السحب البسيطة والقابلة للصيانة لتحسين دعم Node.js ، لكننا نوصي بفتح مشكلة لمناقشة التحسينات التي أجريتها أولاً. + Because three.js is built for the web, it depends on browser and DOM APIs that don't always exist in Node.js. Some of these issues can be resolved by using shims like [link:https://github.com/stackgl/headless-gl headless-gl], or by replacing components like [page:TextureLoader] with custom alternatives. Other DOM APIs may be deeply intertwined with the code that uses them, and will be harder to work around. We welcome simple and maintainable pull requests to improve Node.js support, but recommend opening an issue to discuss your improvements first.

    - ثانيًا ، دعم Node.js لوحدات ES ... معقد. بدءًا من الإصدار 12 من Node.js ، يمكن استيراد المكتبة الأساسية كوحدة نمطية CommonJS ، مع require('three'). ومع ذلك ، فإن معظم أمثلة المكونات في examples/jsm لا يمكنها ذلك. - قد تحل الإصدارات المستقبلية من Node.js هذه المشكلة ، ولكن في هذه الأثناء قد تحتاج إلى استخدام حلول بديلة مثل [link:https://github.com/standard-things/esm esm] لتمكين تطبيق Node.js الخاص بك من التعرف على وحدات ES. + Make sure to add `{ "type": "module" }` to your `package.json` to enable ES6 modules in your node project.

    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..66bf7f1aa6da18 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 أو رسومات الكمبيوتر بشكل عام؟ تحقق من اختيار الأدبيات التي أوصى بها مجتمع المكتبة. @@ -130,7 +127,7 @@

    الروابط القديمة

    • - AlterQualia at WebGL Camp 3 + [link:https://www.youtube.com/watch?v=Dir4KO9RdhM AlterQualia at WebGL Camp 3]
    • [link:http://yomotsu.github.io/threejs-examples/ Yomotsus Examples] - مجموعة من الأمثلة باستخدام three.js r45. @@ -142,7 +139,7 @@

      الروابط القديمة

      [link:http://www.slideshare.net/yomotsu/webgl-and-threejs WebGL and Three.js] بواسطة [link:http://github.com/yomotsu Akihiro Oyamada] (slideshow).
    • - Trigger Rally بواسطة [link:https://github.com/jareiko jareiko] (video). + [link:https://www.youtube.com/watch?v=VdQnOaolrPA Trigger Rally] بواسطة [link:https://github.com/jareiko jareiko] (video).
    • [link:http://blackjk3.github.io/threefab/ ThreeFab] - محرر مشاهد ، تم دعم إصداراته حتى حوالي three.js r50. diff --git a/docs/manual/en/introduction/Color-management.html b/docs/manual/en/introduction/Color-management.html index b5ee0a3c36386c..10ad2e65612d07 100644 --- a/docs/manual/en/introduction/Color-management.html +++ b/docs/manual/en/introduction/Color-management.html @@ -84,7 +84,7 @@

      What is a color space?

      of achromatic values (like white or grey) depend on human perception, which in turn depends heavily on the context of the observer. A color space specifies its "white point" to balance these needs. The white point defined by the sRGB color space is - D65. + [link:https://en.wikipedia.org/wiki/Illuminant_D65 D65].
    • Transfer functions: After choosing the color gamut and a color model, we still need to @@ -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-update-things.html b/docs/manual/en/introduction/How-to-update-things.html index 5fc1e39b5f35a3..aa805c2ac9e5c8 100644 --- a/docs/manual/en/introduction/How-to-update-things.html +++ b/docs/manual/en/introduction/How-to-update-things.html @@ -121,7 +121,7 @@

    BufferGeometry

    - [link:https://jsfiddle.net/xvnctbL0/2/ Here is a fiddle] showing an animated line which you can adapt to your use case. + [link:https://jsfiddle.net/t4m85pLr/1/ Here is a fiddle] showing an animated line which you can adapt to your use case.

    Examples

    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 41281749aba2cc..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 require 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

    @@ -140,15 +148,11 @@

    CommonJS imports

    Node.js

    - Using three.js in [link:https://eloquentjavascript.net/20_node.html Node.js] can be difficult, for two reasons: -

    - -

    - First, because three.js is built for the web, it depends on browser and DOM APIs that don't always exist in Node.js. Some of these issues can be resolved by using shims like [link:https://github.com/stackgl/headless-gl headless-gl], or by replacing components like [page:TextureLoader] with custom alternatives. Other DOM APIs may be deeply intertwined with the code that uses them, and will be harder to work around. We welcome simple and maintainable pull requests to improve Node.js support, but recommend opening an issue to discuss your improvements first. + Because three.js is built for the web, it depends on browser and DOM APIs that don't always exist in Node.js. Some of these issues can be resolved by using shims like [link:https://github.com/stackgl/headless-gl headless-gl], or by replacing components like [page:TextureLoader] with custom alternatives. Other DOM APIs may be deeply intertwined with the code that uses them, and will be harder to work around. We welcome simple and maintainable pull requests to improve Node.js support, but recommend opening an issue to discuss your improvements first.

    - Second, Node.js support for ES modules is ... complicated. As of Node.js v12, the core library can be imported as a CommonJS module, with require('three'). However, most example components in examples/jsm cannot. Future versions of Node.js may resolve this, but in the meantime you may need to use workarounds like [link:https://github.com/standard-things/esm esm] to enable your Node.js application to recognize ES modules. + Make sure to add `{ "type": "module" }` to your `package.json` to enable ES6 modules in your node project.

    diff --git a/docs/manual/en/introduction/Libraries-and-Plugins.html b/docs/manual/en/introduction/Libraries-and-Plugins.html index 6e07b9e3d966af..1e4979bf7e2ba6 100644 --- a/docs/manual/en/introduction/Libraries-and-Plugins.html +++ b/docs/manual/en/introduction/Libraries-and-Plugins.html @@ -77,6 +77,7 @@

    3D Text and Layout

    Particle Systems

      +
    • [link:https://github.com/Alchemist0823/three.quarks three.quarks]
    • [link:https://github.com/creativelifeform/three-nebula three-nebula]
    @@ -101,6 +102,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..c9821035198948 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? @@ -143,7 +140,7 @@

    Old Links

    • - AlterQualia at WebGL Camp 3 + [link:https://www.youtube.com/watch?v=Dir4KO9RdhM AlterQualia at WebGL Camp 3]
    • [link:http://yomotsu.github.io/threejs-examples/ Yomotsus Examples] - a collection of examples using three.js r45. @@ -155,7 +152,7 @@

      Old Links

      [link:http://www.slideshare.net/yomotsu/webgl-and-threejs WebGL and Three.js] by [link:http://github.com/yomotsu Akihiro Oyamada] (slideshow).
    • - Trigger Rally by [link:https://github.com/jareiko jareiko] (video). + [link:https://www.youtube.com/watch?v=VdQnOaolrPA Trigger Rally] by [link:https://github.com/jareiko jareiko] (video).
    • [link:http://blackjk3.github.io/threefab/ ThreeFab] - scene editor, maintained up until around three.js r50. 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..e6c63391e6d42f --- /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 + [link:https://en.wikipedia.org/wiki/Illuminant_D65 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..3da25d2a07e789 --- /dev/null +++ b/docs/manual/fr/introduction/Libraries-and-Plugins.html @@ -0,0 +1,109 @@ + + + + + + + + + +

      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/Alchemist0823/three.quarks three.quarks]
      • +
      • [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..b4c80ed9ab243c --- /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. +

      + +
        +
      • + [link:https://www.youtube.com/watch?v=Dir4KO9RdhM 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). +
      • +
      • + [link:https://www.youtube.com/watch?v=VdQnOaolrPA 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..4d74091c0e4162 --- /dev/null +++ b/docs/manual/it/introduction/Libraries-and-Plugins.html @@ -0,0 +1,109 @@ + + + + + + + + + +

      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/Alchemist0823/three.quarks three.quarks]
      • +
      • [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..a565fdb2c55636 --- /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. +

      + +
        +
      • + [link:https://www.youtube.com/watch?v=Dir4KO9RdhM 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). +
      • +
      • + [link:https://www.youtube.com/watch?v=VdQnOaolrPA 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-update-things.html b/docs/manual/ja/introduction/How-to-update-things.html index 451932bd2c4460..70010bc4a45caf 100644 --- a/docs/manual/ja/introduction/How-to-update-things.html +++ b/docs/manual/ja/introduction/How-to-update-things.html @@ -115,7 +115,7 @@

      BufferGeometry

      - [link:http://jsfiddle.net/w67tzfhx/ Here is a fiddle] showing an animated line which you can adapt to your use case. ここ([link:http://jsfiddle.net/w67tzfhx/ link])では、あなたのユースケースに合わせることができるアニメーションを表示しています。 + ここ([link:https://jsfiddle.net/t4m85pLr/1/ link])では、あなたのユースケースに合わせることができるアニメーションを表示しています。

      Examples

      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 870aacd984bc3b..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> - + const scene = new THREE.Scene(); -

      - すべての機能が build/three.module.js モジュールからアクセスできるわけではありません。コントロール、ローダー、エフェクトの前処理など、ライブラリの他の一般的な部分は、[link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] サブフォルダからインポートする必要があります。詳細については、以下のExamplesを参照してください。 -

      +</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を使用したりしないでください。

      互換性について

      @@ -144,17 +157,11 @@

      Import maps

      Node.js

      - 以下の2つの理由からnode.jsでthree.jsを使用するのは難しくなりがちです。 -

      - -

      - まず、three.jsはWeb用に作られているので、Node.jsには必ずしも存在しないブラウザやDOM APIに依存します。これらの問題のいくつかは、[link:https://github.com/stackgl/headless-gl headless-gl] のような補正ツールを使用したり、[page:TextureLoader] のようなコンポーネントをカスタムの代替品で置き換えることで解決できます。他の DOM APIは、それらを使用するコードと深く絡み合っている可能性があり、回避するのが難しくなります。Node.js - のサポートを改善するためのシンプルで保守性の高いプルリクエストを歓迎しますが、まず問題を開いて改善点を議論することをお勧めします。 + Because three.js is built for the web, it depends on browser and DOM APIs that don't always exist in Node.js. Some of these issues can be resolved by using shims like [link:https://github.com/stackgl/headless-gl headless-gl], or by replacing components like [page:TextureLoader] with custom alternatives. Other DOM APIs may be deeply intertwined with the code that uses them, and will be harder to work around. We welcome simple and maintainable pull requests to improve Node.js support, but recommend opening an issue to discuss your improvements first.

      - 第二に、Node.jsによるESモジュールのサポートは...複雑です。Node.js v12の時点では、three.jsのコアライブラリはrequire('three')でCommonJSモジュールとしてインポートすることができます。しかし、examples/jsmにあるほとんどのサンプルコンポーネントはインポートできません。Node.jsの将来のバージョンで解決されるかもしれませんが、それまでの間は、[link:https://github.com/standard-things/esm - esm]のような回避策を使用して、Node.jsアプリケーションがESモジュールを認識できるようにする必要があるでしょう。 + Make sure to add `{ "type": "module" }` to your `package.json` to enable ES6 modules in your node project.

      diff --git a/docs/manual/ja/introduction/Libraries-and-Plugins.html b/docs/manual/ja/introduction/Libraries-and-Plugins.html index 7b70eec1979dee..d7e8ec71dab7a4 100644 --- a/docs/manual/ja/introduction/Libraries-and-Plugins.html +++ b/docs/manual/ja/introduction/Libraries-and-Plugins.html @@ -71,6 +71,7 @@

      3D Text and Layout

      Particle Systems

        +
      • [link:https://github.com/Alchemist0823/three.quarks three.quarks]
      • [link:https://github.com/creativelifeform/three-nebula three-nebula]
      @@ -94,6 +95,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..70fe60806b8742 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? @@ -138,7 +135,7 @@

    古いリンク(Old Links)

    • - AlterQualia at WebGL Camp 3 + [link:https://www.youtube.com/watch?v=Dir4KO9RdhM AlterQualia at WebGL Camp 3]
    • [link:http://yomotsu.github.io/threejs-examples/ Yomotsus Examples] - a collection of examples using three.js r45. @@ -150,7 +147,7 @@

      古いリンク(Old Links)

      [link:http://www.slideshare.net/yomotsu/webgl-and-threejs WebGL and Three.js] by [link:http://github.com/yomotsu Akihiro Oyamada] (slideshow).
    • - Trigger Rally by [link:https://github.com/jareiko jareiko] (video). + [link:https://www.youtube.com/watch?v=VdQnOaolrPA Trigger Rally] by [link:https://github.com/jareiko jareiko] (video).
    • [link:http://blackjk3.github.io/threefab/ ThreeFab] - scene editor, maintained up until around three.js r50. 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-update-things.html b/docs/manual/ko/introduction/How-to-update-things.html index f099036f739df8..2c170a88f4b978 100644 --- a/docs/manual/ko/introduction/How-to-update-things.html +++ b/docs/manual/ko/introduction/How-to-update-things.html @@ -117,7 +117,7 @@

      BufferGeometry

      - [link:https://jsfiddle.net/xvnctbL0/2/ Here is a fiddle] showing an animated line which you can adapt to your use case. + [link:https://jsfiddle.net/t4m85pLr/1/ Here is a fiddle] showing an animated line which you can adapt to your use case.

      Examples

      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 b18f6c17a7b6a8..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> - + const scene = new THREE.Scene(); -

      - 모든 속성들이 build/three.module.js 모듈을 통해 접근하는 것은 아닙니다. 다른 자주 쓰이는 라이브러리들, controls, loaders, post-processing effects 같은 것들은 - [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm examples/jsm] 의 하위폴더에서 불러와야 합니다. 더 자세한 내용을 알아보려면, 아래 예제를 참고하세요. -

      +</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 라이브러리 자체가 아닌 다른 버전의 예제를 사용하지 마세요. @@ -164,19 +176,11 @@

      maps 불러오기

      Node.js

      - three.js 를 [link:https://eloquentjavascript.net/20_node.html Node.js]에서 사용하는기에는 어려움이 있는데, 두 가지 이유가 있습니다. -

      - -

      - 첫 번째로, three.js는 웹을 목적으로 만들어졌기때문에, Node.js에서 항상 활용 가능하다고 보증할 수 없는 브라우저와 DOM API에 의존하고 있는 까닭입니다. - 이러한 문제들은 shims를 통해 [link:https://github.com/stackgl/headless-gl headless-gl]처럼 해결하거나, [page:TextureLoader] 같은 컴포넌트를 커스터마이징 해서 해결 가능합니다. 다른 DOM API는 관련된 코드가 더 복잡하게 연관되어 있어, 수정하기 더 까다롭습니다. - Node.js 지원을 향상시키기 위한 더 간단하고, 유지보수 가능한 pull 요청은 언제든지 환영이지만, 본인의 작업을 위한 issue 생성을 더 권장합니다. + Because three.js is built for the web, it depends on browser and DOM APIs that don't always exist in Node.js. Some of these issues can be resolved by using shims like [link:https://github.com/stackgl/headless-gl headless-gl], or by replacing components like [page:TextureLoader] with custom alternatives. Other DOM APIs may be deeply intertwined with the code that uses them, and will be harder to work around. We welcome simple and maintainable pull requests to improve Node.js support, but recommend opening an issue to discuss your improvements first.

      - 둘째로, Node.js의 ES 모듈 지원은 ... 다소 복잡합니다. Node.js v12에서, 코어 라이브러리는 CommonJS 모듈로, require('three')와 같이 사용 가능합니다. - 하지만, 대부분의 examples/jsm 안의 예제 컴포넌트들은 불가능합니다. Node.js 향후 버전에서는 이게 해결될 수도 있겠지만, 그 전까지는 - [link:https://github.com/standard-things/esm esm]처럼 사용해 Node.js 앱이 ES 모듈을 인식할 수 있도록 해줘야 합니다. + Make sure to add `{ "type": "module" }` to your `package.json` to enable ES6 modules in your node project.

      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..7396971def8781 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? @@ -139,7 +136,7 @@

      이전 링크들

      • - AlterQualia at WebGL Camp 3 + [link:https://www.youtube.com/watch?v=Dir4KO9RdhM AlterQualia at WebGL Camp 3]
      • [link:http://yomotsu.github.io/threejs-examples/ Yomotsus Examples] - a collection of examples using three.js r45. @@ -151,7 +148,7 @@

        이전 링크들

        [link:http://www.slideshare.net/yomotsu/webgl-and-threejs WebGL and Three.js] by [link:http://github.com/yomotsu Akihiro Oyamada] (slideshow).
      • - Trigger Rally by [link:https://github.com/jareiko jareiko] (video). + [link:https://www.youtube.com/watch?v=VdQnOaolrPA Trigger Rally] by [link:https://github.com/jareiko jareiko] (video).
      • [link:http://blackjk3.github.io/threefab/ ThreeFab] - scene editor, maintained up until around three.js r50. 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..209cc3e8a0ab51 --- /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 é + [link:https://en.wikipedia.org/wiki/Illuminant_D65 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..1b98593dba5007 --- /dev/null +++ b/docs/manual/pt-br/introduction/Libraries-and-Plugins.html @@ -0,0 +1,109 @@ + + + + + + + + + +

        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/Alchemist0823/three.quarks three.quarks]
        • +
        • [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..65ed3faedcf45f --- /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. +

        + +
          +
        • + [link:https://www.youtube.com/watch?v=Dir4KO9RdhM 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). +
        • +
        • + [link:https://www.youtube.com/watch?v=VdQnOaolrPA 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..21d1085d3b3887 --- /dev/null +++ b/docs/manual/ru/introduction/Libraries-and-Plugins.html @@ -0,0 +1,109 @@ + + + + + + + + + +

        Библиотеки и плагины ([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/Alchemist0823/three.quarks three.quarks]
        • +
        • [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..199a688ce9d6b3 --- /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

        +
          +
        • + [link:https://threejs.org/manual/#ru/fundamentals Основы 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 . +

        + +
          +
        • + [link:https://www.youtube.com/watch?v=Dir4KO9RdhM 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] (слайд-шоу). +
        • +
        • + [link:https://www.youtube.com/watch?v=VdQnOaolrPA 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/buildTools/Testing-with-NPM.html b/docs/manual/zh/buildTools/Testing-with-NPM.html index 6771e52fb0c613..e5572b33b68b6b 100644 --- a/docs/manual/zh/buildTools/Testing-with-NPM.html +++ b/docs/manual/zh/buildTools/Testing-with-NPM.html @@ -130,7 +130,7 @@

        添加three.js

        $ npm install three@0.84.0 --save (例子中用的是0.84.0)。 --save 指令将此加入项目的dependency而不是dev dependency。 - 更多信息请参阅这份文档。 + 更多信息请参阅[link:https://docs.npmjs.com/cli/v8/configuring-npm/package-json 这份文档]。
    • @@ -180,12 +180,12 @@

      加入你自己的代码

      1. 为你的代码写一段测试程序来检验期望结果,并把它放在 test/ 目录下。 - 这里有一个实际项目的例子。 + [link:https://github.com/air/encounter/blob/master/test/Physics-test.js 这里]有一个实际项目的例子。
      2. 将你的代码以nodejs承认的方式导出,即可以通过require的方式引用。 - 参考这份代码。 + 参考[link:https://github.com/air/encounter/blob/master/js/Physics.js 这份代码]。
      3. diff --git a/docs/manual/zh/introduction/Animation-system.html b/docs/manual/zh/introduction/Animation-system.html index 8412811f53cd96..ff040a28b7b51e 100644 --- a/docs/manual/zh/introduction/Animation-system.html +++ b/docs/manual/zh/introduction/Animation-system.html @@ -19,7 +19,7 @@

        概述

        相同或不同物体的动画也可以同步发生。

        为了在一个同构系统中实现所有这一切, - three.js的动画系统在2015年彻底改变(注意过时的信息!), + three.js的动画系统[link:https://github.com/mrdoob/three.js/issues/6881 在2015年彻底改变](注意过时的信息!), 它现在有一个与Unity/虚幻4引擎类似的架构。此页面简要阐述了这个系统中的主要组件以及它们如何协同工作。

        diff --git a/docs/manual/zh/introduction/FAQ.html b/docs/manual/zh/introduction/FAQ.html index 0e1cce15afd295..64f5ae228f9c97 100644 --- a/docs/manual/zh/introduction/FAQ.html +++ b/docs/manual/zh/introduction/FAQ.html @@ -50,9 +50,9 @@

        为什么我的物体的一部分是不可见的?

        material.side = THREE.DoubleSide

        -

        Why does three.js sometimes return strange results for invalid inputs?

        +

        为什么有时候无效的输入会让three.js返回奇怪的结果?

        - For performance reasons, three.js doesn't validate inputs in most cases. It's your app's responsibility to make sure that all inputs are valid. + 出于性能考虑,大多数情况下 three.js 不验证输入。确保所有输入均有效是你的应用的责任。

        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-update-things.html b/docs/manual/zh/introduction/How-to-update-things.html index a083a8b42b5712..96265cc7c8721f 100644 --- a/docs/manual/zh/introduction/How-to-update-things.html +++ b/docs/manual/zh/introduction/How-to-update-things.html @@ -107,7 +107,7 @@

        BufferGeometry

        - 这个fiddle展示了一个你可以参考的运动的line。 + [link:https://jsfiddle.net/t4m85pLr/1/ 这个fiddle]展示了一个你可以参考的运动的line。

        例子

        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 5235e0641d5bf7..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> @@ -141,15 +154,11 @@

        Import maps

        Node.js

        - 在 [link:https://eloquentjavascript.net/20_node.html Node.js] 下使用 three.js 较为困难,原因有2条: -

        - -

        - 首先, three.js 是为 web 而构建的,其依赖于浏览器,以及并不总是存在于 Node.js 中的 DOM API。其中的一些问题可使用类似 [link:https://github.com/stackgl/headless-gl headless-gl] 的 shim ,或使用定制的替代品来替换掉一些组件(例如 [page:TextureLoader] )来进行解决。其他的 DOM API 或许和使用它们的代码紧密相连在一起,并且很难解决。我们欢迎简单且可维护的 pull request,以改善对 Node.js 的支持。但建议您首先提出一个 issue 来讨论您的改进。 + Because three.js is built for the web, it depends on browser and DOM APIs that don't always exist in Node.js. Some of these issues can be resolved by using shims like [link:https://github.com/stackgl/headless-gl headless-gl], or by replacing components like [page:TextureLoader] with custom alternatives. Other DOM APIs may be deeply intertwined with the code that uses them, and will be harder to work around. We welcome simple and maintainable pull requests to improve Node.js support, but recommend opening an issue to discuss your improvements first.

        - 第二,Node.js 对于 ES module 的支持可以说……很复杂。在 Node.js v12 中, three.js 的核心库可使用 require('three') 来作为 CommonJS module 进行导入。然而,大多数在 examples/jsm 中的示例组件并不能够这样。未来版本的 Node.js 或许可以解决这个问题,但同时你可能需要一些类似 [link:https://github.com/standard-things/esm esm] 的解决方案,来使得你的 Node.js 应用程序识别 ES module。 + Make sure to add `{ "type": "module" }` to your `package.json` to enable ES6 modules in your node project.

        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..9dc1839b57a2aa 100644 --- a/docs/manual/zh/introduction/Useful-links.html +++ b/docs/manual/zh/introduction/Useful-links.html @@ -59,9 +59,6 @@

        更加广泛、高级的文章与教程

      4. [Link:https://aerotwist.com/tutorials/ Aerotwist] tutorials by [link:https://github.com/paullewis/ Paul Lewis]. -
      5. -
      6. - [link:http://learningthreejs.com/ Learning Three.js] – a blog with articles dedicated to teaching three.js
      7. [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? @@ -117,6 +114,9 @@

        工具

      8. [link:http://idflood.github.io/ThreeNodes.js/ ThreeNodes.js].
      9. +
      10. + [link:https://github.com/Alchemist0823/three.quarks three.quarks] - 针对 three.js 高速粒子特效系统 +
      11. [link:https://marketplace.visualstudio.com/items?itemName=slevesque.shader vscode shader] - Syntax highlighter for shader language.
        @@ -141,7 +141,7 @@

        较旧的链接

        • - AlterQualia at WebGL Camp 3 + [link:https://www.youtube.com/watch?v=Dir4KO9RdhM AlterQualia at WebGL Camp 3]
        • [link:http://yomotsu.github.io/threejs-examples/ Yomotsus Examples] - a collection of examples using three.js r45. @@ -153,7 +153,7 @@

          较旧的链接

          [link:http://www.slideshare.net/yomotsu/webgl-and-threejs WebGL and Three.js] by [link:http://github.com/yomotsu Akihiro Oyamada] (slideshow).
        • - Trigger Rally by [link:https://github.com/jareiko jareiko] (video). + [link:https://www.youtube.com/watch?v=VdQnOaolrPA Trigger Rally] by [link:https://github.com/jareiko jareiko] (video).
        • [link:http://blackjk3.github.io/threefab/ ThreeFab] - scene editor, maintained up until around three.js r50. diff --git a/docs/page.css b/docs/page.css index beda0201862734..6e305348320db6 100644 --- a/docs/page.css +++ b/docs/page.css @@ -76,6 +76,7 @@ body.rtl table { } body.rtl code { direction: ltr !important; + text-align: initial; } a { diff --git a/docs/page.js b/docs/page.js index 8415d74d6f79b0..92b7e407670573 100644 --- a/docs/page.js +++ b/docs/page.js @@ -61,26 +61,54 @@ function onDocumentLoad() { text = text.replace( /\[name\]/gi, name ); text = text.replace( /\[path\]/gi, path ); text = text.replace( /\[page:([\w\.]+)\]/gi, '[page:$1 $1]' ); // [page:name] to [page:name title] - text = text.replace( /\[page:\.([\w\.]+) ([\w\.\s]+)\]/gi, '[page:' + name + '.$1 $2]' ); // [page:.member title] to [page:name.member title] - text = text.replace( /\[page:([\w\.]+) ([\w\.\s]+)\]/gi, '$2' ); // [page:name title] + text = text.replace( /\[page:\.([\w\.]+) ([\w\.\s]+)\]/gi, `[page:${name}.$1 $2]` ); // [page:.member title] to [page:name.member title] + text = text.replace( /\[page:([\w\.]+) ([\w\.\s]+)\]/gi, '$2' ); // [page:name title] // text = text.replace( /\[member:.([\w]+) ([\w\.\s]+)\]/gi, "$2" ); text = text.replace( /\[(member|property|method|param):([\w]+)\]/gi, '[$1:$2 $2]' ); // [member:name] to [member:name title] - text = text.replace( /\[(?:member|property|method):([\w]+) ([\w\.\s]+)\]\s*(\(.*\))?/gi, ' .$2 $3 : $1' ); - text = text.replace( /\[param:([\w\.]+) ([\w\.\s]+)\]/gi, '$2 : $1' ); // [param:name title] + text = text.replace( /\[(?:member|property|method):([\w]+) ([\w\.\s]+)\]\s*(\(.*\))?/gi, ` .$2 $3 : $1` ); + text = text.replace( /\[param:([\w\.]+) ([\w\.\s]+)\]/gi, '$2 : $1' ); // [param:name title] text = text.replace( /\[link:([\w\:\/\.\-\_\(\)\?\#\=\!\~]+)\]/gi, '$1' ); // [link:url] - text = text.replace( /\[link:([\w\:\/\.\-\_\(\)\?\#\=\!\~]+) ([\w\:\/\.\-\_\'\s]+)\]/gi, '$2' ); // [link:url title] + text = text.replace( /\[link:([\w:/.\-_()?#=!~]+) ([\w\p{L}:/.\-_'\s]+)\]/giu, '$2' ); // [link:url title] text = text.replace( /\*([\w\d\"\-\(][\w\d\ \/\+\-\(\)\=\,\."]*[\w\d\"\)]|\w)\*/gi, '$1' ); // *text* text = text.replace( /\`(.*?)\`/gi, '$1' ); // `code` text = text.replace( /\[example:([\w\_]+)\]/gi, '[example:$1 $1]' ); // [example:name] to [example:name title] text = text.replace( /\[example:([\w\_]+) ([\w\:\/\.\-\_ \s]+)\]/gi, '$2' ); // [example:name title] - text = text.replace( /(null|this|Boolean|Object|Array|Number|String|Integer|Float|TypedArray|ArrayBuffer)<\/a>/gi, '$1' ); // remove links to primitive types + text = text.replace( /(undefined|null|this|Boolean|Object|Array|Number|String|Integer|Float|TypedArray|ArrayBuffer)<\/a>/gi, '$1' ); // remove links to primitive types document.body.innerHTML = text; + if ( window.parent.getPageURL ) { + + const links = document.querySelectorAll( '.links' ); + for ( let i = 0; i < links.length; i ++ ) { + + const pageURL = window.parent.getPageURL( links[ i ].dataset.fragment ); + if ( pageURL ) { + + links[ i ].href = './index.html#' + pageURL; + + } + + } + + } + + document.body.addEventListener( 'click', event => { + + const element = event.target; + if ( element.classList.contains( 'links' ) && event.button === 0 && ! event.shiftKey && ! event.ctrlKey && ! event.metaKey && ! event.altKey ) { + + window.parent.setUrlFragment( element.dataset.fragment ); + event.preventDefault(); + + } + + } ); + // handle code snippets formatting const elements = document.getElementsByTagName( 'code' ); @@ -137,7 +165,7 @@ function onDocumentLoad() { } - prettyPrint(); + prettyPrint(); // eslint-disable-line no-undef }; 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 fb4718027cf474..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; @@ -146,9 +147,9 @@ bones = []; // "root bone" - let rootBone = new Bone(); - rootBone.name = "root"; - rootBone.position.y = -sizing.halfHeight; + const rootBone = new Bone(); + rootBone.name = 'root'; + rootBone.position.y = - sizing.halfHeight; bones.push( rootBone ); // @@ -158,7 +159,7 @@ // "bone0" let prevBone = new Bone(); prevBone.position.y = 0; - rootBone.add(prevBone); + rootBone.add( prevBone ); bones.push( prevBone ); // "bone1", "bone2", "bone3" @@ -175,7 +176,7 @@ // "target" const targetBone = new Bone(); - targetBone.name = "target"; + targetBone.name = 'target'; targetBone.position.y = sizing.height + sizing.segmentHeight; // relative to parent: rootBone rootBone.add( targetBone ); bones.push( targetBone ); @@ -214,16 +215,18 @@ gui.add( mesh, 'pose' ).name( 'mesh.pose()' ); mesh.skeleton.bones - .filter( ( bone ) => bone.name === "target" ) - .forEach( function (bone) { + .filter( ( bone ) => bone.name === 'target' ) + .forEach( function ( bone ) { + const folder = gui.addFolder( bone.name ); const delta = 20; 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/Editor.js b/editor/js/Editor.js index f65243b71fbd25..daec6e13b49f64 100644 --- a/editor/js/Editor.js +++ b/editor/js/Editor.js @@ -5,6 +5,9 @@ import { Loader } from './Loader.js'; import { History as _History } from './History.js'; import { Strings } from './Strings.js'; import { Storage as _Storage } from './Storage.js'; +import { Selector } from './Viewport.Selector.js'; + +THREE.ColorManagement.legacyMode = false; var _DEFAULT_CAMERA = new THREE.PerspectiveCamera( 50, 1, 0.01, 1000 ); _DEFAULT_CAMERA.name = 'Camera'; @@ -13,7 +16,7 @@ _DEFAULT_CAMERA.lookAt( new THREE.Vector3() ); function Editor() { - var Signal = signals.Signal; + const Signal = signals.Signal; // eslint-disable-line no-undef this.signals = { @@ -84,7 +87,9 @@ function Editor() { refreshSidebarObject3D: new Signal(), historyChanged: new Signal(), - viewportCameraChanged: new Signal() + viewportCameraChanged: new Signal(), + + intersectionsDetected: new Signal(), }; @@ -92,6 +97,7 @@ function Editor() { this.history = new _History( this ); this.storage = new _Storage(); this.strings = new Strings( this.config ); + this.selector = new Selector( this ); this.loader = new Loader( this ); @@ -132,6 +138,8 @@ Editor.prototype = { this.scene.background = scene.background; this.scene.environment = scene.environment; this.scene.fog = scene.fog; + this.scene.backgroundBlurriness = scene.backgroundBlurriness; + this.scene.backgroundIntensity = scene.backgroundIntensity; this.scene.userData = JSON.parse( JSON.stringify( scene.userData ) ); @@ -535,20 +543,7 @@ Editor.prototype = { select: function ( object ) { - if ( this.selected === object ) return; - - var uuid = null; - - if ( object !== null ) { - - uuid = object.uuid; - - } - - this.selected = object; - - this.config.setKey( 'selected', uuid ); - this.signals.objectSelected.dispatch( object ); + this.selector.select( object ); }, @@ -583,7 +578,7 @@ Editor.prototype = { deselect: function () { - this.select( null ); + this.selector.deselect(); }, diff --git a/editor/js/EditorControls.js b/editor/js/EditorControls.js index 0bab01cc6376b0..e0520182df742c 100644 --- a/editor/js/EditorControls.js +++ b/editor/js/EditorControls.js @@ -1,354 +1,357 @@ import * as THREE from 'three'; -function EditorControls( object, domElement ) { +class EditorControls extends THREE.EventDispatcher { - // API + constructor( object, domElement ) { - this.enabled = true; - this.center = new THREE.Vector3(); - this.panSpeed = 0.002; - this.zoomSpeed = 0.1; - this.rotationSpeed = 0.005; + super(); - // internals + // API - var scope = this; - var vector = new THREE.Vector3(); - var delta = new THREE.Vector3(); - var box = new THREE.Box3(); + this.enabled = true; + this.center = new THREE.Vector3(); + this.panSpeed = 0.002; + this.zoomSpeed = 0.1; + this.rotationSpeed = 0.005; - var STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2 }; - var state = STATE.NONE; + // internals - var center = this.center; - var normalMatrix = new THREE.Matrix3(); - var pointer = new THREE.Vector2(); - var pointerOld = new THREE.Vector2(); - var spherical = new THREE.Spherical(); - var sphere = new THREE.Sphere(); + var scope = this; + var vector = new THREE.Vector3(); + var delta = new THREE.Vector3(); + var box = new THREE.Box3(); - // events + var STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2 }; + var state = STATE.NONE; - var changeEvent = { type: 'change' }; + var center = this.center; + var normalMatrix = new THREE.Matrix3(); + var pointer = new THREE.Vector2(); + var pointerOld = new THREE.Vector2(); + var spherical = new THREE.Spherical(); + var sphere = new THREE.Sphere(); - this.focus = function ( target ) { + // events - var distance; + var changeEvent = { type: 'change' }; - box.setFromObject( target ); + this.focus = function ( target ) { - if ( box.isEmpty() === false ) { + var distance; - box.getCenter( center ); - distance = box.getBoundingSphere( sphere ).radius; + box.setFromObject( target ); - } else { + if ( box.isEmpty() === false ) { - // Focusing on an Group, AmbientLight, etc + box.getCenter( center ); + distance = box.getBoundingSphere( sphere ).radius; - center.setFromMatrixPosition( target.matrixWorld ); - distance = 0.1; + } else { - } + // Focusing on an Group, AmbientLight, etc - delta.set( 0, 0, 1 ); - delta.applyQuaternion( object.quaternion ); - delta.multiplyScalar( distance * 4 ); + center.setFromMatrixPosition( target.matrixWorld ); + distance = 0.1; - object.position.copy( center ).add( delta ); + } - scope.dispatchEvent( changeEvent ); + delta.set( 0, 0, 1 ); + delta.applyQuaternion( object.quaternion ); + delta.multiplyScalar( distance * 4 ); - }; + object.position.copy( center ).add( delta ); - this.pan = function ( delta ) { + scope.dispatchEvent( changeEvent ); - var distance = object.position.distanceTo( center ); + }; - delta.multiplyScalar( distance * scope.panSpeed ); - delta.applyMatrix3( normalMatrix.getNormalMatrix( object.matrix ) ); + this.pan = function ( delta ) { - object.position.add( delta ); - center.add( delta ); + var distance = object.position.distanceTo( center ); - scope.dispatchEvent( changeEvent ); + delta.multiplyScalar( distance * scope.panSpeed ); + delta.applyMatrix3( normalMatrix.getNormalMatrix( object.matrix ) ); - }; + object.position.add( delta ); + center.add( delta ); - this.zoom = function ( delta ) { + scope.dispatchEvent( changeEvent ); - var distance = object.position.distanceTo( center ); + }; - delta.multiplyScalar( distance * scope.zoomSpeed ); + this.zoom = function ( delta ) { - if ( delta.length() > distance ) return; + var distance = object.position.distanceTo( center ); - delta.applyMatrix3( normalMatrix.getNormalMatrix( object.matrix ) ); + delta.multiplyScalar( distance * scope.zoomSpeed ); - object.position.add( delta ); + if ( delta.length() > distance ) return; - scope.dispatchEvent( changeEvent ); + delta.applyMatrix3( normalMatrix.getNormalMatrix( object.matrix ) ); - }; + object.position.add( delta ); - this.rotate = function ( delta ) { + scope.dispatchEvent( changeEvent ); - vector.copy( object.position ).sub( center ); + }; - spherical.setFromVector3( vector ); + this.rotate = function ( delta ) { - spherical.theta += delta.x * scope.rotationSpeed; - spherical.phi += delta.y * scope.rotationSpeed; + vector.copy( object.position ).sub( center ); - spherical.makeSafe(); + spherical.setFromVector3( vector ); - vector.setFromSpherical( spherical ); + spherical.theta += delta.x * scope.rotationSpeed; + spherical.phi += delta.y * scope.rotationSpeed; - object.position.copy( center ).add( vector ); + spherical.makeSafe(); - object.lookAt( center ); + vector.setFromSpherical( spherical ); - scope.dispatchEvent( changeEvent ); + object.position.copy( center ).add( vector ); - }; + object.lookAt( center ); - // + scope.dispatchEvent( changeEvent ); - function onPointerDown( event ) { + }; - if ( scope.enabled === false ) return; + // - switch ( event.pointerType ) { + function onPointerDown( event ) { - case 'mouse': - case 'pen': - onMouseDown( event ); - break; + if ( scope.enabled === false ) return; - // TODO touch + switch ( event.pointerType ) { - } + case 'mouse': + case 'pen': + onMouseDown( event ); + break; - domElement.ownerDocument.addEventListener( 'pointermove', onPointerMove ); - domElement.ownerDocument.addEventListener( 'pointerup', onPointerUp ); + // TODO touch - } + } + + domElement.ownerDocument.addEventListener( 'pointermove', onPointerMove ); + domElement.ownerDocument.addEventListener( 'pointerup', onPointerUp ); + + } - function onPointerMove( event ) { + function onPointerMove( event ) { - if ( scope.enabled === false ) return; + if ( scope.enabled === false ) return; - switch ( event.pointerType ) { + switch ( event.pointerType ) { - case 'mouse': - case 'pen': - onMouseMove( event ); - break; + case 'mouse': + case 'pen': + onMouseMove( event ); + break; - // TODO touch + // TODO touch + + } } - } + function onPointerUp( event ) { - function onPointerUp( event ) { + switch ( event.pointerType ) { - switch ( event.pointerType ) { + case 'mouse': + case 'pen': + onMouseUp(); + break; - case 'mouse': - case 'pen': - onMouseUp(); - break; + // TODO touch - // TODO touch + } + + domElement.ownerDocument.removeEventListener( 'pointermove', onPointerMove ); + domElement.ownerDocument.removeEventListener( 'pointerup', onPointerUp ); } - domElement.ownerDocument.removeEventListener( 'pointermove', onPointerMove ); - domElement.ownerDocument.removeEventListener( 'pointerup', onPointerUp ); + // mouse - } + function onMouseDown( event ) { - // mouse + if ( event.button === 0 ) { - function onMouseDown( event ) { + state = STATE.ROTATE; - if ( event.button === 0 ) { + } else if ( event.button === 1 ) { - state = STATE.ROTATE; + state = STATE.ZOOM; - } else if ( event.button === 1 ) { + } else if ( event.button === 2 ) { - state = STATE.ZOOM; + state = STATE.PAN; - } else if ( event.button === 2 ) { + } - state = STATE.PAN; + pointerOld.set( event.clientX, event.clientY ); } - pointerOld.set( event.clientX, event.clientY ); + function onMouseMove( event ) { - } + pointer.set( event.clientX, event.clientY ); - function onMouseMove( event ) { + var movementX = pointer.x - pointerOld.x; + var movementY = pointer.y - pointerOld.y; - pointer.set( event.clientX, event.clientY ); + if ( state === STATE.ROTATE ) { - var movementX = pointer.x - pointerOld.x; - var movementY = pointer.y - pointerOld.y; + scope.rotate( delta.set( - movementX, - movementY, 0 ) ); - if ( state === STATE.ROTATE ) { + } else if ( state === STATE.ZOOM ) { - scope.rotate( delta.set( - movementX, - movementY, 0 ) ); + scope.zoom( delta.set( 0, 0, movementY ) ); - } else if ( state === STATE.ZOOM ) { + } else if ( state === STATE.PAN ) { - scope.zoom( delta.set( 0, 0, movementY ) ); + scope.pan( delta.set( - movementX, movementY, 0 ) ); - } else if ( state === STATE.PAN ) { + } - scope.pan( delta.set( - movementX, movementY, 0 ) ); + pointerOld.set( event.clientX, event.clientY ); } - pointerOld.set( event.clientX, event.clientY ); + function onMouseUp() { - } + state = STATE.NONE; - function onMouseUp() { + } - state = STATE.NONE; + function onMouseWheel( event ) { - } + if ( scope.enabled === false ) return; - function onMouseWheel( event ) { + event.preventDefault(); - if ( scope.enabled === false ) return; + // Normalize deltaY due to https://bugzilla.mozilla.org/show_bug.cgi?id=1392460 + scope.zoom( delta.set( 0, 0, event.deltaY > 0 ? 1 : - 1 ) ); - event.preventDefault(); + } - // Normalize deltaY due to https://bugzilla.mozilla.org/show_bug.cgi?id=1392460 - scope.zoom( delta.set( 0, 0, event.deltaY > 0 ? 1 : - 1 ) ); + function contextmenu( event ) { - } + event.preventDefault(); - function contextmenu( event ) { + } - event.preventDefault(); + this.dispose = function () { - } + domElement.removeEventListener( 'contextmenu', contextmenu ); + domElement.removeEventListener( 'dblclick', onMouseUp ); + domElement.removeEventListener( 'wheel', onMouseWheel ); - this.dispose = function () { + domElement.removeEventListener( 'pointerdown', onPointerDown ); - domElement.removeEventListener( 'contextmenu', contextmenu ); - domElement.removeEventListener( 'dblclick', onMouseUp ); - domElement.removeEventListener( 'wheel', onMouseWheel ); + domElement.removeEventListener( 'touchstart', touchStart ); + domElement.removeEventListener( 'touchmove', touchMove ); - domElement.removeEventListener( 'pointerdown', onPointerDown ); + }; - domElement.removeEventListener( 'touchstart', touchStart ); - domElement.removeEventListener( 'touchmove', touchMove ); + domElement.addEventListener( 'contextmenu', contextmenu ); + domElement.addEventListener( 'dblclick', onMouseUp ); + domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } ); - }; + domElement.addEventListener( 'pointerdown', onPointerDown ); - domElement.addEventListener( 'contextmenu', contextmenu ); - domElement.addEventListener( 'dblclick', onMouseUp ); - domElement.addEventListener( 'wheel', onMouseWheel ); + // touch - domElement.addEventListener( 'pointerdown', onPointerDown ); + var touches = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ]; + var prevTouches = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ]; - // touch + var prevDistance = null; - var touches = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ]; - var prevTouches = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ]; + function touchStart( event ) { - var prevDistance = null; + if ( scope.enabled === false ) return; - function touchStart( event ) { + switch ( event.touches.length ) { - if ( scope.enabled === false ) return; + case 1: + touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); + touches[ 1 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); + break; - switch ( event.touches.length ) { + case 2: + touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); + touches[ 1 ].set( event.touches[ 1 ].pageX, event.touches[ 1 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); + prevDistance = touches[ 0 ].distanceTo( touches[ 1 ] ); + break; - case 1: - touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); - touches[ 1 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); - break; + } - case 2: - touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); - touches[ 1 ].set( event.touches[ 1 ].pageX, event.touches[ 1 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); - prevDistance = touches[ 0 ].distanceTo( touches[ 1 ] ); - break; + prevTouches[ 0 ].copy( touches[ 0 ] ); + prevTouches[ 1 ].copy( touches[ 1 ] ); } - prevTouches[ 0 ].copy( touches[ 0 ] ); - prevTouches[ 1 ].copy( touches[ 1 ] ); - } + function touchMove( event ) { + if ( scope.enabled === false ) return; - function touchMove( event ) { + event.preventDefault(); + event.stopPropagation(); - if ( scope.enabled === false ) return; + function getClosest( touch, touches ) { - event.preventDefault(); - event.stopPropagation(); + var closest = touches[ 0 ]; - function getClosest( touch, touches ) { + for ( var touch2 of touches ) { - var closest = touches[ 0 ]; + if ( closest.distanceTo( touch ) > touch2.distanceTo( touch ) ) closest = touch2; - for ( var touch2 of touches ) { + } - if ( closest.distanceTo( touch ) > touch2.distanceTo( touch ) ) closest = touch2; + return closest; } - return closest; + switch ( event.touches.length ) { - } + case 1: + touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); + touches[ 1 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); + scope.rotate( touches[ 0 ].sub( getClosest( touches[ 0 ], prevTouches ) ).multiplyScalar( - 1 ) ); + break; - switch ( event.touches.length ) { + case 2: + touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); + touches[ 1 ].set( event.touches[ 1 ].pageX, event.touches[ 1 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); + var distance = touches[ 0 ].distanceTo( touches[ 1 ] ); + scope.zoom( delta.set( 0, 0, prevDistance - distance ) ); + prevDistance = distance; - case 1: - touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); - touches[ 1 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); - scope.rotate( touches[ 0 ].sub( getClosest( touches[ 0 ], prevTouches ) ).multiplyScalar( - 1 ) ); - break; - case 2: - touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); - touches[ 1 ].set( event.touches[ 1 ].pageX, event.touches[ 1 ].pageY, 0 ).divideScalar( window.devicePixelRatio ); - var distance = touches[ 0 ].distanceTo( touches[ 1 ] ); - scope.zoom( delta.set( 0, 0, prevDistance - distance ) ); - prevDistance = distance; + var offset0 = touches[ 0 ].clone().sub( getClosest( touches[ 0 ], prevTouches ) ); + var offset1 = touches[ 1 ].clone().sub( getClosest( touches[ 1 ], prevTouches ) ); + offset0.x = - offset0.x; + offset1.x = - offset1.x; + scope.pan( offset0.add( offset1 ) ); - var offset0 = touches[ 0 ].clone().sub( getClosest( touches[ 0 ], prevTouches ) ); - var offset1 = touches[ 1 ].clone().sub( getClosest( touches[ 1 ], prevTouches ) ); - offset0.x = - offset0.x; - offset1.x = - offset1.x; + break; - scope.pan( offset0.add( offset1 ) ); + } - break; + prevTouches[ 0 ].copy( touches[ 0 ] ); + prevTouches[ 1 ].copy( touches[ 1 ] ); } - prevTouches[ 0 ].copy( touches[ 0 ] ); - prevTouches[ 1 ].copy( touches[ 1 ] ); + domElement.addEventListener( 'touchstart', touchStart, { passive: false } ); + domElement.addEventListener( 'touchmove', touchMove, { passive: false } ); } - domElement.addEventListener( 'touchstart', touchStart ); - domElement.addEventListener( 'touchmove', touchMove ); - } -EditorControls.prototype = Object.create( THREE.EventDispatcher.prototype ); -EditorControls.prototype.constructor = EditorControls; - export { EditorControls }; diff --git a/editor/js/History.js b/editor/js/History.js index ae76e9a5534226..519140e164a703 100644 --- a/editor/js/History.js +++ b/editor/js/History.js @@ -1,41 +1,40 @@ - import * as Commands from './commands/Commands.js'; -function History( editor ) { +class History { - this.editor = editor; - this.undos = []; - this.redos = []; - this.lastCmdTime = new Date(); - this.idCounter = 0; + constructor( editor ) { - this.historyDisabled = false; - this.config = editor.config; + this.editor = editor; + this.undos = []; + this.redos = []; + this.lastCmdTime = Date.now(); + this.idCounter = 0; - // signals + this.historyDisabled = false; + this.config = editor.config; - const scope = this; + // signals - this.editor.signals.startPlayer.add( function () { + const scope = this; - scope.historyDisabled = true; + this.editor.signals.startPlayer.add( function () { - } ); + scope.historyDisabled = true; - this.editor.signals.stopPlayer.add( function () { + } ); - scope.historyDisabled = false; + this.editor.signals.stopPlayer.add( function () { - } ); + scope.historyDisabled = false; -} + } ); -History.prototype = { + } - execute: function ( cmd, optionalName ) { + execute( cmd, optionalName ) { const lastCmd = this.undos[ this.undos.length - 1 ]; - const timeDifference = new Date().getTime() - this.lastCmdTime.getTime(); + const timeDifference = Date.now() - this.lastCmdTime; const isUpdatableCmd = lastCmd && lastCmd.updatable && @@ -76,16 +75,16 @@ History.prototype = { } - this.lastCmdTime = new Date(); + this.lastCmdTime = Date.now(); // clearing all the redo-commands this.redos = []; this.editor.signals.historyChanged.dispatch( cmd ); - }, + } - undo: function () { + undo() { if ( this.historyDisabled ) { @@ -118,9 +117,9 @@ History.prototype = { return cmd; - }, + } - redo: function () { + redo() { if ( this.historyDisabled ) { @@ -153,9 +152,9 @@ History.prototype = { return cmd; - }, + } - toJSON: function () { + toJSON() { const history = {}; history.undos = []; @@ -193,9 +192,9 @@ History.prototype = { return history; - }, + } - fromJSON: function ( json ) { + fromJSON( json ) { if ( json === undefined ) return; @@ -226,9 +225,9 @@ History.prototype = { // Select the last executed undo-command this.editor.signals.historyChanged.dispatch( this.undos[ this.undos.length - 1 ] ); - }, + } - clear: function () { + clear() { this.undos = []; this.redos = []; @@ -236,9 +235,9 @@ History.prototype = { this.editor.signals.historyChanged.dispatch(); - }, + } - goToState: function ( id ) { + goToState( id ) { if ( this.historyDisabled ) { @@ -281,9 +280,9 @@ History.prototype = { this.editor.signals.sceneGraphChanged.dispatch(); this.editor.signals.historyChanged.dispatch( cmd ); - }, + } - enableSerialization: function ( id ) { + enableSerialization( id ) { /** * because there might be commands in this.undos and this.redos @@ -317,6 +316,6 @@ History.prototype = { } -}; +} export { History }; diff --git a/editor/js/Loader.js b/editor/js/Loader.js index 18ac71481f6bf5..df0389449287ae 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,11 +196,11 @@ 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/' ); - loader.decodeDracoFile( contents, function ( geometry ) { + loader.setDecoderPath( '../examples/jsm/libs/draco/' ); + loader.parse( contents, function ( geometry ) { let object; @@ -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,11 +263,11 @@ 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/' ); + dracoLoader.setDecoderPath( '../examples/jsm/libs/draco/gltf/' ); const loader = new GLTFLoader(); loader.setDRACOLoader( dracoLoader ); @@ -279,6 +279,8 @@ function Loader( editor ) { scene.animations.push( ...result.animations ); editor.execute( new AddObjectCommand( editor, scene ) ); + dracoLoader.dispose(); + } ); }, false ); @@ -296,24 +298,14 @@ function Loader( editor ) { const contents = event.target.result; - let loader; - - if ( isGLTF1( contents ) ) { - - alert( 'Import of glTF asset not possible. Only versions >= 2.0 are supported. Please try to upgrade the file to glTF 2.0 using glTF-Pipeline.' ); - - } else { - - const { DRACOLoader } = await import( '../../examples/jsm/loaders/DRACOLoader.js' ); - const { GLTFLoader } = await import( '../../examples/jsm/loaders/GLTFLoader.js' ); - - const dracoLoader = new DRACOLoader(); - dracoLoader.setDecoderPath( '../examples/js/libs/draco/gltf/' ); + const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' ); + const { GLTFLoader } = await import( 'three/addons/loaders/GLTFLoader.js' ); - loader = new GLTFLoader( manager ); - loader.setDRACOLoader( dracoLoader ); + const dracoLoader = new DRACOLoader(); + dracoLoader.setDecoderPath( '../examples/jsm/libs/draco/gltf/' ); - } + const loader = new GLTFLoader( manager ); + loader.setDRACOLoader( dracoLoader ); loader.parse( contents, '', function ( result ) { @@ -323,6 +315,8 @@ function Loader( editor ) { scene.animations.push( ...result.animations ); editor.execute( new AddObjectCommand( editor, scene ) ); + dracoLoader.dispose(); + } ); }, false ); @@ -393,10 +387,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 +410,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 +433,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 +462,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 +489,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 +533,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 +572,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 +606,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 +650,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 +680,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 +714,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 +739,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 +760,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 +890,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 +931,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,11 +946,11 @@ 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/' ); + dracoLoader.setDecoderPath( '../examples/jsm/libs/draco/gltf/' ); const loader = new GLTFLoader(); loader.setDRACOLoader( dracoLoader ); @@ -946,6 +962,8 @@ function Loader( editor ) { scene.animations.push( ...result.animations ); editor.execute( new AddObjectCommand( editor, scene ) ); + dracoLoader.dispose(); + } ); break; @@ -956,11 +974,11 @@ 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/' ); + dracoLoader.setDecoderPath( '../examples/jsm/libs/draco/gltf/' ); const loader = new GLTFLoader( manager ); loader.setDRACOLoader( dracoLoader ); @@ -971,6 +989,8 @@ function Loader( editor ) { scene.animations.push( ...result.animations ); editor.execute( new AddObjectCommand( editor, scene ) ); + dracoLoader.dispose(); + } ); break; @@ -983,41 +1003,6 @@ function Loader( editor ) { } - function isGLTF1( contents ) { - - let resultContent; - - if ( typeof contents === 'string' ) { - - // contents is a JSON string - resultContent = contents; - - } else { - - const magic = THREE.LoaderUtils.decodeText( new Uint8Array( contents, 0, 4 ) ); - - if ( magic === 'glTF' ) { - - // contents is a .glb file; extract the version - const version = new DataView( contents ).getUint32( 4, true ); - - return version < 2; - - } else { - - // contents is a .gltf file - resultContent = THREE.LoaderUtils.decodeText( new Uint8Array( contents ) ); - - } - - } - - const json = JSON.parse( resultContent ); - - return ( json.asset != undefined && json.asset.version[ 0 ] < 2 ); - - } - } export { Loader }; diff --git a/editor/js/Menubar.Add.js b/editor/js/Menubar.Add.js index 30a68f237c450b..c55f108f1fe113 100644 --- a/editor/js/Menubar.Add.js +++ b/editor/js/Menubar.Add.js @@ -79,7 +79,7 @@ function MenubarAdd( editor ) { option.setTextContent( strings.getKey( 'menubar/add/circle' ) ); option.onClick( function () { - const geometry = new THREE.CircleGeometry( 1, 8, 0, Math.PI * 2 ); + const geometry = new THREE.CircleGeometry( 1, 32, 0, Math.PI * 2 ); const mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() ); mesh.name = 'Circle'; @@ -95,7 +95,7 @@ function MenubarAdd( editor ) { option.setTextContent( strings.getKey( 'menubar/add/cylinder' ) ); option.onClick( function () { - const geometry = new THREE.CylinderGeometry( 1, 1, 1, 8, 1, false, 0, Math.PI * 2 ); + const geometry = new THREE.CylinderGeometry( 1, 1, 1, 32, 1, false, 0, Math.PI * 2 ); const mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() ); mesh.name = 'Cylinder'; @@ -192,7 +192,7 @@ function MenubarAdd( editor ) { option.setTextContent( strings.getKey( 'menubar/add/ring' ) ); option.onClick( function () { - const geometry = new THREE.RingGeometry( 0.5, 1, 8, 1, 0, Math.PI * 2 ); + const geometry = new THREE.RingGeometry( 0.5, 1, 32, 1, 0, Math.PI * 2 ); const mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() ); mesh.name = 'Ring'; @@ -255,7 +255,7 @@ function MenubarAdd( editor ) { option.setTextContent( strings.getKey( 'menubar/add/torus' ) ); option.onClick( function () { - const geometry = new THREE.TorusGeometry( 1, 0.4, 8, 6, Math.PI * 2 ); + const geometry = new THREE.TorusGeometry( 1, 0.4, 12, 48, Math.PI * 2 ); const mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() ); mesh.name = 'Torus'; diff --git a/editor/js/Menubar.File.js b/editor/js/Menubar.File.js index 11932144c841fb..8b51fcad6cf585 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,11 +386,11 @@ 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(); - saveArrayBuffer( await exporter.parse( editor.scene, { binary: true } ), 'model.usdz' ); + saveArrayBuffer( await exporter.parse( editor.scene ), 'model.usdz' ); } ); options.add( option ); diff --git a/editor/js/Sidebar.Animation.js b/editor/js/Sidebar.Animation.js index cb41e1e78982da..62f17b0c87efb9 100644 --- a/editor/js/Sidebar.Animation.js +++ b/editor/js/Sidebar.Animation.js @@ -23,13 +23,11 @@ function SidebarAnimation( editor ) { const name = new UIText( animation.name ).setWidth( '200px' ); container.add( name ); - const button = new UIButton( getButtonText( action ) ); + const button = new UIButton( getButtonText( action ) ); button.onClick( function () { - console.log( action ); - action.isRunning() ? action.stop() : action.play(); - button.setTextContent( getButtonText( action ) ); + button.setTextContent( getButtonText( action ) ); } ); diff --git a/editor/js/Sidebar.Geometry.Modifiers.js b/editor/js/Sidebar.Geometry.Modifiers.js index e1f458bf4f3fc2..149d3c1aef7aaf 100644 --- a/editor/js/Sidebar.Geometry.Modifiers.js +++ b/editor/js/Sidebar.Geometry.Modifiers.js @@ -1,7 +1,9 @@ -import { UIDiv, UIButton } from './libs/ui.js'; +import { UIDiv, UIButton, UIRow } from './libs/ui.js'; function SidebarGeometryModifiers( editor, object ) { + const strings = editor.strings; + const signals = editor.signals; const container = new UIDiv().setPaddingLeft( '90px' ); @@ -10,18 +12,34 @@ function SidebarGeometryModifiers( editor, object ) { // Compute Vertex Normals - const button = new UIButton( 'Compute Vertex Normals' ); - button.onClick( function () { + const computeVertexNormalsButton = new UIButton( strings.getKey( 'sidebar/geometry/compute_vertex_normals' ) ); + computeVertexNormalsButton.onClick( function () { geometry.computeVertexNormals(); - geometry.attributes.normal.needsUpdate = true; + signals.geometryChanged.dispatch( object ); + + } ); + + const computeVertexNormalsRow = new UIRow(); + computeVertexNormalsRow.add( computeVertexNormalsButton ); + container.add( computeVertexNormalsRow ); + + + // Center Geometry + + const centerButton = new UIButton( strings.getKey( 'sidebar/geometry/center' ) ); + centerButton.onClick( function () { + + geometry.center(); signals.geometryChanged.dispatch( object ); } ); - container.add( button ); + const centerRow = new UIRow(); + centerRow.add( centerButton ); + container.add( centerRow ); // 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.ColorProperty.js b/editor/js/Sidebar.Material.ColorProperty.js index 2ab16949e8be1a..282daa388dde62 100644 --- a/editor/js/Sidebar.Material.ColorProperty.js +++ b/editor/js/Sidebar.Material.ColorProperty.js @@ -16,7 +16,7 @@ function SidebarMaterialColorProperty( editor, property, name ) { if ( property === 'emissive' ) { - intensity = new UINumber().setWidth( '30px' ).onChange( onChange ); + intensity = new UINumber( 1 ).setWidth( '30px' ).setRange( 0, Infinity ).onChange( onChange ); container.add( intensity ); } diff --git a/editor/js/Sidebar.Material.MapProperty.js b/editor/js/Sidebar.Material.MapProperty.js index d943599fdd6d5f..7626ea00be9234 100644 --- a/editor/js/Sidebar.Material.MapProperty.js +++ b/editor/js/Sidebar.Material.MapProperty.js @@ -26,7 +26,7 @@ function SidebarMaterialMapProperty( editor, property, name ) { if ( property === 'aoMap' ) { - intensity = new UINumber().setWidth( '30px' ).onChange( onIntensityChange ); + intensity = new UINumber( 1 ).setWidth( '30px' ).setRange( 0, 1 ).onChange( onIntensityChange ); container.add( intensity ); } @@ -55,7 +55,7 @@ function SidebarMaterialMapProperty( editor, property, name ) { let rangeMin, rangeMax; if ( property === 'iridescenceThicknessMap' ) { - + const range = new UIDiv().setMarginLeft( '3px' ); container.add( range ); diff --git a/editor/js/Sidebar.Material.js b/editor/js/Sidebar.Material.js index b700658d76b88a..ca87e8672a367d 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 = { @@ -316,6 +351,11 @@ function SidebarMaterial( editor ) { const materialTransparent = new SidebarMaterialBooleanProperty( editor, 'transparent', strings.getKey( 'sidebar/material/transparent' ) ); container.add( materialTransparent ); + // forceSinglePass + + const materialForceSinglePass = new SidebarMaterialBooleanProperty( editor, 'forceSinglePass', strings.getKey( 'sidebar/material/forcesinglepass' ) ); + container.add( materialForceSinglePass ); + // alpha test const materialAlphaTest = new SidebarMaterialNumberProperty( editor, 'alphaTest', strings.getKey( 'sidebar/material/alphatest' ), [ 0, 1 ] ); diff --git a/editor/js/Sidebar.Scene.js b/editor/js/Sidebar.Scene.js index bc09377528970b..d5b445a642cb8d 100644 --- a/editor/js/Sidebar.Scene.js +++ b/editor/js/Sidebar.Scene.js @@ -185,13 +185,27 @@ 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 ); + + const backgroundIntensity = new UINumber( 1 ).setWidth( '40px' ).setRange( 0, Infinity ).onChange( onBackgroundChanged ); + backgroundEquirectRow.add( backgroundIntensity ); + + container.add( backgroundEquirectRow ); + function onBackgroundChanged() { signals.sceneBackgroundChanged.dispatch( backgroundType.getValue(), backgroundColor.getHexValue(), backgroundTexture.getValue(), - backgroundEquirectangularTexture.getValue() + backgroundEquirectangularTexture.getValue(), + backgroundBlurriness.getValue(), + backgroundIntensity.getValue() ); } @@ -204,6 +218,7 @@ function SidebarScene( editor ) { backgroundColor.setDisplay( type === 'Color' ? '' : 'none' ); backgroundTexture.setDisplay( type === 'Texture' ? '' : 'none' ); backgroundEquirectangularTexture.setDisplay( type === 'Equirectangular' ? '' : 'none' ); + backgroundEquirectRow.setDisplay( type === 'Equirectangular' ? '' : 'none' ); } @@ -384,6 +399,8 @@ function SidebarScene( editor ) { backgroundType.setValue( 'Equirectangular' ); backgroundEquirectangularTexture.setValue( scene.background ); + backgroundBlurriness.setValue( scene.backgroundBlurriness ); + backgroundIntensity.setValue( scene.backgroundIntensity ); } else { diff --git a/editor/js/Strings.js b/editor/js/Strings.js index e9481ba6597bbe..7f93fa5bf1e229 100644 --- a/editor/js/Strings.js +++ b/editor/js/Strings.js @@ -134,6 +134,8 @@ function Strings( config ) { 'sidebar/geometry/name': 'Name', 'sidebar/geometry/bounds': 'Bounds', 'sidebar/geometry/show_vertex_normals': 'Show Vertex Normals', + 'sidebar/geometry/compute_vertex_normals': 'Compute Vertex Normals', + 'sidebar/geometry/center': 'Center', 'sidebar/geometry/box_geometry/width': 'Width', 'sidebar/geometry/box_geometry/height': 'Height', @@ -260,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', @@ -277,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', @@ -289,6 +298,7 @@ function Strings( config ) { 'sidebar/material/blending': 'Blending', 'sidebar/material/opacity': 'Opacity', 'sidebar/material/transparent': 'Transparent', + 'sidebar/material/forcesinglepass': 'Force Single Pass', 'sidebar/material/alphatest': 'Alpha Test', 'sidebar/material/depthtest': 'Depth Test', 'sidebar/material/depthwrite': 'Depth Write', @@ -476,6 +486,8 @@ function Strings( config ) { 'sidebar/geometry/name': 'Nom', 'sidebar/geometry/bounds': 'Limites', 'sidebar/geometry/show_vertex_normals': 'Afficher normales', + 'sidebar/geometry/compute_vertex_normals': 'Compute Vertex Normals', + 'sidebar/geometry/center': 'Center', 'sidebar/geometry/box_geometry/width': 'Largeur', 'sidebar/geometry/box_geometry/height': 'Hauteur', @@ -599,6 +611,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', @@ -614,11 +632,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', @@ -626,6 +650,7 @@ function Strings( config ) { 'sidebar/material/blending': 'Mélange', 'sidebar/material/opacity': 'Opacité', 'sidebar/material/transparent': 'Transparence', + 'sidebar/material/forcesinglepass': 'Force Single Pass', 'sidebar/material/alphatest': 'Test de transparence', 'sidebar/material/depthtest': 'Depth Test', 'sidebar/material/depthwrite': 'Depth Write', @@ -813,6 +838,8 @@ function Strings( config ) { 'sidebar/geometry/name': '名称', 'sidebar/geometry/bounds': '界限', 'sidebar/geometry/show_vertex_normals': '显示顶点法线', + 'sidebar/geometry/compute_vertex_normals': '计算顶点法线', + 'sidebar/geometry/center': '居中', 'sidebar/geometry/box_geometry/width': '宽度', 'sidebar/geometry/box_geometry/height': '高度', @@ -936,9 +963,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': '材质捕获', @@ -951,11 +984,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': '大小衰减', @@ -963,6 +1002,7 @@ function Strings( config ) { 'sidebar/material/blending': '混合', 'sidebar/material/opacity': '透明度', 'sidebar/material/transparent': '透明性', + 'sidebar/material/forcesinglepass': 'Force Single Pass', 'sidebar/material/alphatest': 'α测试', 'sidebar/material/depthtest': '深度测试', 'sidebar/material/depthwrite': '深度缓冲', diff --git a/editor/js/Viewport.Selector.js b/editor/js/Viewport.Selector.js new file mode 100644 index 00000000000000..dc4e13f5944b1a --- /dev/null +++ b/editor/js/Viewport.Selector.js @@ -0,0 +1,67 @@ +class Selector { + + constructor( editor ) { + + const signals = editor.signals; + + this.editor = editor; + this.signals = signals; + + // signals + + signals.intersectionsDetected.add( ( intersects ) => { + + if ( intersects.length > 0 ) { + + const object = intersects[ 0 ].object; + + if ( object.userData.object !== undefined ) { + + // helper + + this.select( object.userData.object ); + + } else { + + this.select( object ); + + } + + } else { + + this.select( null ); + + } + + } ); + + } + + select( object ) { + + if ( this.editor.selected === object ) return; + + let uuid = null; + + if ( object !== null ) { + + uuid = object.uuid; + + } + + this.editor.selected = object; + this.editor.config.setKey( 'selected', uuid ); + + this.signals.objectSelected.dispatch( object ); + + } + + deselect() { + + this.select( null ); + + } + +} + +export { Selector }; 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 742b7a69b9a787..1ebc729c3d39a1 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 ) { @@ -207,28 +207,7 @@ function Viewport( editor ) { if ( onDownPosition.distanceTo( onUpPosition ) === 0 ) { const intersects = getIntersects( onUpPosition ); - - if ( intersects.length > 0 ) { - - const object = intersects[ 0 ].object; - - if ( object.userData.object !== undefined ) { - - // helper - - editor.select( object.userData.object ); - - } else { - - editor.select( object ); - - } - - } else { - - editor.select( null ); - - } + signals.intersectionsDetected.dispatch( intersects ); render(); @@ -300,7 +279,7 @@ function Viewport( editor ) { } container.dom.addEventListener( 'mousedown', onMouseDown ); - container.dom.addEventListener( 'touchstart', onTouchStart ); + container.dom.addEventListener( 'touchstart', onTouchStart, { passive: false } ); container.dom.addEventListener( 'dblclick', onDoubleClick ); // controls need to be added *after* main logic, @@ -313,7 +292,7 @@ function Viewport( editor ) { signals.refreshSidebarObject3D.dispatch( camera ); } ); - viewHelper.controls = controls; + viewHelper.center = controls.center; // signals @@ -471,9 +450,11 @@ function Viewport( editor ) { } - if ( editor.helpers[ object.id ] !== undefined ) { + const helper = editor.helpers[ object.id ]; + + if ( helper !== undefined && helper.isSkeletonHelper !== true ) { - editor.helpers[ object.id ].update(); + helper.update(); } @@ -500,7 +481,7 @@ function Viewport( editor ) { // background - signals.sceneBackgroundChanged.add( function ( backgroundType, backgroundColor, backgroundTexture, backgroundEquirectangularTexture ) { + signals.sceneBackgroundChanged.add( function ( backgroundType, backgroundColor, backgroundTexture, backgroundEquirectangularTexture, backgroundBlurriness, backgroundIntensity ) { switch ( backgroundType ) { @@ -532,6 +513,8 @@ function Viewport( editor ) { backgroundEquirectangularTexture.mapping = THREE.EquirectangularReflectionMapping; scene.background = backgroundEquirectangularTexture; + scene.backgroundBlurriness = backgroundBlurriness; + scene.backgroundIntensity = backgroundIntensity; } diff --git a/editor/js/libs/app/index.html b/editor/js/libs/app/index.html index 574e29daeb2a7e..81b979b430c524 100644 --- a/editor/js/libs/app/index.html +++ b/editor/js/libs/app/index.html @@ -27,6 +27,8 @@ window.THREE = THREE; // Used by APP Scripts. window.VRButton = VRButton; // Used by APP Scripts. + THREE.ColorManagement.legacyMode = false; + var loader = new THREE.FileLoader(); loader.load( 'app.json', function ( text ) { diff --git a/editor/js/libs/codemirror/codemirror.js b/editor/js/libs/codemirror/codemirror.js index 193d445b4c869e..e9cb967554f6f1 100644 --- a/editor/js/libs/codemirror/codemirror.js +++ b/editor/js/libs/codemirror/codemirror.js @@ -533,7 +533,7 @@ var on = function(emitter, type, f) { if (emitter.addEventListener) { - emitter.addEventListener(type, f, false); + emitter.addEventListener(type, f, { passive: false }); } else if (emitter.attachEvent) { emitter.attachEvent("on" + type, f); } else { 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 'bmap-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 0a2f0bdefe3974..3b9cd1ada9fae7 100644 --- a/examples/css3d_molecules.html +++ b/examples/css3d_molecules.html @@ -10,44 +10,6 @@ background-color: #050505; background: radial-gradient(ellipse at center, rgba(43,45,48,1) 0%,rgba(0,0,0,1) 100%); } - - #topmenu { - position: absolute; - top: 50px; - width: 100%; - padding: 10px; - box-sizing: border-box; - text-align: center; - } - - #menu { - position: absolute; - bottom: 20px; - width: 100%; - padding: 10px; - box-sizing: border-box; - text-align: center; - } - - button { - color: rgb(255,255,255); - background: rgb(255,255,255,0.1); - border: 0px; - padding: 5px 10px; - margin: 2px; - font-size: 14px; - cursor: pointer; - } - - button:hover { - background-color: rgba(0,255,255,0.5); - } - - button:active { - color: #000000; - background-color: rgba(0,255,255,1); - } - .bond { width: 5px; height: 10px; @@ -59,10 +21,6 @@
          three.js css3d - molecules
          -
          - -
          - @@ -71,7 +29,8 @@ @@ -80,9 +39,10 @@ import * as THREE from 'bmap-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 { 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; @@ -95,7 +55,11 @@ const tmpVec4 = new THREE.Vector3(); const offset = new THREE.Vector3(); - let visualizationType = 2; + const VIZ_TYPE = { + 'Atoms': 0, + 'Bonds': 1, + 'Atoms + Bonds': 2 + }; const MOLECULES = { 'Ethanol': 'ethanol.pdb', @@ -118,12 +82,15 @@ 'Graphite': 'graphite.pdb' }; + const params = { + vizType: 2, + molecule: 'caffeine.pdb' + }; + const loader = new PDBLoader(); const colorSpriteMap = {}; const baseSprite = document.createElement( 'img' ); - const menu = document.getElementById( 'menu' ); - init(); animate(); @@ -152,8 +119,7 @@ baseSprite.onload = function () { - loadMolecule( 'models/pdb/caffeine.pdb' ); - createMenu(); + loadMolecule( params.molecule ); }; @@ -163,56 +129,21 @@ window.addEventListener( 'resize', onWindowResize ); - } - - // - - function generateButtonCallback( url ) { - - return function () { + // - loadMolecule( url ); + const gui = new GUI(); - }; + gui.add( params, 'vizType', VIZ_TYPE ).onChange( changeVizType ); + gui.add( params, 'molecule', MOLECULES ).onChange( loadMolecule ); + gui.open(); } - function createMenu() { - - for ( const m in MOLECULES ) { - - const button = document.createElement( 'button' ); - button.innerHTML = m; - menu.appendChild( button ); + function changeVizType( value ) { - const url = 'models/pdb/' + MOLECULES[ m ]; - - button.addEventListener( 'click', generateButtonCallback( url ) ); - - } - - const b_a = document.getElementById( 'b_a' ); - const b_b = document.getElementById( 'b_b' ); - const b_ab = document.getElementById( 'b_ab' ); - - b_a.addEventListener( 'click', function () { - - visualizationType = 0; - showAtoms(); - - } ); - b_b.addEventListener( 'click', function () { - - visualizationType = 1; - showBonds(); - - } ); - b_ab.addEventListener( 'click', function () { - - visualizationType = 2; - showAtomsBonds(); - - } ); + if ( value === 0 ) showAtoms(); + else if ( value === 1 ) showBonds(); + else showAtomsBonds(); } @@ -322,7 +253,9 @@ // - function loadMolecule( url ) { + function loadMolecule( model ) { + + const url = 'models/pdb/' + model; for ( let i = 0; i < objects.length; i ++ ) { @@ -471,19 +404,7 @@ //console.log( "CSS3DObjects:", objects.length ); - switch ( visualizationType ) { - - case 0: - showAtoms(); - break; - case 1: - showBonds(); - break; - case 2: - showAtomsBonds(); - break; - - } + changeVizType( params.vizType ); } ); diff --git a/examples/css3d_orthographic.html b/examples/css3d_orthographic.html index ca7a60a77df880..9088e75eacea7b 100644 --- a/examples/css3d_orthographic.html +++ b/examples/css3d_orthographic.html @@ -27,7 +27,8 @@ @@ -36,8 +37,8 @@ import * as THREE from 'bmap-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 ac23e5b8e098f6..9eded885dc66e3 100644 --- a/examples/css3d_periodictable.html +++ b/examples/css3d_periodictable.html @@ -98,7 +98,8 @@ @@ -107,9 +108,9 @@ import * as THREE from 'bmap-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 0c0f92aa96aa1d..4b04b909db9142 100644 --- a/examples/css3d_sandbox.html +++ b/examples/css3d_sandbox.html @@ -23,7 +23,8 @@ @@ -32,8 +33,8 @@ import * as THREE from 'bmap-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 d3d0f061987edc..9ab141990d1c2a 100644 --- a/examples/css3d_sprites.html +++ b/examples/css3d_sprites.html @@ -27,7 +27,8 @@ @@ -36,9 +37,9 @@ import * as THREE from 'bmap-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 781c4a05cc851b..aab2c609d8f76f 100644 --- a/examples/css3d_youtube.html +++ b/examples/css3d_youtube.html @@ -30,7 +30,8 @@ @@ -39,8 +40,8 @@ import * as THREE from 'bmap-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 25daa66c655668..0f3f2a647d7dd6 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", @@ -26,6 +27,7 @@ "webgl_geometry_colors", "webgl_geometry_colors_lookuptable", "webgl_geometry_convex", + "webgl_geometry_csg", "webgl_geometry_cube", "webgl_geometry_dynamic", "webgl_geometry_extrude_shapes", @@ -84,7 +86,10 @@ "webgl_loader_fbx_nurbs", "webgl_loader_gcode", "webgl_loader_gltf", + "webgl_loader_gltf_avif", "webgl_loader_gltf_compressed", + "webgl_loader_gltf_instancing", + "webgl_loader_gltf_iridescence", "webgl_loader_gltf_sheen", "webgl_loader_gltf_transmission", "webgl_loader_gltf_variants", @@ -119,7 +124,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", @@ -140,6 +147,7 @@ "webgl_materials_displacementmap", "webgl_materials_envmaps", "webgl_materials_envmaps_exr", + "webgl_materials_envmaps_groundprojected", "webgl_materials_envmaps_hdr", "webgl_materials_lightmap", "webgl_materials_matcap", @@ -172,6 +180,7 @@ "webgl_modifier_curve_instanced", "webgl_modifier_edgesplit", "webgl_modifier_simplifier", + "webgl_modifier_subdivision", "webgl_modifier_tessellation", "webgl_morphtargets", "webgl_morphtargets_face", @@ -195,9 +204,11 @@ "webgl_points_sprites", "webgl_points_waves", "webgl_portal", - "webgl_raycast_sprite", - "webgl_raycast_texture", + "webgl_raycaster_bvh", + "webgl_raycaster_sprite", + "webgl_raycaster_texture", "webgl_read_float_buffer", + "webgl_renderer_pathtracer", "webgl_refraction", "webgl_rtt", "webgl_shader", @@ -225,10 +236,16 @@ "webgl_water_flowmap" ], "webgl / nodes": [ - "webgl_materials_instance_uniform_nodes", - "webgl_materials_standard_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_points_nodes" + "webgl_nodes_points" ], "webgl / postprocessing": [ "webgl_postprocessing", @@ -283,7 +300,6 @@ "webgl_gpgpu_birds_gltf", "webgl_gpgpu_water", "webgl_gpgpu_protoplanet", - "webgl_instancing_modified", "webgl_lightningstrike", "webgl_materials_modified", "webgl_raymarching_reflect", @@ -296,28 +312,36 @@ ], "webgl2": [ "webgl2_buffergeometry_attributes_integer", + "webgl2_buffergeometry_attributes_none", "webgl2_materials_texture2darray", "webgl2_materials_texture3d", "webgl2_materials_texture3d_partialupdate", "webgl2_multiple_rendertargets", - "webgl2_multiple_rendertargets_multisampled", "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", + "webgpu_lights_ies_spotlight", + "webgpu_lights_phong", "webgpu_lights_selective", "webgpu_loader_gltf", "webgpu_materials", "webgpu_nodes_playground", + "webgpu_particles", "webgpu_rtt", "webgpu_sandbox", "webgpu_skinning", @@ -333,9 +357,11 @@ ], "webxr": [ "webxr_ar_cones", + "webxr_ar_dragging", "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 49e8b3eb593710..61860ad25c1964 100644 --- a/examples/games_fps.html +++ b/examples/games_fps.html @@ -21,7 +21,8 @@ @@ -30,16 +31,16 @@ import * as THREE from 'bmap-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/ies/007cfb11e343e2f42e3b476be4ab684e.ies b/examples/ies/007cfb11e343e2f42e3b476be4ab684e.ies new file mode 100644 index 00000000000000..52b2e8a994325c --- /dev/null +++ b/examples/ies/007cfb11e343e2f42e3b476be4ab684e.ies @@ -0,0 +1,28 @@ +IESNA:LM-63-1995 +[TEST] +[MANUFAC] BEGA +[MORE] Copyright LUMCat V +[LUMCAT] +[LUMINAIRE] 50975.6K3 (Preliminary) +[LAMPCAT] LED 7,9W +[LAMP] 321 lm,9 W +TILT=NONE +1 -1 1.0 73 1 1 2 -0.080 0.000 0.000 +1.0 1.0 9 + 0.0 2.5 5.0 7.5 10.0 12.5 15.0 17.5 20.0 22.5 25.0 27.5 30.0 + 32.5 35.0 37.5 40.0 42.5 45.0 47.5 50.0 52.5 55.0 57.5 60.0 62.5 + 65.0 67.5 70.0 72.5 75.0 77.5 80.0 82.5 85.0 87.5 90.0 92.5 95.0 + 97.5 100.0 102.5 105.0 107.5 110.0 112.5 115.0 117.5 120.0 122.5 125.0 127.5 + 130.0 132.5 135.0 137.5 140.0 142.5 145.0 147.5 150.0 152.5 155.0 157.5 160.0 + 162.5 165.0 167.5 170.0 172.5 175.0 177.5 180.0 + 0.0 + 330.8 333.2 335.2 336.2 336.8 337.1 337.2 336.7 + 331.4 302.1 238.1 159.9 90.7 51.3 38.9 36.0 + 34.8 34.2 33.5 32.7 31.6 29.3 25.2 19.8 + 15.4 12.3 9.9 8.1 6.4 5.1 3.9 3.0 + 2.1 1.4 0.9 0.4 0.1 0.1 0.1 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.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 + 0.0 diff --git a/examples/ies/02a7562c650498ebb301153dbbf59207.ies b/examples/ies/02a7562c650498ebb301153dbbf59207.ies new file mode 100644 index 00000000000000..fcf33147fc956b --- /dev/null +++ b/examples/ies/02a7562c650498ebb301153dbbf59207.ies @@ -0,0 +1,202 @@ +IESNA:LM-63-1995 +[TEST] +[MANUFAC] BEGA +[MORE] Copyright LUMCat V +[LUMCAT] +[LUMINAIRE] 84659K4 (Preliminary) +[LAMPCAT] LED 62W +[LAMP] 9600 lm,68 W +TILT=NONE +1 -1 1.0 37 37 1 2 0.240 0.270 0.000 +1.0 1.0 68 + 0.0 2.5 5.0 7.5 10.0 12.5 15.0 17.5 20.0 22.5 25.0 27.5 30.0 + 32.5 35.0 37.5 40.0 42.5 45.0 47.5 50.0 52.5 55.0 57.5 60.0 62.5 + 65.0 67.5 70.0 72.5 75.0 77.5 80.0 82.5 85.0 87.5 90.0 + 90.0 95.0 100.0 105.0 110.0 115.0 120.0 125.0 130.0 135.0 140.0 145.0 150.0 + 155.0 160.0 165.0 170.0 175.0 180.0 185.0 190.0 195.0 200.0 205.0 210.0 215.0 + 220.0 225.0 230.0 235.0 240.0 245.0 250.0 255.0 260.0 265.0 270.0 + 1739.8 1748.5 1754.2 1758.7 1775.5 1813.8 1888.7 2057.8 + 2268.7 2530.0 2653.0 2727.6 2847.9 2943.6 3012.0 3010.7 + 2925.3 2695.3 2336.5 1929.2 1501.3 1136.6 808.5 532.9 + 280.7 122.6 64.3 37.0 26.4 18.3 12.9 8.2 + 5.1 2.4 0.3 0.0 0.0 + 1739.8 1748.6 1755.1 1761.4 1779.4 1810.3 1897.9 2049.0 + 2262.6 2522.0 2673.8 2761.2 2883.7 2983.2 3028.5 3050.3 + 2988.3 2746.1 2362.9 1967.1 1541.8 1172.7 839.4 558.2 + 309.8 141.1 80.4 50.8 35.6 24.5 16.9 10.8 + 7.1 4.0 1.2 0.0 0.0 + 1739.8 1749.1 1757.4 1767.4 1785.7 1823.3 1899.7 2048.4 + 2256.2 2498.9 2694.0 2773.9 2844.4 2922.8 2988.7 3031.0 + 3027.4 2881.6 2567.2 2188.7 1761.0 1375.4 1018.7 699.3 + 400.3 196.2 113.3 71.3 47.6 32.5 22.1 14.8 + 9.7 5.2 2.1 0.1 0.0 + 1739.8 1749.8 1760.2 1773.9 1795.1 1832.1 1900.1 2045.2 + 2239.3 2482.5 2660.9 2744.7 2861.5 3034.0 3184.8 3305.3 + 3327.2 3210.1 2878.7 2442.9 1979.1 1517.9 1151.7 808.6 + 498.3 261.5 152.9 99.1 66.3 42.9 26.9 18.1 + 11.5 6.5 2.5 0.0 0.0 + 1739.8 1750.6 1763.0 1780.3 1803.0 1833.0 1894.3 2008.2 + 2199.0 2444.7 2696.9 2888.1 3087.5 3267.2 3389.1 3432.1 + 3418.0 3298.7 3024.6 2609.8 2146.7 1683.6 1305.7 944.7 + 626.2 363.9 214.5 137.1 87.4 54.7 34.9 23.2 + 15.2 8.4 2.5 0.0 0.0 + 1739.8 1751.6 1766.6 1786.2 1806.4 1826.5 1860.2 1973.2 + 2177.0 2478.9 2808.4 3035.9 3161.6 3281.4 3384.3 3448.8 + 3438.0 3361.0 3159.2 2800.0 2365.0 1909.0 1518.8 1156.2 + 839.7 537.7 333.0 229.1 153.9 98.5 60.9 38.2 + 22.2 10.8 3.6 0.0 0.0 + 1739.8 1752.7 1771.7 1792.3 1802.7 1808.7 1832.9 1970.3 + 2231.9 2557.8 2848.8 3046.8 3145.9 3246.5 3374.8 3453.3 + 3465.7 3410.5 3291.8 3011.3 2624.9 2203.5 1792.9 1450.0 + 1136.5 840.7 606.6 481.8 364.3 246.9 150.7 88.9 + 48.1 22.0 6.9 0.3 0.0 + 1739.8 1753.8 1777.0 1796.5 1794.8 1791.9 1841.4 2021.7 + 2280.7 2542.2 2771.2 2975.5 3121.1 3248.2 3391.1 3511.0 + 3531.5 3484.4 3392.6 3203.7 2913.7 2548.4 2163.0 1821.9 + 1540.7 1327.8 1160.0 1022.5 800.9 563.3 370.4 228.6 + 125.4 51.8 15.1 1.2 0.1 + 1739.8 1754.8 1781.0 1795.7 1781.8 1792.6 1886.5 2075.7 + 2261.2 2450.6 2649.5 2876.7 3093.7 3285.2 3444.9 3600.0 + 3677.9 3661.2 3584.7 3460.9 3265.7 2991.9 2661.8 2352.5 + 2166.2 2101.0 2042.7 1810.4 1435.5 1092.7 774.0 501.6 + 276.8 103.1 26.9 2.6 0.0 + 1739.8 1755.4 1782.8 1790.5 1772.5 1813.9 1953.0 2096.5 + 2208.0 2334.6 2514.0 2750.9 3033.0 3305.6 3497.4 3638.5 + 3780.3 3871.8 3869.9 3803.3 3693.5 3534.0 3313.6 3128.5 + 3083.1 3162.1 3100.2 2758.2 2262.6 1809.0 1341.3 899.8 + 500.0 187.6 46.7 4.3 0.0 + 1739.8 1755.7 1782.8 1783.3 1768.3 1848.9 2006.2 2097.5 + 2154.6 2236.7 2392.4 2608.1 2899.4 3231.2 3514.3 3713.1 + 3856.4 3983.7 4070.7 4087.8 4080.7 4098.0 4077.7 4091.0 + 4192.6 4272.4 4144.6 3754.2 3197.0 2607.4 2005.6 1386.9 + 778.1 293.9 79.5 7.5 0.0 + 1739.8 1755.4 1782.2 1774.3 1772.9 1890.9 2037.3 2090.6 + 2116.9 2172.1 2286.5 2481.7 2751.7 3076.9 3413.4 3703.8 + 3904.5 4053.3 4183.4 4293.1 4376.2 4499.1 4733.8 5032.2 + 5271.9 5261.5 5017.0 4611.3 4064.9 3373.1 2651.0 1878.4 + 1053.3 386.3 107.3 13.3 0.0 + 1739.8 1754.8 1781.2 1763.5 1782.8 1925.4 2052.3 2085.7 + 2109.9 2148.2 2230.5 2373.6 2592.0 2872.4 3193.1 3524.8 + 3813.4 4054.3 4243.0 4393.5 4537.7 4758.7 5191.2 5738.1 + 6099.8 6004.9 5742.4 5359.5 4807.0 4117.3 3298.1 2376.1 + 1374.9 499.6 137.2 19.0 0.1 + 1739.8 1754.2 1779.0 1753.3 1795.5 1954.6 2057.7 2081.8 + 2106.0 2140.8 2198.8 2293.9 2431.6 2638.7 2872.8 3146.3 + 3442.6 3729.7 4009.0 4277.9 4534.4 4841.2 5334.3 5971.2 + 6458.4 6427.8 6214.9 5945.5 5405.8 4726.0 3924.8 2910.2 + 1731.6 647.9 172.7 24.4 0.2 + 1739.8 1753.7 1775.5 1747.2 1811.0 1975.6 2058.3 2078.1 + 2100.7 2143.1 2192.8 2252.8 2332.3 2443.4 2578.3 2735.2 + 2900.4 3095.8 3322.8 3611.9 3979.1 4473.8 5057.7 5592.9 + 6039.2 6254.0 6274.6 6086.8 5637.3 5050.5 4315.5 3337.6 + 2052.6 777.2 188.6 27.0 0.1 + 1739.8 1753.5 1772.1 1743.4 1825.3 1988.7 2055.7 2075.2 + 2104.0 2147.1 2182.2 2230.3 2278.6 2338.0 2407.8 2488.4 + 2561.1 2649.0 2758.2 2933.2 3221.1 3689.9 4315.9 4887.8 + 5217.3 5403.3 5578.3 5593.9 5285.6 4859.4 4234.2 3286.5 + 2092.1 833.6 192.9 25.7 0.1 + 1739.8 1753.4 1770.3 1741.1 1834.5 1998.4 2060.2 2074.5 + 2102.5 2137.9 2177.5 2212.0 2239.4 2273.8 2324.5 2374.0 + 2422.9 2478.7 2555.6 2672.0 2890.8 3264.9 3773.6 4189.1 + 4395.8 4538.9 4636.8 4609.0 4417.1 4064.6 3531.1 2726.5 + 1743.9 712.5 163.7 22.3 0.0 + 1739.8 1753.2 1769.9 1740.7 1844.3 2003.6 2059.3 2074.3 + 2101.9 2140.5 2174.2 2200.8 2225.4 2242.9 2274.6 2316.0 + 2375.6 2439.1 2522.0 2651.4 2890.5 3269.0 3713.2 4051.6 + 4168.6 4152.3 4098.0 3932.4 3645.8 3237.7 2704.4 2024.6 + 1266.2 505.7 118.2 17.2 0.2 + 1739.8 1752.7 1768.9 1739.4 1848.0 2005.0 2057.8 2076.1 + 2105.3 2138.8 2172.1 2193.3 2208.4 2232.2 2264.7 2306.5 + 2370.7 2456.0 2566.0 2716.8 2996.1 3411.2 3879.6 4247.8 + 4401.7 4315.5 4107.0 3814.8 3470.1 3017.1 2489.7 1881.1 + 1180.9 457.8 104.1 14.4 0.2 + 1739.8 1751.9 1766.5 1736.6 1841.4 1999.8 2051.3 2064.5 + 2091.3 2125.1 2159.2 2184.1 2191.0 2207.5 2233.7 2281.7 + 2347.3 2428.6 2529.8 2693.0 2968.7 3391.4 3882.6 4271.4 + 4468.1 4373.3 4162.7 3880.4 3514.7 2965.6 2326.5 1745.4 + 1081.3 418.7 96.3 13.4 1.0 + 1739.8 1750.6 1763.4 1733.9 1826.0 1984.8 2039.0 2046.3 + 2062.0 2088.3 2113.7 2133.3 2141.8 2161.8 2185.5 2224.5 + 2273.4 2341.5 2413.9 2555.7 2779.9 3119.7 3534.7 3883.8 + 4018.8 3886.8 3657.9 3358.8 2911.8 2312.5 1679.0 1171.2 + 650.0 219.8 51.6 7.1 0.1 + 1739.8 1748.8 1761.1 1728.9 1802.9 1961.8 2019.1 2024.3 + 2035.5 2051.2 2063.9 2066.3 2069.3 2082.4 2104.1 2127.4 + 2161.4 2207.3 2257.9 2335.9 2458.5 2688.2 2954.9 3149.0 + 3185.9 2991.3 2712.6 2412.9 1981.8 1449.2 948.1 615.6 + 320.2 97.1 23.3 3.3 0.2 + 1739.8 1746.5 1759.4 1723.6 1777.0 1932.0 1998.8 1995.7 + 1994.2 2001.1 2002.5 1998.9 1987.0 1981.7 1985.9 1995.0 + 1999.0 1996.4 1977.9 1933.3 1936.8 2021.7 2181.6 2300.9 + 2256.1 2053.8 1778.0 1471.1 1135.3 799.3 514.5 323.3 + 164.0 54.3 15.1 1.6 0.1 + 1739.8 1744.0 1757.0 1721.8 1748.6 1894.2 1976.7 1971.4 + 1956.9 1944.0 1936.1 1924.3 1898.2 1872.1 1842.7 1794.3 + 1718.2 1646.3 1576.3 1483.8 1417.8 1401.1 1440.9 1460.8 + 1416.0 1272.8 1065.0 836.9 632.9 445.5 286.8 178.6 + 94.5 37.6 12.6 1.2 0.3 + 1739.8 1741.7 1753.4 1722.7 1722.0 1842.1 1944.5 1941.7 + 1918.0 1891.7 1868.5 1851.0 1816.6 1752.6 1640.2 1519.0 + 1434.8 1324.8 1200.9 1070.9 944.0 869.6 846.3 831.3 + 790.4 737.8 618.3 463.7 343.7 247.9 165.4 107.8 + 60.6 28.2 10.6 1.1 0.1 + 1739.8 1739.8 1748.9 1724.2 1698.3 1788.1 1901.0 1907.5 + 1882.0 1856.4 1822.8 1785.5 1710.2 1563.1 1442.7 1331.9 + 1185.6 1054.8 883.0 738.7 614.5 520.0 465.7 457.4 + 447.6 406.0 346.2 275.1 205.1 152.5 114.7 80.8 + 48.6 23.4 9.0 1.0 0.0 + 1739.8 1738.1 1743.9 1725.3 1681.1 1728.5 1845.0 1873.7 + 1849.8 1813.1 1773.9 1679.5 1531.6 1417.5 1288.7 1126.7 + 980.5 804.6 659.8 523.7 411.4 329.1 333.5 349.1 + 341.6 296.6 255.7 218.4 169.0 130.9 111.9 85.7 + 54.1 24.0 7.9 0.6 0.4 + 1739.8 1736.4 1738.6 1726.7 1675.0 1674.9 1765.5 1832.5 + 1821.7 1779.7 1679.0 1525.9 1406.7 1277.8 1119.9 973.6 + 776.8 629.6 489.6 373.0 292.8 297.0 338.4 373.3 + 360.6 319.8 289.8 241.5 177.2 139.2 116.7 85.4 + 50.4 21.6 5.9 0.6 0.2 + 1739.8 1734.9 1733.0 1726.6 1678.5 1639.2 1676.6 1759.3 + 1781.8 1728.1 1560.6 1415.1 1296.8 1138.6 994.1 791.0 + 639.3 488.9 362.5 271.5 278.4 342.3 430.8 470.2 + 433.8 400.4 375.7 296.9 194.9 131.9 99.3 72.7 + 46.8 21.9 6.2 0.3 0.1 + 1739.8 1733.4 1726.2 1721.4 1683.0 1628.9 1608.0 1656.3 + 1704.4 1642.1 1461.3 1338.6 1178.5 1036.7 842.3 665.5 + 509.1 370.1 248.1 237.4 299.4 424.0 538.7 550.9 + 505.8 511.8 478.4 333.3 185.0 107.6 77.9 62.2 + 39.9 17.1 4.6 0.4 0.7 + 1739.8 1731.9 1718.6 1711.6 1685.5 1634.5 1578.3 1566.8 + 1578.6 1503.9 1391.7 1255.9 1088.7 918.0 716.7 559.7 + 401.4 255.8 187.5 211.9 297.5 428.9 500.2 478.8 + 461.1 488.9 417.1 244.3 117.7 65.4 46.5 33.1 + 19.9 8.9 2.5 0.5 0.7 + 1739.8 1730.4 1712.0 1698.4 1680.5 1643.5 1584.6 1522.5 + 1448.6 1328.1 1281.5 1153.1 1024.0 806.2 630.3 450.3 + 309.5 184.1 158.9 180.9 253.0 347.8 373.9 338.1 + 321.6 318.9 245.2 135.1 69.1 41.8 29.2 21.0 + 13.5 6.3 1.6 0.2 0.5 + 1739.8 1728.7 1707.5 1686.4 1669.4 1640.1 1597.6 1534.1 + 1390.3 1215.9 1131.7 1016.4 911.0 711.6 558.9 394.2 + 239.7 152.3 141.0 158.0 216.4 290.9 300.0 255.6 + 228.7 224.1 172.4 88.1 36.6 18.1 12.7 8.7 + 5.8 3.1 0.9 0.3 0.3 + 1739.8 1727.3 1704.7 1677.5 1654.2 1625.8 1594.5 1538.4 + 1391.4 1223.5 1086.3 937.0 788.1 619.2 476.3 340.5 + 195.2 136.2 124.3 136.7 186.6 250.5 253.2 209.8 + 198.9 210.2 154.6 57.6 19.1 7.5 2.6 0.4 + 0.3 0.1 0.3 0.1 0.1 + 1739.8 1726.1 1702.3 1671.4 1641.1 1613.2 1577.6 1520.4 + 1376.1 1245.4 1102.8 950.4 762.0 587.5 432.1 303.3 + 173.0 126.7 111.5 113.1 144.8 183.9 180.1 150.1 + 148.3 152.5 110.7 58.0 29.4 14.6 6.5 3.5 + 2.2 1.2 0.3 0.2 0.3 + 1739.8 1725.3 1699.4 1669.8 1633.6 1599.7 1563.7 1498.5 + 1345.3 1223.2 1074.8 935.8 757.2 592.9 431.9 290.9 + 166.9 125.1 107.4 101.7 108.6 116.4 100.5 77.0 + 69.3 66.1 49.9 31.9 17.8 9.2 6.1 5.1 + 3.8 2.4 0.4 0.2 0.1 + 1739.8 1725.1 1697.8 1670.7 1629.3 1595.2 1555.4 1496.7 + 1324.7 1209.7 1067.7 938.0 736.8 576.8 423.8 288.7 + 163.9 124.3 105.5 94.1 90.2 83.9 64.6 44.4 + 32.4 26.8 19.6 12.9 7.9 4.1 2.8 2.2 + 1.1 0.2 0.2 0.1 0.2 diff --git a/examples/ies/06b4cfdc8805709e767b5e2e904be8ad.ies b/examples/ies/06b4cfdc8805709e767b5e2e904be8ad.ies new file mode 100644 index 00000000000000..d025fd3dfc9663 --- /dev/null +++ b/examples/ies/06b4cfdc8805709e767b5e2e904be8ad.ies @@ -0,0 +1,87 @@ +IESNA:LM-63-1995 +[TEST] +[MANUFAC] BEGA +[MORE] Copyright LUMCat V +[LUMCAT] +[LUMINAIRE] 50899.2K3 +[LAMPCAT] LED 11,5W +[LAMP] 1221 lm,14 W +TILT=NONE +1 -1 1.0 19 24 1 2 -0.120 0.000 0.000 +1.0 1.0 14 + 0.0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 50.0 55.0 60.0 + 65.0 70.0 75.0 80.0 85.0 90.0 + 0.0 15.0 30.0 45.0 60.0 75.0 90.0 105.0 120.0 135.0 150.0 165.0 180.0 + 195.0 210.0 225.0 240.0 255.0 270.0 285.0 300.0 315.0 330.0 345.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 + 2160.3 1896.0 1447.3 1122.5 882.7 695.9 546.9 529.2 + 284.6 41.6 27.5 23.8 21.4 20.2 18.5 10.0 + 4.9 1.7 0.0 diff --git a/examples/ies/1a936937a49c63374e6d4fbed9252b29.ies b/examples/ies/1a936937a49c63374e6d4fbed9252b29.ies new file mode 100644 index 00000000000000..0d3e38acde1c64 --- /dev/null +++ b/examples/ies/1a936937a49c63374e6d4fbed9252b29.ies @@ -0,0 +1,30 @@ +IESNA:LM-63-2002 +[TEST] LightLab International Test Report No. LL20433-R01-S1 +[MANUFAC] Efficient Lighting Systems, +[MORE] Brunswick. VIC. 3056. +[LUMINAIRE] Efficient Lighting Systems LED Display Track Light. Product ID: DT106.XTM10.N.94.61. +[MORE] Cylindrical cast aluminium body and rectangular gear housing, 150 x 165 x 140 mm deep. +[MORE] Recessed glass lens. Luminous opening of 92 mm diameter. Specular multifaceted “15 degree” reflector +[MORE] about LED. One "Xicato XTM19954030CCA 0D" LED centred 60 mm above L/O. +[MORE] One Harvard Technology CL40-1050S2D 220-240V 50/60Hz electronic driver set to “1050mA” +[OTHER] Absolute test - lamp lumens value set to -1 +[MORE] NA conventions used for C0 plane alignment and C-plane rotation direction. +[MORE] The sample was tested at a distance of 8m. +[MORE] This IES file created by LightLab/LSA Report program version 3.803a. +[DATE] This file created: Tuesday, 26 September 2017 4:14:01 PM +[LUMCAT] DT106.XTM10.N.94.61 +[TESTLAB] LightLab International +[ISSUEDATE] 26/09/2017 +TILT=NONE +1 -1 1.498 181 1 1 2 -0.092 -0.092 0 +1 1 39 +0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7 7.5 8 8.5 9 9.5 10 10.5 11 11.5 12 12.5 13 13.5 14 14.5 15 15.5 16 16.5 17 17.5 18 18.5 19 19.5 20 20.5 21 21.5 22 22.5 23 23.5 24 24.5 25 25.5 26 26.5 27 27.5 28 28.5 29 29.5 30 30.5 31 31.5 32 32.5 33 33.5 34 +34.5 35 35.5 36 36.5 37 37.5 38 38.5 39 39.5 40 40.5 41 41.5 42 42.5 43 43.5 44 44.5 45 45.5 46 46.5 47 47.5 48 48.5 49 49.5 50 50.5 51 51.5 52 52.5 53 53.5 54 54.5 55 55.5 56 56.5 57 57.5 58 58.5 59 59.5 60 60.5 61 61.5 62 62.5 63 63.5 64 64.5 65 65.5 66 + 66.5 67 67.5 68 68.5 69 69.5 70 70.5 71 71.5 72 72.5 73 73.5 74 74.5 75 75.5 76 76.5 77 77.5 78 78.5 79 79.5 80 80.5 81 81.5 82 82.5 83 83.5 84 84.5 85 85.5 86 86.5 87 87.5 88 88.5 89 89.5 90 +0 +9769.798 9766.099 9733.675 9662.947 9575.834 9442.665 9280.229 9118.304 8886.575 8613.292 8341.374 7954.059 7478.424 7037.077 6451.128 5813.887 5183.818 4670.251 4124.621 3645.885 3310.188 2945.517 2631.518 2403.866 2164.416 1958.844 1816.224 1663.451 +1524.167 1419.652 1306.115 1202.535 1115.449 1047.913 981.195 921.649 876.95 831.168 790.026 760.98 730.924 706.114 687.086 667.788 650.355 637.35 624.922 614.813 604.786 598.047 591.914 586.282 582.085 577.621 574.641 572.333 569.62 567.557 565.539 +563.204 559.745 553.524 544.477 534.858 527.80 521.81 511.364 498.373 483.43 463.707 439.765 418.717 389.445 360.335 336.512 304.879 270.151 238.945 213.729 181.877 150.681 128.811 105.391 82.645 66.833 52.248 42.075 37.054 34.538 33.947 33.94 34.272 +34.798 35.093 35.396 35.972 36.688 37.212 38.144 38.89 40.057 40.797 41.463 40.917 39.831 37.592 34.888 32.145 28.847 25.431 22.88 20.927 19.271 18.25 17.761 17.155 16.807 16.327 16.267 15.817 15.558 14.90 14.597 14.109 13.879 13.68 13.192 13.221 12.815 +12.386 12.512 12.193 12.364 11.876 11.735 11.684 11.387 11.248 11.307 11.121 10.967 10.93 10.766 10.818 10.663 10.766 10.522 10.745 10.486 10.56 10.308 10.079 10.064 9.99 9.813 9.724 9.354 9.303 9.111 8.586 8.408 8.061 7.779 7.129 6.693 6.123 5.287 4.541 +3.646 3.513 2.833 2.678 2.33 1.916 1.709 1.178 0.814 0.502 0.396 0.059 0.00 diff --git a/examples/ies/README.md b/examples/ies/README.md new file mode 100644 index 00000000000000..66ba6d89e4c8b4 --- /dev/null +++ b/examples/ies/README.md @@ -0,0 +1,3 @@ +Profiles from the [IES Library](https://ieslibrary.com/en/home) website. + +New profiles can be created via [CNDL](https://cndl.io/). diff --git a/examples/index.html b/examples/index.html index 6c1a11cdc57ab3..b1fc84f264bae6 100644 --- a/examples/index.html +++ b/examples/index.html @@ -29,7 +29,7 @@

          three.js

          -
          +
          @@ -49,7 +49,7 @@

          three.js

          const content = document.getElementById( 'content' ); const viewer = document.getElementById( 'viewer' ); const filterInput = document.getElementById( 'filterInput' ); - const exitSearchButton = document.getElementById( 'exitSearchButton' ); + const clearSearchButton = document.getElementById( 'clearSearchButton' ); const expandButton = document.getElementById( 'expandButton' ); const viewSrcButton = document.getElementById( 'button' ); const panelScrim = document.getElementById( 'panelScrim' ); @@ -77,18 +77,18 @@

          three.js

          for ( const key in files ) { - const section = files[ key ]; + const category = files[ key ]; const header = document.createElement( 'h2' ); header.textContent = key; header.setAttribute( 'data-category', key ); container.appendChild( header ); - for ( let i = 0; i < section.length; i ++ ) { + for ( let i = 0; i < category.length; i ++ ) { - const file = section[ i ]; + const file = category[ i ]; - const link = createLink( file ); + const link = createLink( file, tags[ file ] ); container.appendChild( link ); links[ file ] = link; @@ -153,11 +153,11 @@

          three.js

          }; - exitSearchButton.onclick = function ( ) { + clearSearchButton.onclick = function ( ) { filterInput.value = ''; updateFilter( files, tags ); - panel.classList.remove( 'searchFocused' ); + filterInput.focus(); }; @@ -201,15 +201,17 @@

          three.js

          } - function createLink( file ) { + function createLink( file, tags ) { + + const external = Array.isArray( tags ) && tags.includes( 'external' ) ? ' external' : ''; const template = ` `; @@ -310,27 +312,16 @@

          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 ) { link.classList.remove( 'hidden' ); - for ( let i = 0; i < res.length; i ++ ) { - - text = name.replace( res[ i ], '' + res[ i ] + '' ); - - } - - link.querySelector( '.title' ).innerHTML = text; - } else { link.classList.add( 'hidden' ); - link.querySelector( '.title' ).innerHTML = name; } diff --git a/examples/js/animation/AnimationClipCreator.js b/examples/js/animation/AnimationClipCreator.js deleted file mode 100644 index dc399c51c75afc..00000000000000 --- a/examples/js/animation/AnimationClipCreator.js +++ /dev/null @@ -1,97 +0,0 @@ -( function () { - - class AnimationClipCreator { - - static CreateRotationAnimation( period, axis = 'x' ) { - - const times = [ 0, period ], - values = [ 0, 360 ]; - const trackName = '.rotation[' + axis + ']'; - const track = new THREE.NumberKeyframeTrack( trackName, times, values ); - return new THREE.AnimationClip( null, period, [ track ] ); - - } - - static CreateScaleAxisAnimation( period, axis = 'x' ) { - - const times = [ 0, period ], - values = [ 0, 1 ]; - const trackName = '.scale[' + axis + ']'; - const track = new THREE.NumberKeyframeTrack( trackName, times, values ); - 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 ); - tmp.set( Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0 ).multiply( shakeScale ).toArray( values, values.length ); - - } - - const trackName = '.position'; - const track = new THREE.VectorKeyframeTrack( trackName, times, values ); - 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 ); - const scaleFactor = Math.random() * pulseScale; - tmp.set( scaleFactor, scaleFactor, scaleFactor ).toArray( values, values.length ); - - } - - const trackName = '.scale'; - const track = new THREE.VectorKeyframeTrack( trackName, times, values ); - return new THREE.AnimationClip( null, duration, [ track ] ); - - } - - static CreateVisibilityAnimation( duration ) { - - const times = [ 0, duration / 2, duration ], - values = [ true, false, true ]; - const trackName = '.visible'; - const track = new THREE.BooleanKeyframeTrack( trackName, times, values ); - 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 ); - values.push( colors[ i % colors.length ] ); - - } - - const trackName = '.material[0].color'; - const track = new THREE.ColorKeyframeTrack( trackName, times, values ); - return new THREE.AnimationClip( null, duration, [ track ] ); - - } - - } - - THREE.AnimationClipCreator = AnimationClipCreator; - -} )(); diff --git a/examples/js/animation/CCDIKSolver.js b/examples/js/animation/CCDIKSolver.js deleted file mode 100644 index c177b2b217ea8a..00000000000000 --- a/examples/js/animation/CCDIKSolver.js +++ /dev/null @@ -1,433 +0,0 @@ -( 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 - * - * // ik parameter example - * // - * // target, effector, index in links are bone index in skeleton.bones. - * // the bones relation should be - * // <-- parent child --> - * // links[ n ], links[ n - 1 ], ..., links[ 0 ], effector - * iks = [ { - * target: 1, - * effector: 2, - * links: [ { index: 5, limitation: new THREE.Vector3( 1, 0, 0 ) }, { index: 4, enabled: false }, { index : 3 } ], - * iteration: 10, - * minAngle: 0.0, - * maxAngle: 1.0, - * } ]; - */ - - - class CCDIKSolver { - - /** - * @param {THREE.SkinnedMesh} mesh - * @param {Array} iks - */ - constructor( mesh, iks = [] ) { - - 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 ] ); - - } - - 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 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. - - _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. - - 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. - - link.matrixWorld.decompose( _linkPos, _invLinkQ, _linkScale ); - - _invLinkQ.invert(); - - _effectorPos.setFromMatrixPosition( effector.matrixWorld ); // 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; - - } else if ( angle < - 1.0 ) { - - angle = - 1.0; - - } - - 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; - - } - - if ( ik.maxAngle !== undefined && angle > ik.maxAngle ) { - - angle = ik.maxAngle; - - } - - _axis.crossVectors( _effectorVec, _targetVec ); - - _axis.normalize(); - - _q.setFromAxisAngle( _axis, angle ); - - link.quaternion.multiply( _q ); // TODO: re-consider the limitation specification - - if ( limitation !== undefined ) { - - let c = link.quaternion.w; - if ( c > 1.0 ) c = 1.0; - const c2 = math.sqrt( 1 - c * c ); - link.quaternion.set( limitation.x * c2, limitation.y * c2, limitation.z * c2, c ); - - } - - if ( rotationMin !== undefined ) { - - link.rotation.setFromVector3( _vector.setFromEuler( link.rotation ).max( rotationMin ) ); - - } - - if ( rotationMax !== undefined ) { - - link.rotation.setFromVector3( _vector.setFromEuler( link.rotation ).min( rotationMax ) ); - - } - - link.updateMatrixWorld( true ); - rotated = true; - - } - - if ( ! rotated ) break; - - } - - return this; - - } - /** - * Creates Helper - * - * @return {CCDIKHelper} - */ - - - createHelper() { - - return new CCDIKHelper( this.mesh, this.mesh.geometry.userData.MMD.iks ); - - } // 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 ]; - const effector = bones[ ik.effector ]; - 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 ); - - } - - link0 = link1; - - } - - } - - } - - } - - function getPosition( bone, matrixWorldInv ) { - - return _vector.setFromMatrixPosition( bone.matrixWorld ).applyMatrix4( matrixWorldInv ); - - } - - function setPositionOfBoneToAttributeArray( array, index, bone, matrixWorldInv ) { - - const v = getPosition( bone, matrixWorldInv ); - array[ index * 3 + 0 ] = v.x; - array[ index * 3 + 1 ] = v.y; - array[ index * 3 + 2 ] = v.z; - - } - /** - * Visualize IK bones - * - * @param {SkinnedMesh} mesh - * @param {Array} iks - */ - - - class CCDIKHelper extends THREE.Object3D { - - constructor( mesh, iks = [] ) { - - 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.targetSphereMaterial = new THREE.MeshBasicMaterial( { - color: new THREE.Color( 0xff8888 ), - depthTest: false, - depthWrite: false, - transparent: true - } ); - this.effectorSphereMaterial = new THREE.MeshBasicMaterial( { - color: new THREE.Color( 0x88ff88 ), - depthTest: false, - depthWrite: false, - transparent: true - } ); - this.linkSphereMaterial = new THREE.MeshBasicMaterial( { - color: new THREE.Color( 0x8888ff ), - depthTest: false, - depthWrite: false, - transparent: true - } ); - this.lineMaterial = new THREE.LineBasicMaterial( { - color: new THREE.Color( 0xff0000 ), - depthTest: false, - 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 ]; - const targetBone = bones[ ik.target ]; - const effectorBone = bones[ ik.effector ]; - const targetMesh = this.children[ offset ++ ]; - 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 ]; - const linkBone = bones[ link.index ]; - const linkMesh = this.children[ offset ++ ]; - linkMesh.position.copy( getPosition( linkBone, _matrix ) ); - - } - - const line = this.children[ offset ++ ]; - 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 ]; - const linkBone = bones[ link.index ]; - setPositionOfBoneToAttributeArray( array, j + 2, linkBone, _matrix ); - - } - - line.geometry.attributes.position.needsUpdate = true; - - } - - } - - this.matrix.copy( mesh.matrixWorld ); - super.updateMatrixWorld( force ); - - } // private method - - - _init() { - - const scope = this; - const iks = this.iks; - - function createLineGeometry( ik ) { - - const geometry = new THREE.BufferGeometry(); - const vertices = new Float32Array( ( 2 + ik.links.length ) * 3 ); - geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - return geometry; - - } - - function createTargetMesh() { - - return new THREE.Mesh( scope.sphereGeometry, scope.targetSphereMaterial ); - - } - - function createEffectorMesh() { - - return new THREE.Mesh( scope.sphereGeometry, scope.effectorSphereMaterial ); - - } - - function createLinkMesh() { - - return new THREE.Mesh( scope.sphereGeometry, scope.linkSphereMaterial ); - - } - - function createLine( ik ) { - - return new THREE.Line( createLineGeometry( ik ), scope.lineMaterial ); - - } - - for ( let i = 0, il = iks.length; i < il; i ++ ) { - - const ik = iks[ i ]; - this.add( createTargetMesh() ); - this.add( createEffectorMesh() ); - - for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) { - - this.add( createLinkMesh() ); - - } - - this.add( createLine( ik ) ); - - } - - } - - } - - THREE.CCDIKHelper = CCDIKHelper; - THREE.CCDIKSolver = CCDIKSolver; - -} )(); diff --git a/examples/js/animation/MMDAnimationHelper.js b/examples/js/animation/MMDAnimationHelper.js deleted file mode 100644 index 181e436e61cb14..00000000000000 --- a/examples/js/animation/MMDAnimationHelper.js +++ /dev/null @@ -1,1117 +0,0 @@ -( function () { - - /** - * MMDAnimationHelper handles animation of MMD assets loaded by MMDLoader - * with MMD special features as IK, Grant, and Physics. - * - * Dependencies - * - ammo.js https://github.com/kripken/ammo.js - * - THREE.MMDPhysics - * - THREE.CCDIKSolver - * - * TODO - * - more precise grant skinning support. - */ - - class MMDAnimationHelper { - - /** - * @param {Object} params - (optional) - * @param {boolean} params.sync - Whether animation durations of added objects are synched. Default is true. - * @param {Number} params.afterglow - Default is 0.0. - * @param {boolean} params.resetPhysicsOnLoop - Default is true. - */ - constructor( params = {} ) { - - this.meshes = []; - this.camera = null; - this.cameraTarget = new THREE.Object3D(); - this.cameraTarget.name = 'target'; - this.audio = null; - this.audioManager = null; - this.objects = new WeakMap(); - this.configuration = { - sync: params.sync !== undefined ? params.sync : true, - afterglow: params.afterglow !== undefined ? params.afterglow : 0.0, - resetPhysicsOnLoop: params.resetPhysicsOnLoop !== undefined ? params.resetPhysicsOnLoop : true, - pmxAnimation: params.pmxAnimation !== undefined ? params.pmxAnimation : false - }; - this.enabled = { - animation: true, - ik: true, - grant: true, - physics: true, - cameraAnimation: true - }; - - this.onBeforePhysics = function - /* mesh */ - () {}; // 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 - * if this.configuration.sync is true. - * - * @param {THREE.SkinnedMesh|THREE.Camera|THREE.Audio} object - * @param {Object} params - (optional) - * @param {THREE.AnimationClip|Array} params.animation - Only for THREE.SkinnedMesh and THREE.Camera. Default is undefined. - * @param {boolean} params.physics - Only for THREE.SkinnedMesh. Default is true. - * @param {Integer} params.warmup - Only for THREE.SkinnedMesh and physics is true. Default is 60. - * @param {Number} params.unitStep - Only for THREE.SkinnedMesh and physics is true. Default is 1 / 65. - * @param {Integer} params.maxStepNum - Only for THREE.SkinnedMesh and physics is true. Default is 3. - * @param {Vector3} params.gravity - Only for THREE.SkinnedMesh and physics is true. Default ( 0, - 9.8 * 10, 0 ). - * @param {Number} params.delayTime - Only for THREE.Audio. Default is 0.0. - * @return {MMDAnimationHelper} - */ - - - add( object, params = {} ) { - - if ( object.isSkinnedMesh ) { - - this._addMesh( object, params ); - - } else if ( object.isCamera ) { - - this._setupCamera( object, params ); - - } else if ( object.type === 'Audio' ) { - - this._setupAudio( object, params ); - - } else { - - throw new Error( 'THREE.MMDAnimationHelper.add: ' + 'accepts only ' + 'THREE.SkinnedMesh or ' + 'THREE.Camera or ' + 'THREE.Audio instance.' ); - - } - - if ( this.configuration.sync ) this._syncDuration(); - return this; - - } - /** - * Removes an Three.js Object from helper. - * - * @param {THREE.SkinnedMesh|THREE.Camera|THREE.Audio} object - * @return {MMDAnimationHelper} - */ - - - remove( object ) { - - if ( object.isSkinnedMesh ) { - - this._removeMesh( object ); - - } else if ( object.isCamera ) { - - this._clearCamera( object ); - - } else if ( object.type === 'Audio' ) { - - this._clearAudio( object ); - - } else { - - throw new Error( 'THREE.MMDAnimationHelper.remove: ' + 'accepts only ' + 'THREE.SkinnedMesh or ' + 'THREE.Camera or ' + 'THREE.Audio instance.' ); - - } - - if ( this.configuration.sync ) this._syncDuration(); - 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 ); - - } - - if ( this.sharedPhysics ) this._updateSharedPhysics( delta ); - if ( this.camera !== null ) this._animateCamera( this.camera, delta ); - return this; - - } - /** - * Changes the pose of SkinnedMesh as VPD specifies. - * - * @param {THREE.SkinnedMesh} mesh - * @param {Object} vpd - VPD content parsed MMDParser - * @param {Object} params - (optional) - * @param {boolean} params.resetPose - Default is true. - * @param {boolean} params.ik - Default is true. - * @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; - - } - - const vector = new THREE.Vector3(); - const quaternion = new THREE.Quaternion(); - - for ( let i = 0, il = boneParams.length; i < il; i ++ ) { - - const boneParam = boneParams[ i ]; - const boneIndex = boneNameDictionary[ boneParam.name ]; - if ( boneIndex === undefined ) continue; - const bone = bones[ boneIndex ]; - bone.position.add( vector.fromArray( boneParam.translation ) ); - bone.quaternion.multiply( quaternion.fromArray( boneParam.quaternion ) ); - - } - - 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 { - - if ( params.ik !== false ) { - - this._createCCDIKSolver( mesh ).update(); - - } - - if ( params.grant !== false ) { - - this.createGrantSolver( mesh ).update(); - - } - - } - - return this; - - } - /** - * Enabes/Disables an animation feature. - * - * @param {string} key - * @param {boolean} enabled - * @return {MMDAnimationHelper} - */ - - - enable( key, enabled ) { - - if ( this.enabled[ key ] === undefined ) { - - throw new Error( 'THREE.MMDAnimationHelper.enable: ' + 'unknown key ' + key ); - - } - - this.enabled[ key ] = enabled; - - if ( key === 'physics' ) { - - for ( let i = 0, il = this.meshes.length; i < il; i ++ ) { - - this._optimizeIK( this.meshes[ i ], enabled ); - - } - - } - - 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 - - - _addMesh( mesh, params ) { - - if ( this.meshes.indexOf( mesh ) >= 0 ) { - - throw new Error( 'THREE.MMDAnimationHelper._addMesh: ' + 'SkinnedMesh \'' + mesh.name + '\' has already been added.' ); - - } - - this.meshes.push( mesh ); - this.objects.set( mesh, { - looped: false - } ); - - this._setupMeshAnimation( mesh, params.animation ); - - if ( params.physics !== false ) { - - this._setupMeshPhysics( mesh, params ); - - } - - return this; - - } - - _setupCamera( camera, params ) { - - if ( this.camera === camera ) { - - throw new Error( 'THREE.MMDAnimationHelper._setupCamera: ' + 'Camera \'' + camera.name + '\' has already been set.' ); - - } - - if ( this.camera ) this.clearCamera( this.camera ); - this.camera = camera; - camera.add( this.cameraTarget ); - this.objects.set( camera, {} ); - - if ( params.animation !== undefined ) { - - this._setupCameraAnimation( camera, params.animation ); - - } - - return this; - - } - - _setupAudio( audio, params ) { - - if ( this.audio === audio ) { - - throw new Error( 'THREE.MMDAnimationHelper._setupAudio: ' + 'Audio \'' + audio.name + '\' has already been set.' ); - - } - - if ( this.audio ) this.clearAudio( this.audio ); - this.audio = audio; - this.audioManager = new AudioManager( audio, params ); - this.objects.set( this.audioManager, { - duration: this.audioManager.duration - } ); - 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 ) { - - this.objects.delete( mesh ); - found = true; - continue; - - } - - this.meshes[ writeIndex ++ ] = this.meshes[ i ]; - - } - - if ( ! found ) { - - throw new Error( 'THREE.MMDAnimationHelper._removeMesh: ' + 'SkinnedMesh \'' + mesh.name + '\' has not been added yet.' ); - - } - - this.meshes.length = writeIndex; - return this; - - } - - _clearCamera( camera ) { - - if ( camera !== this.camera ) { - - throw new Error( 'THREE.MMDAnimationHelper._clearCamera: ' + 'Camera \'' + camera.name + '\' has not been set yet.' ); - - } - - this.camera.remove( this.cameraTarget ); - this.objects.delete( this.camera ); - this.camera = null; - return this; - - } - - _clearAudio( audio ) { - - if ( audio !== this.audio ) { - - throw new Error( 'THREE.MMDAnimationHelper._clearAudio: ' + 'Audio \'' + audio.name + '\' has not been set yet.' ); - - } - - this.objects.delete( this.audioManager ); - this.audio = null; - this.audioManager = null; - 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 - - - objects.mixer.addEventListener( 'loop', function ( event ) { - - const tracks = event.action._clip.tracks; - if ( tracks.length > 0 && tracks[ 0 ].name.slice( 0, 6 ) !== '.bones' ) return; - objects.looped = true; - - } ); - - } - - objects.ikSolver = this._createCCDIKSolver( mesh ); - objects.grantSolver = this.createGrantSolver( mesh ); - 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(); - - } - - } - - _setupMeshPhysics( mesh, params ) { - - 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 ); - const mixer = objects.mixer; - const ikSolver = objects.ikSolver; - 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 ); - - mixer.update( delta ); - - this._saveBones( mesh ); // 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 { - - if ( ikSolver && this.enabled.ik ) { - - mesh.updateMatrixWorld( true ); - ikSolver.update(); - - } - - if ( grantSolver && this.enabled.grant ) { - - grantSolver.update(); - - } - - } - - } - - if ( looped === true && this.enabled.physics ) { - - if ( physics && this.configuration.resetPhysicsOnLoop ) physics.reset(); - objects.looped = false; - - } - - if ( physics && this.enabled.physics && ! this.sharedPhysics ) { - - this.onBeforePhysics( mesh ); - physics.update( delta ); - - } - - } // 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 ) { - - if ( a.transformationClass !== b.transformationClass ) { - - return a.transformationClass - b.transformationClass; - - } else { - - return a.index - b.index; - - } - - } ); - - } // 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 ); - - } - - mesh.updateMatrixWorld( true ); - return this; - - } - - _animateCamera( camera, delta ) { - - const mixer = this.objects.get( camera ).mixer; - - if ( mixer && this.enabled.cameraAnimation ) { - - mixer.update( delta ); - camera.updateProjectionMatrix(); - camera.up.set( 0, 1, 0 ); - camera.up.applyQuaternion( camera.quaternion ); - camera.lookAt( this.cameraTarget.position ); - - } - - } - - _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 - // because its rotation will be overriden by physics - link.enabled = bones[ link.index ].rigidBodyType > 0 ? false : true; - - } else { - - link.enabled = true; - - } - - } - - } - - } - - _createCCDIKSolver( mesh ) { - - if ( THREE.CCDIKSolver === undefined ) { - - throw new Error( 'THREE.MMDAnimationHelper: Import THREE.CCDIKSolver.' ); - - } - - return new THREE.CCDIKSolver( mesh, mesh.geometry.userData.MMD.iks ); - - } - - _createMMDPhysics( mesh, params ) { - - if ( THREE.MMDPhysics === undefined ) { - - throw new Error( 'THREE.MMDPhysics: Import THREE.MMDPhysics.' ); - - } - - 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 - - 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, { - duration: clip.duration - } ); - - } - - max = Math.max( max, objects.get( clip ).duration ); - - } - - } - - 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, { - duration: clip.duration - } ); - - } - - max = Math.max( max, objects.get( clip ).duration ); - - } - - } - - } - - if ( audioManager !== null ) { - - max = Math.max( max, objects.get( audioManager ).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; - - } - - } - - if ( camera !== null ) { - - const mixer = this.objects.get( camera ).mixer; - - if ( mixer !== undefined ) { - - for ( let i = 0, il = mixer._actions.length; i < il; i ++ ) { - - mixer._actions[ i ]._clip.duration = max; - - } - - } - - } - - if ( audioManager !== null ) { - - audioManager.duration = max; - - } - - } // 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 ]; - const buffer = propertyMixer.buffer; - const stride = propertyMixer.valueSize; - const offset = ( accuIndex + 1 ) * stride; - propertyMixer.binding.getValue( buffer, offset ); - - } - - } - /* - * Avoiding these two issues by restore/save bones before/after mixer animation. - * - * 1. PropertyMixer used by THREE.AnimationMixer holds cache value in .buffer. - * Calculating IK, Grant, and Physics after mixer animation can break - * the cache coherency. - * - * 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 ); - objects.backupBones = backupBones; - - } - - for ( let i = 0, il = bones.length; i < il; i ++ ) { - - const bone = bones[ i ]; - bone.position.toArray( backupBones, i * 7 ); - bone.quaternion.toArray( backupBones, i * 7 + 3 ); - - } - - } - - _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 ]; - bone.position.fromArray( backupBones, i * 7 ); - bone.quaternion.fromArray( backupBones, i * 7 + 3 ); - - } - - } // 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; - return this.masterPhysics; - - } - - } - - 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(); - - } - - } - - 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(); - - } - - } - - } - - } // Keep working quaternions for less GC - - - const _quaternions = []; - let _quaternionIndex = 0; - - function getQuaternion() { - - if ( _quaternionIndex >= _quaternions.length ) { - - _quaternions.push( new THREE.Quaternion() ); - - } - - return _quaternions[ _quaternionIndex ++ ]; - - } // 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. - - if ( _grantResultMap.has( boneIndex ) ) return; - 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 ) ); // @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 ); - - } - - grantSolver.addGrantRotation( bone, _grantResultMap.get( parentIndex ), ratio ); - - } - - if ( ikSolver && boneData.ik ) { - - // @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? - - 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 ) ); - - } - - } - - } // Update with the actual result here - - - quaternion.copy( bone.quaternion ); - - } // - - - class AudioManager { - - /** - * @param {THREE.Audio} audio - * @param {Object} params - (optional) - * @param {Nuumber} params.delayTime - */ - constructor( audio, params = {} ) { - - this.audio = audio; - this.elapsedTime = 0.0; - this.currentTime = 0.0; - this.delayTime = params.delayTime !== undefined ? params.delayTime : 0.0; - this.audioDuration = this.audio.buffer.duration; - this.duration = this.audioDuration + this.delayTime; - - } - /** - * @param {Number} delta - * @return {AudioManager} - */ - - - control( delta ) { - - this.elapsed += delta; - this.currentTime += delta; - if ( this._shouldStopAudio() ) this.audio.stop(); - if ( this._shouldStartAudio() ) this.audio.play(); - return this; - - } // 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 > this.audioDuration ) return false; - return true; - - } - - _shouldStopAudio() { - - return this.audio.isPlaying && this.currentTime >= this.duration; - - } - - } - - 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.) - * Grant propagates a bone's transform to other bones transforms even if - * they are not children. - * @param {THREE.SkinnedMesh} mesh - * @param {Array} grants - */ - - - class GrantSolver { - - constructor( mesh, grants = [] ) { - - this.mesh = mesh; - 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 ] ); - - } - - 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.affectRotation ) {} - - } else { - - // TODO: implement - if ( grant.affectPosition ) {} - - if ( grant.affectRotation ) { - - this.addGrantRotation( bone, parentBone.quaternion, grant.ratio ); - - } - - } - - return this; - - } - - addGrantRotation( bone, q, ratio ) { - - _q.set( 0, 0, 0, 1 ); - - _q.slerp( q, ratio ); - - bone.quaternion.multiply( _q ); - return this; - - } - - } - - THREE.MMDAnimationHelper = MMDAnimationHelper; - -} )(); diff --git a/examples/js/animation/MMDPhysics.js b/examples/js/animation/MMDPhysics.js deleted file mode 100644 index a7a293b351718c..00000000000000 --- a/examples/js/animation/MMDPhysics.js +++ /dev/null @@ -1,1253 +0,0 @@ -( function () { - - /** - * Dependencies - * - Ammo.js https://github.com/kripken/ammo.js - * - * MMDPhysics calculates physics with Ammo(Bullet based JavaScript Physics engine) - * for MMD model loaded by MMDLoader. - * - * TODO - * - Physics in Worker - */ - - /* global Ammo */ - - class MMDPhysics { - - /** - * @param {THREE.SkinnedMesh} mesh - * @param {Array} rigidBodyParams - * @param {Array} (optional) constraintParams - * @param {Object} params - (optional) - * @param {Number} params.unitStep - Default is 1 / 65. - * @param {Integer} params.maxStepNum - Default is 3. - * @param {Vector3} params.gravity - Default is ( 0, - 9.8 * 10, 0 ) - */ - constructor( mesh, rigidBodyParams, constraintParams = [], params = {} ) { - - if ( typeof Ammo === 'undefined' ) { - - throw new Error( 'THREE.MMDPhysics: Import ammo.js https://github.com/kripken/ammo.js' ); - - } - - 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 ); - if ( params.gravity !== undefined ) this.gravity.copy( params.gravity ); - this.world = params.world !== undefined ? params.world : null; // experimental - - 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 - // mesh's world scale (1, 1, 1). - // Convert to (1, 1, 1) if it isn't. - - let isNonDefaultScale = false; - const position = manager.allocThreeVector3(); - 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; - - } - - let parent; - - if ( isNonDefaultScale ) { - - parent = mesh.parent; - if ( parent !== null ) mesh.parent = null; - scale.copy( this.mesh.scale ); - mesh.scale.set( 1, 1, 1 ); - mesh.updateMatrixWorld( true ); - - } // calculate physics and update bones - - - this._updateRigidBodies(); - - this._stepSimulation( delta ); - - this._updateBones(); // restore mesh if converted above - - - if ( isNonDefaultScale ) { - - if ( parent !== null ) mesh.parent = parent; - mesh.scale.copy( scale ); - - } - - manager.freeThreeVector3( scale ); - manager.freeThreeQuaternion( quaternion ); - manager.freeThreeVector3( position ); - return this; - - } - /** - * Resets rigid bodies transorm to current bone's. - * - * @return {MMDPhysics} - */ - - - reset() { - - for ( let i = 0, il = this.bodies.length; i < il; i ++ ) { - - this.bodies[ i ].reset(); - - } - - return this; - - } - /** - * Warm ups Rigid bodies. Calculates cycles steps. - * - * @param {Integer} cycles - * @return {MMDPhysics} - */ - - - warmup( cycles ) { - - for ( let i = 0; i < cycles; i ++ ) { - - this.update( 1 / 60 ); - - } - - return this; - - } - /** - * Sets gravity. - * - * @param {Vector3} gravity - * @return {MMDPhysicsHelper} - */ - - - setGravity( gravity ) { - - this.world.setGravity( new Ammo.btVector3( gravity.x, gravity.y, gravity.z ) ); - this.gravity.copy( gravity ); - return this; - - } - /** - * Creates MMDPhysicsHelper - * - * @return {MMDPhysicsHelper} - */ - - - createHelper() { - - return new MMDPhysicsHelper( this.mesh, this ); - - } // private methods - - - _init( mesh, rigidBodyParams, constraintParams ) { - - 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) - - const parent = mesh.parent; - if ( parent !== null ) mesh.parent = null; - const currentPosition = manager.allocThreeVector3(); - const currentQuaternion = manager.allocThreeQuaternion(); - const currentScale = manager.allocThreeVector3(); - currentPosition.copy( mesh.position ); - currentQuaternion.copy( mesh.quaternion ); - currentScale.copy( mesh.scale ); - mesh.position.set( 0, 0, 0 ); - mesh.quaternion.set( 0, 0, 0, 1 ); - mesh.scale.set( 1, 1, 1 ); - mesh.updateMatrixWorld( true ); - - if ( this.world === null ) { - - this.world = this._createWorld(); - this.setGravity( this.gravity ); - - } - - this._initRigidBodies( rigidBodyParams ); - - this._initConstraints( constraintParams ); - - if ( parent !== null ) mesh.parent = parent; - mesh.position.copy( currentPosition ); - mesh.quaternion.copy( currentQuaternion ); - mesh.scale.copy( currentScale ); - mesh.updateMatrixWorld( true ); - this.reset(); - manager.freeThreeVector3( currentPosition ); - manager.freeThreeQuaternion( currentQuaternion ); - manager.freeThreeVector3( currentScale ); - - } - - _createWorld() { - - const config = new Ammo.btDefaultCollisionConfiguration(); - const dispatcher = new Ammo.btCollisionDispatcher( config ); - const cache = new Ammo.btDbvtBroadphase(); - const solver = new Ammo.btSequentialImpulseConstraintSolver(); - const world = new Ammo.btDiscreteDynamicsWorld( dispatcher, cache, solver, config ); - return world; - - } - - _initRigidBodies( rigidBodies ) { - - for ( let i = 0, il = rigidBodies.length; i < il; i ++ ) { - - this.bodies.push( new RigidBody( this.mesh, this.world, rigidBodies[ i ], this.manager ) ); - - } - - } - - _initConstraints( constraints ) { - - for ( let i = 0, il = constraints.length; i < il; i ++ ) { - - const params = constraints[ i ]; - const bodyA = this.bodies[ params.rigidBodyIndex1 ]; - const bodyB = this.bodies[ params.rigidBodyIndex2 ]; - this.constraints.push( new Constraint( this.mesh, this.world, bodyA, bodyB, params, this.manager ) ); - - } - - } - - _stepSimulation( delta ) { - - const unitStep = this.unitStep; - let stepTime = delta; - let maxStepNum = ( delta / unitStep | 0 ) + 1; - - if ( stepTime < unitStep ) { - - stepTime = unitStep; - maxStepNum = 1; - - } - - if ( maxStepNum > this.maxStepNum ) { - - maxStepNum = this.maxStepNum; - - } - - this.world.stepSimulation( stepTime, maxStepNum, unitStep ); - - } - - _updateRigidBodies() { - - for ( let i = 0, il = this.bodies.length; i < il; i ++ ) { - - this.bodies[ i ].updateFromBone(); - - } - - } - - _updateBones() { - - for ( let i = 0, il = this.bodies.length; i < il; i ++ ) { - - this.bodies[ i ].updateBone(); - - } - - } - - } - /** - * This manager's responsibilies are - * - * 1. manage Ammo.js and Three.js object resources and - * improve the performance and the memory consumption by - * reusing objects. - * - * 2. provide simple Ammo object operations. - */ - - - class ResourceManager { - - constructor() { - - // for Three.js - this.threeVector3s = []; - this.threeMatrix4s = []; - this.threeQuaternions = []; - 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(); - t.getBasis().getRotation( q ); - return q; - - } - - getBasisAsMatrix3( t ) { - - var q = this.getBasis( t ); - var m = this.quaternionToMatrix3( q ); - this.freeQuaternion( q ); - 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 ); - this.setBasis( t, q ); - 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(); - var thE = this.allocThreeEuler(); - thE.set( a[ 0 ], a[ 1 ], a[ 2 ] ); - this.setBasisFromThreeQuaternion( t, thQ.setFromEuler( thE ) ); - this.freeThreeEuler( thE ); - this.freeThreeQuaternion( thQ ); - - } - - setBasisFromThreeQuaternion( t, a ) { - - var q = this.allocQuaternion(); - q.setX( a.x ); - q.setY( a.y ); - q.setZ( a.z ); - q.setW( a.w ); - this.setBasis( t, q ); - this.freeQuaternion( q ); - - } - - multiplyTransforms( t1, t2 ) { - - var t = this.allocTransform(); - this.setIdentity( t ); - var m1 = this.getBasisAsMatrix3( t1 ); - var m2 = this.getBasisAsMatrix3( t2 ); - var o1 = this.getOrigin( t1 ); - var o2 = this.getOrigin( t2 ); - var v1 = this.multiplyMatrix3ByVector3( m1, o2 ); - var v2 = this.addVector3( v1, o1 ); - this.setOrigin( t, v2 ); - var m3 = this.multiplyMatrices3( m1, m2 ); - this.setBasisFromMatrix3( t, m3 ); - this.freeVector3( v1 ); - this.freeVector3( v2 ); - return t; - - } - - inverseTransform( t ) { - - var t2 = this.allocTransform(); - var m1 = this.getBasisAsMatrix3( t ); - var o = this.getOrigin( t ); - var m2 = this.transposeMatrix3( m1 ); - var v1 = this.negativeVector3( o ); - var v2 = this.multiplyMatrix3ByVector3( m2, v1 ); - this.setOrigin( t2, v2 ); - this.setBasisFromMatrix3( t2, m2 ); - this.freeVector3( v1 ); - this.freeVector3( v2 ); - return t2; - - } - - multiplyMatrices3( m1, m2 ) { - - var m3 = []; - var v10 = this.rowOfMatrix3( m1, 0 ); - var v11 = this.rowOfMatrix3( m1, 1 ); - var v12 = this.rowOfMatrix3( m1, 2 ); - var v20 = this.columnOfMatrix3( m2, 0 ); - var v21 = this.columnOfMatrix3( m2, 1 ); - var v22 = this.columnOfMatrix3( m2, 2 ); - m3[ 0 ] = this.dotVectors3( v10, v20 ); - m3[ 1 ] = this.dotVectors3( v10, v21 ); - m3[ 2 ] = this.dotVectors3( v10, v22 ); - m3[ 3 ] = this.dotVectors3( v11, v20 ); - m3[ 4 ] = this.dotVectors3( v11, v21 ); - m3[ 5 ] = this.dotVectors3( v11, v22 ); - m3[ 6 ] = this.dotVectors3( v12, v20 ); - m3[ 7 ] = this.dotVectors3( v12, v21 ); - m3[ 8 ] = this.dotVectors3( v12, v22 ); - this.freeVector3( v10 ); - this.freeVector3( v11 ); - this.freeVector3( v12 ); - this.freeVector3( v20 ); - this.freeVector3( v21 ); - this.freeVector3( v22 ); - return m3; - - } - - addVector3( v1, v2 ) { - - var v = this.allocVector3(); - v.setValue( v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z() ); - 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(); - v.setValue( m[ i * 3 + 0 ], m[ i * 3 + 1 ], m[ i * 3 + 2 ] ); - return v; - - } - - columnOfMatrix3( m, i ) { - - var v = this.allocVector3(); - v.setValue( m[ i + 0 ], m[ i + 3 ], m[ i + 6 ] ); - return v; - - } - - negativeVector3( v ) { - - var v2 = this.allocVector3(); - v2.setValue( - v.x(), - v.y(), - v.z() ); - return v2; - - } - - multiplyMatrix3ByVector3( m, v ) { - - var v4 = this.allocVector3(); - var v0 = this.rowOfMatrix3( m, 0 ); - var v1 = this.rowOfMatrix3( m, 1 ); - var v2 = this.rowOfMatrix3( m, 2 ); - var x = this.dotVectors3( v0, v ); - var y = this.dotVectors3( v1, v ); - var z = this.dotVectors3( v2, v ); - v4.setValue( x, y, z ); - this.freeVector3( v0 ); - this.freeVector3( v1 ); - this.freeVector3( v2 ); - return v4; - - } - - transposeMatrix3( m ) { - - var m2 = []; - m2[ 0 ] = m[ 0 ]; - m2[ 1 ] = m[ 3 ]; - m2[ 2 ] = m[ 6 ]; - m2[ 3 ] = m[ 1 ]; - m2[ 4 ] = m[ 4 ]; - m2[ 5 ] = m[ 7 ]; - m2[ 6 ] = m[ 2 ]; - m2[ 7 ] = m[ 5 ]; - m2[ 8 ] = m[ 8 ]; - return m2; - - } - - quaternionToMatrix3( q ) { - - var m = []; - var x = q.x(); - var y = q.y(); - var z = q.z(); - var w = q.w(); - var xx = x * x; - var yy = y * y; - var zz = z * z; - var xy = x * y; - var yz = y * z; - var zx = z * x; - var xw = x * w; - var yw = y * w; - var zw = z * w; - m[ 0 ] = 1 - 2 * ( yy + zz ); - m[ 1 ] = 2 * ( xy - zw ); - m[ 2 ] = 2 * ( zx + yw ); - m[ 3 ] = 2 * ( xy + zw ); - m[ 4 ] = 1 - 2 * ( zz + xx ); - m[ 5 ] = 2 * ( yz - xw ); - m[ 6 ] = 2 * ( zx - yw ); - m[ 7 ] = 2 * ( yz + xw ); - m[ 8 ] = 1 - 2 * ( xx + yy ); - 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; - w = 0.25 * s; - x = ( m[ 7 ] - m[ 5 ] ) / s; - y = ( m[ 2 ] - m[ 6 ] ) / s; - z = ( m[ 3 ] - m[ 1 ] ) / s; - - } else if ( m[ 0 ] > m[ 4 ] && m[ 0 ] > m[ 8 ] ) { - - s = Math.sqrt( 1.0 + m[ 0 ] - m[ 4 ] - m[ 8 ] ) * 2; - w = ( m[ 7 ] - m[ 5 ] ) / s; - x = 0.25 * s; - y = ( m[ 1 ] + m[ 3 ] ) / s; - z = ( m[ 2 ] + m[ 6 ] ) / s; - - } else if ( m[ 4 ] > m[ 8 ] ) { - - s = Math.sqrt( 1.0 + m[ 4 ] - m[ 0 ] - m[ 8 ] ) * 2; - w = ( m[ 2 ] - m[ 6 ] ) / s; - x = ( m[ 1 ] + m[ 3 ] ) / s; - y = 0.25 * s; - z = ( m[ 5 ] + m[ 7 ] ) / s; - - } else { - - s = Math.sqrt( 1.0 + m[ 8 ] - m[ 0 ] - m[ 4 ] ) * 2; - w = ( m[ 3 ] - m[ 1 ] ) / s; - x = ( m[ 2 ] + m[ 6 ] ) / s; - y = ( m[ 5 ] + m[ 7 ] ) / s; - z = 0.25 * s; - - } - - var q = this.allocQuaternion(); - q.setX( x ); - q.setY( y ); - q.setZ( z ); - q.setW( w ); - return q; - - } - - } - /** - * @param {THREE.SkinnedMesh} mesh - * @param {Ammo.btDiscreteDynamicsWorld} world - * @param {Object} params - * @param {ResourceManager} manager - */ - - - class RigidBody { - - constructor( mesh, world, params, manager ) { - - this.mesh = mesh; - this.world = world; - this.params = params; - this.manager = manager; - this.body = null; - 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 ) { - - this._setTransformFromBone(); - - } - - return this; - - } - /** - * Updates bone from the current ridid body's transform. - * - * @return {RidigBody} - */ - - - updateBone() { - - if ( this.params.type === 0 || this.params.boneIndex === - 1 ) { - - return this; - - } - - this._updateBoneRotation(); - - if ( this.params.type === 1 ) { - - this._updateBonePosition(); - - } - - this.bone.updateMatrixWorld( true ); - - if ( this.params.type === 2 ) { - - this._setPositionFromBone(); - - } - - return this; - - } // private methods - - - _init() { - - function generateShape( p ) { - - switch ( p.shapeType ) { - - 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 ); - - } - - } - - const manager = this.manager; - const params = this.params; - const bones = this.mesh.skeleton.bones; - const bone = params.boneIndex === - 1 ? new THREE.Bone() : bones[ params.boneIndex ]; - const shape = generateShape( params ); - const weight = params.type === 0 ? 0 : params.weight; - const localInertia = manager.allocVector3(); - localInertia.setValue( 0, 0, 0 ); - - if ( weight !== 0 ) { - - shape.calculateLocalInertia( weight, localInertia ); - - } - - const boneOffsetForm = manager.allocTransform(); - manager.setIdentity( boneOffsetForm ); - manager.setOriginFromArray3( boneOffsetForm, params.position ); - manager.setBasisFromArray3( boneOffsetForm, params.rotation ); - const vector = manager.allocThreeVector3(); - const boneForm = manager.allocTransform(); - manager.setIdentity( boneForm ); - manager.setOriginFromThreeVector3( boneForm, bone.getWorldPosition( vector ) ); - const form = manager.multiplyTransforms( boneForm, boneOffsetForm ); - const state = new Ammo.btDefaultMotionState( form ); - const info = new Ammo.btRigidBodyConstructionInfo( weight, state, shape, localInertia ); - 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 ); - - } - - body.setDamping( params.positionDamping, params.rotationDamping ); - body.setSleepingThresholds( 0, 0 ); - this.world.addRigidBody( body, 1 << params.groupIndex, params.groupTarget ); - this.body = body; - this.bone = bone; - this.boneOffsetForm = boneOffsetForm; - this.boneOffsetFormInverse = manager.inverseTransform( boneOffsetForm ); - manager.freeVector3( localInertia ); - manager.freeTransform( form ); - manager.freeTransform( boneForm ); - manager.freeThreeVector3( vector ); - - } - - _getBoneTransform() { - - const manager = this.manager; - const p = manager.allocThreeVector3(); - const q = manager.allocThreeQuaternion(); - const s = manager.allocThreeVector3(); - this.bone.matrixWorld.decompose( p, q, s ); - const tr = manager.allocTransform(); - manager.setOriginFromThreeVector3( tr, p ); - manager.setBasisFromThreeQuaternion( tr, q ); - const form = manager.multiplyTransforms( tr, this.boneOffsetForm ); - manager.freeTransform( tr ); - manager.freeThreeVector3( s ); - manager.freeThreeQuaternion( q ); - manager.freeThreeVector3( p ); - return form; - - } - - _getWorldTransformForBone() { - - const manager = this.manager; - const tr = this.body.getCenterOfMassTransform(); - return manager.multiplyTransforms( tr, this.boneOffsetFormInverse ); - - } - - _setTransformFromBone() { - - const manager = this.manager; - - const form = this._getBoneTransform(); // 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 ); - - 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(); - const thQ3 = manager.allocThreeQuaternion(); - 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 ); - - 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 ); - manager.freeThreeQuaternion( thQ3 ); - manager.freeQuaternion( q ); - 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 ); - - } - - this.bone.position.copy( thV ); - manager.freeThreeVector3( thV ); - manager.freeTransform( tr ); - - } - - } // - - - class Constraint { - - /** - * @param {THREE.SkinnedMesh} mesh - * @param {Ammo.btDiscreteDynamicsWorld} world - * @param {RigidBody} bodyA - * @param {RigidBody} bodyB - * @param {Object} params - * @param {ResourceManager} manager - */ - constructor( mesh, world, bodyA, bodyB, params, manager ) { - - this.mesh = mesh; - this.world = world; - this.bodyA = bodyA; - this.bodyB = bodyB; - this.params = params; - this.manager = manager; - this.constraint = null; - - this._init(); - - } // private method - - - _init() { - - const manager = this.manager; - const params = this.params; - const bodyA = this.bodyA; - const bodyB = this.bodyB; - const form = manager.allocTransform(); - manager.setIdentity( form ); - manager.setOriginFromArray3( form, params.position ); - manager.setBasisFromArray3( form, params.rotation ); - const formA = manager.allocTransform(); - const formB = manager.allocTransform(); - bodyA.body.getMotionState().getWorldTransform( formA ); - bodyB.body.getMotionState().getWorldTransform( formB ); - const formInverseA = manager.inverseTransform( formA ); - const formInverseB = manager.inverseTransform( formB ); - const formA2 = manager.multiplyTransforms( formInverseA, form ); - const formB2 = manager.multiplyTransforms( formInverseB, form ); - const constraint = new Ammo.btGeneric6DofSpringConstraint( bodyA.body, bodyB.body, formA2, formB2, true ); - const lll = manager.allocVector3(); - const lul = manager.allocVector3(); - const all = manager.allocVector3(); - const aul = manager.allocVector3(); - lll.setValue( params.translationLimitation1[ 0 ], params.translationLimitation1[ 1 ], params.translationLimitation1[ 2 ] ); - lul.setValue( params.translationLimitation2[ 0 ], params.translationLimitation2[ 1 ], params.translationLimitation2[ 2 ] ); - all.setValue( params.rotationLimitation1[ 0 ], params.rotationLimitation1[ 1 ], params.rotationLimitation1[ 2 ] ); - aul.setValue( params.rotationLimitation2[ 0 ], params.rotationLimitation2[ 1 ], params.rotationLimitation2[ 2 ] ); - constraint.setLinearLowerLimit( lll ); - constraint.setLinearUpperLimit( lul ); - constraint.setAngularLowerLimit( all ); - constraint.setAngularUpperLimit( aul ); - - for ( let i = 0; i < 3; i ++ ) { - - if ( params.springPosition[ i ] !== 0 ) { - - constraint.enableSpring( i, true ); - constraint.setStiffness( i, params.springPosition[ i ] ); - - } - - } - - for ( let i = 0; i < 3; i ++ ) { - - if ( params.springRotation[ i ] !== 0 ) { - - constraint.enableSpring( i + 3, true ); - constraint.setStiffness( i + 3, params.springRotation[ i ] ); - - } - - } - /* - * 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 ++ ) { - - constraint.setParam( 2, 0.475, i ); - - } - - } - - this.world.addConstraint( constraint, true ); - this.constraint = constraint; - manager.freeTransform( form ); - manager.freeTransform( formA ); - manager.freeTransform( formB ); - manager.freeTransform( formInverseA ); - manager.freeTransform( formInverseB ); - manager.freeTransform( formA2 ); - manager.freeTransform( formB2 ); - manager.freeVector3( lll ); - manager.freeVector3( lul ); - manager.freeVector3( all ); - manager.freeVector3( aul ); - - } - - } // - - - 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 { - - /** - * Visualize Rigid bodies - * - * @param {THREE.SkinnedMesh} mesh - * @param {Physics} physics - */ - constructor( mesh, physics ) { - - super(); - this.root = mesh; - this.physics = physics; - this.matrix.copy( mesh.matrixWorld ); - this.matrixAutoUpdate = false; - this.materials = []; - this.materials.push( new THREE.MeshBasicMaterial( { - color: new THREE.Color( 0xff8888 ), - wireframe: true, - depthTest: false, - depthWrite: false, - opacity: 0.25, - transparent: true - } ) ); - this.materials.push( new THREE.MeshBasicMaterial( { - color: new THREE.Color( 0x88ff88 ), - wireframe: true, - depthTest: false, - depthWrite: false, - opacity: 0.25, - transparent: true - } ) ); - this.materials.push( new THREE.MeshBasicMaterial( { - color: new THREE.Color( 0x8888ff ), - wireframe: true, - depthTest: false, - depthWrite: false, - opacity: 0.25, - transparent: true - } ) ); - - this._init(); - - } - /** - * 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; - var child = this.children[ i ]; - var tr = body.getCenterOfMassTransform(); - var origin = tr.getOrigin(); - var rotation = tr.getRotation(); - child.position.set( origin.x(), origin.y(), origin.z() ).applyMatrix4( _matrixWorldInv ); - child.quaternion.setFromRotationMatrix( _matrixWorldInv ).multiply( _quaternion.set( rotation.x(), rotation.y(), rotation.z(), rotation.w() ) ); - - } - - } - - this.matrix.copy( mesh.matrixWorld ).decompose( _position, _quaternion, _scale ).compose( _position, _quaternion, _scale.set( 1, 1, 1 ) ); - super.updateMatrixWorld( force ); - - } // 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 ); - - default: - return null; - - } - - } - - 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; - this.add( new THREE.Mesh( createGeometry( param ), this.materials[ param.type ] ) ); - - } - - } - - } - - THREE.MMDPhysics = MMDPhysics; - -} )(); diff --git a/examples/js/cameras/CinematicCamera.js b/examples/js/cameras/CinematicCamera.js deleted file mode 100644 index 63acf090b60af5..00000000000000 --- a/examples/js/cameras/CinematicCamera.js +++ /dev/null @@ -1,157 +0,0 @@ -( function () { - - class CinematicCamera extends THREE.PerspectiveCamera { - - constructor( fov, aspect, near, far ) { - - super( fov, aspect, near, far ); - this.type = 'CinematicCamera'; - this.postprocessing = { - enabled: true - }; - this.shaderSettings = { - rings: 3, - samples: 4 - }; - const depthShader = THREE.BokehDepthShader; - this.materialDepth = new THREE.ShaderMaterial( { - uniforms: depthShader.uniforms, - vertexShader: depthShader.vertexShader, - 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.setLens(); - this.initPostProcessing(); - - } // 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.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; - const znear = this.near; - 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 - - - focusAt( focusDistance = 20 ) { - - const focalLength = this.getFocalLength(); // distance from the camera (normal to frustrum) to focus on - - this.focus = focusDistance; // the nearest point from the camera which is in focus (unused) - - this.nearPoint = this.hyperFocal * this.focus / ( this.hyperFocal + ( this.focus - focalLength ) ); // the farthest point from the camera which is in focus (unused) - - 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) - - 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 ) { - - this.postprocessing.scene = new THREE.Scene(); - this.postprocessing.camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, - 10000, 10000 ); - this.postprocessing.scene.add( this.postprocessing.camera ); - this.postprocessing.rtTextureDepth = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight ); - this.postprocessing.rtTextureColor = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight ); - const bokeh_shader = THREE.BokehShader; - this.postprocessing.bokeh_uniforms = THREE.UniformsUtils.clone( bokeh_shader.uniforms ); - this.postprocessing.bokeh_uniforms[ 'tColor' ].value = this.postprocessing.rtTextureColor.texture; - this.postprocessing.bokeh_uniforms[ 'tDepth' ].value = this.postprocessing.rtTextureDepth.texture; - this.postprocessing.bokeh_uniforms[ 'manualdof' ].value = 0; - 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[ 'znear' ].value = this.near; - this.postprocessing.bokeh_uniforms[ 'zfar' ].value = this.near; - this.postprocessing.bokeh_uniforms[ 'textureWidth' ].value = window.innerWidth; - this.postprocessing.bokeh_uniforms[ 'textureHeight' ].value = window.innerHeight; - this.postprocessing.materialBokeh = new THREE.ShaderMaterial( { - uniforms: this.postprocessing.bokeh_uniforms, - vertexShader: bokeh_shader.vertexShader, - fragmentShader: bokeh_shader.fragmentShader, - defines: { - RINGS: this.shaderSettings.rings, - SAMPLES: this.shaderSettings.samples, - DEPTH_PACKING: 1 - } - } ); - this.postprocessing.quad = new THREE.Mesh( new THREE.PlaneGeometry( window.innerWidth, window.innerHeight ), this.postprocessing.materialBokeh ); - this.postprocessing.quad.position.z = - 500; - this.postprocessing.scene.add( this.postprocessing.quad ); - - } - - } - - renderCinematic( scene, renderer ) { - - if ( this.postprocessing.enabled ) { - - const currentRenderTarget = renderer.getRenderTarget(); - renderer.clear(); // Render scene into texture - - scene.overrideMaterial = null; - renderer.setRenderTarget( this.postprocessing.rtTextureColor ); - renderer.clear(); - 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.setRenderTarget( null ); - renderer.render( this.postprocessing.scene, this.postprocessing.camera ); - renderer.setRenderTarget( currentRenderTarget ); - - } - - } - - } - - THREE.CinematicCamera = CinematicCamera; - -} )(); diff --git a/examples/js/controls/ArcballControls.js b/examples/js/controls/ArcballControls.js deleted file mode 100644 index b1d852ad4207a1..00000000000000 --- a/examples/js/controls/ArcballControls.js +++ /dev/null @@ -1,3024 +0,0 @@ -( function () { - - const STATE = { - IDLE: Symbol(), - ROTATE: Symbol(), - PAN: Symbol(), - SCALE: Symbol(), - FOV: Symbol(), - FOCUS: Symbol(), - ZROTATE: Symbol(), - TOUCH_MULTI: Symbol(), - ANIMATION_FOCUS: Symbol(), - ANIMATION_ROTATE: Symbol() - }; - const INPUT = { - NONE: Symbol(), - ONE_FINGER: Symbol(), - ONE_FINGER_SWITCHED: Symbol(), - TWO_FINGER: Symbol(), - MULT_FINGER: Symbol(), - CURSOR: Symbol() - }; //cursor center coordinates - - const _center = { - x: 0, - y: 0 - }; //transformation matrices for gizmos and camera - - const _transformation = { - camera: new THREE.Matrix4(), - gizmos: new THREE.Matrix4() - }; //events - - const _changeEvent = { - type: 'change' - }; - const _startEvent = { - type: 'start' - }; - 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(); - /** - * - * @param {Camera} camera Virtual camera used in the scene - * @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; - this._tbRadius = this.calculateTbRadius( this.camera ); - const newRadius = this._tbRadius / scale; - 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; - - } - - this.dispatchEvent( _changeEvent ); - - }; - - this.onContextMenu = event => { - - if ( ! this.enabled ) { - - return; - - } - - for ( let i = 0; i < this.mouseActions.length; i ++ ) { - - if ( this.mouseActions[ i ].mouse == 2 ) { - - //prevent only if button 2 is actually used - event.preventDefault(); - break; - - } - - } - - }; - - this.onPointerCancel = () => { - - this._touchStart.splice( 0, this._touchStart.length ); - - this._touchCurrent.splice( 0, this._touchCurrent.length ); - - this._input = INPUT.NONE; - - }; - - this.onPointerDown = event => { - - if ( event.button == 0 && event.isPrimary ) { - - this._downValid = true; - - this._downEvents.push( event ); - - this._downStart = performance.now(); - - } else { - - this._downValid = false; - - } - - if ( event.pointerType == 'touch' && this._input != INPUT.CURSOR ) { - - this._touchStart.push( event ); - - this._touchCurrent.push( event ); - - switch ( this._input ) { - - case INPUT.NONE: - //singleStart - this._input = INPUT.ONE_FINGER; - this.onSinglePanStart( event, 'ROTATE' ); - window.addEventListener( 'pointermove', this.onPointerMove ); - window.addEventListener( 'pointerup', this.onPointerUp ); - break; - - case INPUT.ONE_FINGER: - case INPUT.ONE_FINGER_SWITCHED: - //doubleStart - this._input = INPUT.TWO_FINGER; - this.onRotateStart(); - this.onPinchStart(); - this.onDoublePanStart(); - break; - - case INPUT.TWO_FINGER: - //multipleStart - this._input = INPUT.MULT_FINGER; - this.onTriplePanStart( event ); - break; - - } - - } else if ( event.pointerType != 'touch' && this._input == INPUT.NONE ) { - - let modifier = null; - - if ( event.ctrlKey || event.metaKey ) { - - modifier = 'CTRL'; - - } else if ( event.shiftKey ) { - - modifier = 'SHIFT'; - - } - - this._mouseOp = this.getOpFromAction( event.button, modifier ); - - if ( this._mouseOp != null ) { - - window.addEventListener( 'pointermove', this.onPointerMove ); - window.addEventListener( 'pointerup', this.onPointerUp ); //singleStart - - this._input = INPUT.CURSOR; - this._button = event.button; - this.onSinglePanStart( event, this._mouseOp ); - - } - - } - - }; - - this.onPointerMove = event => { - - if ( event.pointerType == 'touch' && this._input != INPUT.CURSOR ) { - - switch ( this._input ) { - - case INPUT.ONE_FINGER: - //singleMove - 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 - this._input = INPUT.ONE_FINGER; - this.updateTouchEvent( event ); - this.onSinglePanStart( event, 'ROTATE' ); - break; - - } - - break; - - case INPUT.TWO_FINGER: - //rotate/pan/pinchMove - this.updateTouchEvent( event ); - this.onRotateMove(); - this.onPinchMove(); - this.onDoublePanMove(); - break; - - case INPUT.MULT_FINGER: - //multMove - this.updateTouchEvent( event ); - this.onTriplePanMove( event ); - break; - - } - - } else if ( event.pointerType != 'touch' && this._input == INPUT.CURSOR ) { - - let modifier = null; - - if ( event.ctrlKey || event.metaKey ) { - - modifier = 'CTRL'; - - } else if ( event.shiftKey ) { - - modifier = 'SHIFT'; - - } - - const mouseOpState = this.getOpStateFromAction( this._button, modifier ); - - if ( mouseOpState != null ) { - - this.onSinglePanMove( event, mouseOpState ); - - } - - } //checkDistance - - - if ( this._downValid ) { - - const movement = this.calculatePointersDistance( this._downEvents[ this._downEvents.length - 1 ], event ) * this._devPxRatio; - - if ( movement > this._movementThreshold ) { - - this._downValid = false; - - } - - } - - }; - - this.onPointerUp = event => { - - 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; - - } - - } - - switch ( this._input ) { - - case INPUT.ONE_FINGER: - case INPUT.ONE_FINGER_SWITCHED: - //singleEnd - window.removeEventListener( 'pointermove', this.onPointerMove ); - window.removeEventListener( 'pointerup', this.onPointerUp ); - 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._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 - - this._input = INPUT.NONE; - this.onTriplePanEnd(); - - } - - break; - - } - - } else if ( event.pointerType != 'touch' && this._input == INPUT.CURSOR ) { - - window.removeEventListener( 'pointermove', this.onPointerMove ); - window.removeEventListener( 'pointerup', this.onPointerUp ); - this._input = INPUT.NONE; - this.onSinglePanEnd(); - this._button = - 1; - - } - - if ( event.isPrimary ) { - - if ( this._downValid ) { - - const downTime = event.timeStamp - this._downEvents[ this._downEvents.length - 1 ].timeStamp; - - if ( downTime <= this._maxDownTime ) { - - if ( this._nclicks == 0 ) { - - //first valid click detected - this._nclicks = 1; - this._clickStart = performance.now(); - - } 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(); - - } - - } - - } else { - - this._downValid = false; - this._nclicks = 0; - - this._downEvents.splice( 0, this._downEvents.length ); - - } - - } else { - - this._nclicks = 0; - - this._downEvents.splice( 0, this._downEvents.length ); - - } - - } - - }; - - this.onWheel = event => { - - if ( this.enabled && this.enableZoom ) { - - let modifier = null; - - if ( event.ctrlKey || event.metaKey ) { - - modifier = 'CTRL'; - - } else if ( event.shiftKey ) { - - modifier = 'SHIFT'; - - } - - 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; - - } else if ( sgn < 0 ) { - - size = this.scaleFactor; - - } - - switch ( mouseOp ) { - - case 'ZOOM': - this.updateTbState( STATE.SCALE, true ); - - if ( sgn > 0 ) { - - size = 1 / Math.pow( this.scaleFactor, sgn ); - - } else if ( sgn < 0 ) { - - size = Math.pow( this.scaleFactor, - sgn ); - - } - - 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 ); - - } else if ( this.camera.isPerspectiveCamera ) { - - scalePoint = this.unprojectOnTbPlane( this.camera, event.clientX, event.clientY, this.domElement ).applyQuaternion( this.camera.quaternion ).add( this._gizmos.position ); - - } - - this.applyTransformMatrix( this.scale( size, scalePoint ) ); - - } else { - - this.applyTransformMatrix( this.scale( size, this._gizmos.position ) ); - - } - - if ( this._grid != null ) { - - this.disposeGrid(); - this.drawGrid(); - - } - - this.updateTbState( STATE.IDLE, false ); - this.dispatchEvent( _changeEvent ); - this.dispatchEvent( _endEvent ); - break; - - case 'FOV': - if ( this.camera.isPerspectiveCamera ) { - - this.updateTbState( STATE.FOV, true ); //Vertigo effect - // fov / 2 - // |\ - // | \ - // | \ - // x | \ - // | \ - // | \ - // | _ _ _\ - // y - //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 ); - - } else if ( sgn < 0 ) { - - size = Math.pow( this.scaleFactor, - sgn ); - - } - - } - - 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 - - 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 - - let newFov = THREE.MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 ); //check min and max fov - - if ( newFov > this.maxFov ) { - - newFov = this.maxFov; - - } else if ( newFov < this.minFov ) { - - newFov = this.minFov; - - } - - const newDistance = y / Math.tan( THREE.MathUtils.DEG2RAD * ( newFov / 2 ) ); - size = x / newDistance; - this.setFov( newFov ); - this.applyTransformMatrix( this.scale( size, this._gizmos.position, false ) ); - - } - - if ( this._grid != null ) { - - this.disposeGrid(); - this.drawGrid(); - - } - - this.updateTbState( STATE.IDLE, false ); - this.dispatchEvent( _changeEvent ); - this.dispatchEvent( _endEvent ); - break; - - } - - } - - } - - }; - - this.onSinglePanStart = ( event, operation ) => { - - if ( this.enabled ) { - - this.dispatchEvent( _startEvent ); - this.setCenter( event.clientX, event.clientY ); - - switch ( operation ) { - - case 'PAN': - if ( ! this.enablePan ) { - - return; - - } - - if ( this._animationId != - 1 ) { - - cancelAnimationFrame( this._animationId ); - this._animationId = - 1; - this._timeStart = - 1; - this.activateGizmos( false ); - this.dispatchEvent( _changeEvent ); - - } - - this.updateTbState( STATE.PAN, true ); - - this._startCursorPosition.copy( this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ) ); - - if ( this.enableGrid ) { - - this.drawGrid(); - this.dispatchEvent( _changeEvent ); - - } - - break; - - case 'ROTATE': - if ( ! this.enableRotate ) { - - return; - - } - - if ( this._animationId != - 1 ) { - - cancelAnimationFrame( this._animationId ); - this._animationId = - 1; - this._timeStart = - 1; - - } - - 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; - - } - - this.dispatchEvent( _changeEvent ); - break; - - case 'FOV': - if ( ! this.camera.isPerspectiveCamera || ! this.enableZoom ) { - - return; - - } - - if ( this._animationId != - 1 ) { - - cancelAnimationFrame( this._animationId ); - this._animationId = - 1; - this._timeStart = - 1; - this.activateGizmos( false ); - this.dispatchEvent( _changeEvent ); - - } - - 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 ) { - - return; - - } - - if ( this._animationId != - 1 ) { - - cancelAnimationFrame( this._animationId ); - this._animationId = - 1; - this._timeStart = - 1; - this.activateGizmos( false ); - this.dispatchEvent( _changeEvent ); - - } - - 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; - - } - - } - - }; - - this.onSinglePanMove = ( event, opState ) => { - - if ( this.enabled ) { - - const restart = opState != this._state; - this.setCenter( event.clientX, event.clientY ); - - switch ( opState ) { - - case STATE.PAN: - if ( this.enablePan ) { - - 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(); - - } - - this.activateGizmos( false ); - - } else { - - //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 ) ); - - } - - } - - 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(); - - } - - this.activateGizmos( true ); - - } else { - - //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 ); - - } - - } - - } - - 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(); - - } - - this.activateGizmos( false ); - - } else { - - //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 ); - - } else if ( movement > 0 ) { - - size = Math.pow( this.scaleFactor, movement * screenNotches ); - - } - - this._v3_1.setFromMatrixPosition( this._gizmoMatrixState ); - - this.applyTransformMatrix( this.scale( size, this._v3_1 ) ); - - } - - } - - 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(); - - } - - this.activateGizmos( false ); - - } else { - - //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 ); - - } else if ( movement > 0 ) { - - size = Math.pow( this.scaleFactor, movement * screenNotches ); - - } - - 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 - - xNew = THREE.MathUtils.clamp( xNew, this.minDistance, this.maxDistance ); - const y = x * Math.tan( THREE.MathUtils.DEG2RAD * this._fovState * 0.5 ); //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 - - _offset.copy( this._gizmos.position ).sub( this.camera.position ).normalize().multiplyScalar( newDistance / x ); - - this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z ); - - } - - } - - break; - - } - - this.dispatchEvent( _changeEvent ); - - } - - }; - - this.onSinglePanEnd = () => { - - if ( this._state == STATE.ROTATE ) { - - if ( ! this.enableRotate ) { - - return; - - } - - if ( this.enableAnimations ) { - - //perform rotation animation - const deltaTime = performance.now() - this._timeCurrent; - - if ( deltaTime < 120 ) { - - const w = Math.abs( ( this._wPrev + this._wCurr ) / 2 ); - const self = this; - this._animationId = window.requestAnimationFrame( function ( t ) { - - self.updateTbState( STATE.ANIMATION_ROTATE, true ); - const rotationAxis = self.calculateRotationAxis( self._cursorPosPrev, self._cursorPosCurr ); - self.onRotationAnim( t, rotationAxis, Math.min( w, self.wMax ) ); - - } ); - - } else { - - //cursor has been standing still for over 120 ms since last movement - this.updateTbState( STATE.IDLE, false ); - this.activateGizmos( false ); - this.dispatchEvent( _changeEvent ); - - } - - } else { - - this.updateTbState( STATE.IDLE, false ); - this.activateGizmos( false ); - this.dispatchEvent( _changeEvent ); - - } - - } else if ( this._state == STATE.PAN || this._state == STATE.IDLE ) { - - this.updateTbState( STATE.IDLE, false ); - - if ( this.enableGrid ) { - - this.disposeGrid(); - - } - - this.activateGizmos( false ); - this.dispatchEvent( _changeEvent ); - - } - - this.dispatchEvent( _endEvent ); - - }; - - this.onDoubleTap = event => { - - if ( this.enabled && this.enablePan && this.scene != null ) { - - 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 ); - - } - - this._timeStart = - 1; - this._animationId = window.requestAnimationFrame( function ( t ) { - - self.updateTbState( STATE.ANIMATION_FOCUS, true ); - self.onFocusAnim( t, hitP, self._cameraMatrixState, self._gizmoMatrixState ); - - } ); - - } else if ( hitP != null && ! this.enableAnimations ) { - - this.updateTbState( STATE.FOCUS, true ); - this.focus( hitP, this.scaleFactor ); - this.updateTbState( STATE.IDLE, false ); - this.dispatchEvent( _changeEvent ); - - } - - } - - this.dispatchEvent( _endEvent ); - - }; - - this.onDoublePanStart = () => { - - if ( this.enabled && this.enablePan ) { - - 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 ); - - } - - }; - - this.onDoublePanMove = () => { - - 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 ); - - } - - }; - - this.onDoublePanEnd = () => { - - this.updateTbState( STATE.IDLE, false ); - this.dispatchEvent( _endEvent ); - - }; - - this.onRotateStart = () => { - - if ( this.enabled && this.enableRotate ) { - - this.dispatchEvent( _startEvent ); - 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; - this.camera.getWorldDirection( this._rotationAxis ); //rotation axis - - if ( ! this.enablePan && ! this.enableZoom ) { - - this.activateGizmos( true ); - - } - - } - - }; - - this.onRotateMove = () => { - - if ( this.enabled && this.enableRotate ) { - - 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 = 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 ); - - } 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 ); - - } - - const amount = THREE.MathUtils.DEG2RAD * ( this._startFingerRotation - this._currentFingerRotation ); - this.applyTransformMatrix( this.zRotate( rotationPoint, amount ) ); - this.dispatchEvent( _changeEvent ); - - } - - }; - - this.onRotateEnd = () => { - - this.updateTbState( STATE.IDLE, false ); - this.activateGizmos( false ); - this.dispatchEvent( _endEvent ); - - }; - - this.onPinchStart = () => { - - if ( this.enabled && this.enableZoom ) { - - this.dispatchEvent( _startEvent ); - this.updateTbState( STATE.SCALE, true ); - this._startFingerDistance = this.calculatePointersDistance( this._touchCurrent[ 0 ], this._touchCurrent[ 1 ] ); - this._currentFingerDistance = this._startFingerDistance; - this.activateGizmos( false ); - - } - - }; - - this.onPinchMove = () => { - - if ( this.enabled && this.enableZoom ) { - - this.setCenter( ( this._touchCurrent[ 0 ].clientX + this._touchCurrent[ 1 ].clientX ) / 2, ( this._touchCurrent[ 0 ].clientY + this._touchCurrent[ 1 ].clientY ) / 2 ); - const minDistance = 12; //minimum distance between fingers (in css pixels) - - if ( this._state != STATE.SCALE ) { - - this._startFingerDistance = this._currentFingerDistance; - this.updateTbState( STATE.SCALE, true ); - - } - - 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; - - } else { - - if ( this.camera.isOrthographicCamera ) { - - scalePoint = this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ).applyQuaternion( this.camera.quaternion ).multiplyScalar( 1 / this.camera.zoom ).add( this._gizmos.position ); - - } else if ( this.camera.isPerspectiveCamera ) { - - scalePoint = this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ).applyQuaternion( this.camera.quaternion ).add( this._gizmos.position ); - - } - - } - - this.applyTransformMatrix( this.scale( amount, scalePoint ) ); - this.dispatchEvent( _changeEvent ); - - } - - }; - - this.onPinchEnd = () => { - - this.updateTbState( STATE.IDLE, false ); - this.dispatchEvent( _endEvent ); - - }; - - this.onTriplePanStart = () => { - - if ( this.enabled && this.enableZoom ) { - - this.dispatchEvent( _startEvent ); - 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; - clientY += this._touchCurrent[ i ].clientY; - - } - - 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 ); - - } - - }; - - this.onTriplePanMove = () => { - - if ( this.enabled && this.enableZoom ) { - - // fov / 2 - // |\ - // | \ - // | \ - // x | \ - // | \ - // | \ - // | _ _ _\ - // 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; - clientY += this._touchCurrent[ i ].clientY; - - } - - 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 ); - - } else if ( movement > 0 ) { - - size = Math.pow( this.scaleFactor, movement * screenNotches ); - - } - - 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 - - xNew = THREE.MathUtils.clamp( xNew, this.minDistance, this.maxDistance ); - const y = x * Math.tan( THREE.MathUtils.DEG2RAD * this._fovState * 0.5 ); //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 - - _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 ); - - } - - }; - - this.onTriplePanEnd = () => { - - this.updateTbState( STATE.IDLE, false ); - this.dispatchEvent( _endEvent ); //this.dispatchEvent( _changeEvent ); - - }; - - this.setCenter = ( clientX, clientY ) => { - - _center.x = clientX; - _center.y = clientY; - - }; - - this.initializeMouseActions = () => { - - this.setMouseAction( 'PAN', 0, 'CTRL' ); - this.setMouseAction( 'PAN', 2 ); - this.setMouseAction( 'ROTATE', 0 ); - this.setMouseAction( 'ZOOM', 'WHEEL' ); - this.setMouseAction( 'ZOOM', 1 ); - this.setMouseAction( 'FOV', 'WHEEL', 'SHIFT' ); - this.setMouseAction( 'FOV', 1, 'SHIFT' ); - - }; - - this.compareMouseAction = ( action1, action2 ) => { - - if ( action1.operation == action2.operation ) { - - if ( action1.mouse == action2.mouse && action1.key == action2.key ) { - - return true; - - } else { - - return false; - - } - - } else { - - return false; - - } - - }; - - this.setMouseAction = ( operation, mouse, key = null ) => { - - const operationInput = [ 'PAN', 'ROTATE', 'ZOOM', 'FOV' ]; - 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 - return false; - - } - - if ( mouse == 'WHEEL' ) { - - if ( operation != 'ZOOM' && operation != 'FOV' ) { - - //cannot associate 2D operation to 1D input - return false; - - } - - } - - switch ( operation ) { - - case 'PAN': - state = STATE.PAN; - break; - - case 'ROTATE': - state = STATE.ROTATE; - break; - - case 'ZOOM': - state = STATE.SCALE; - break; - - case 'FOV': - state = STATE.FOV; - break; - - } - - const action = { - operation: operation, - mouse: mouse, - 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 ) { - - this.mouseActions.splice( i, 1, action ); - return true; - - } - - } - - this.mouseActions.push( action ); - return true; - - }; - - this.unsetMouseAction = ( mouse, key = null ) => { - - for ( let i = 0; i < this.mouseActions.length; i ++ ) { - - if ( this.mouseActions[ i ].mouse == mouse && this.mouseActions[ i ].key == key ) { - - this.mouseActions.splice( i, 1 ); - return true; - - } - - } - - return false; - - }; - - 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; - - } - - } - - if ( key != null ) { - - for ( let i = 0; i < this.mouseActions.length; i ++ ) { - - action = this.mouseActions[ i ]; - - if ( action.mouse == mouse && action.key == null ) { - - return action.operation; - - } - - } - - } - - return null; - - }; - - 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; - - } - - } - - if ( key != null ) { - - for ( let i = 0; i < this.mouseActions.length; i ++ ) { - - action = this.mouseActions[ i ]; - - if ( action.mouse == mouse && action.key == null ) { - - return action.state; - - } - - } - - } - - return null; - - }; - - this.getAngle = ( p1, p2 ) => { - - return Math.atan2( p2.clientY - p1.clientY, p2.clientX - p1.clientX ) * 180 / Math.PI; - - }; - - this.updateTouchEvent = event => { - - for ( let i = 0; i < this._touchCurrent.length; i ++ ) { - - if ( this._touchCurrent[ i ].pointerId == event.pointerId ) { - - this._touchCurrent.splice( i, 1, event ); - - break; - - } - - } - - }; - - this.calculateAngularSpeed = ( p0, p1, t0, t1 ) => { - - const s = p1 - p0; - const t = ( t1 - t0 ) / 1000; - - if ( t == 0 ) { - - return 0; - - } - - return s / t; - - }; - - this.calculatePointersDistance = ( p0, p1 ) => { - - return Math.sqrt( Math.pow( p1.clientX - p0.clientX, 2 ) + Math.pow( p1.clientY - p0.clientY, 2 ) ); - - }; - - 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(); - - }; - - 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' ) { - - return Math.min( camera.top, camera.right ) * this.radiusFactor; - - } - - }; - - this.focus = ( point, size, amount = 1 ) => { - - //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 ); //apply zoom - - - if ( this.enableZoom ) { - - this.applyTransformMatrix( this.scale( size, this._gizmos.position ) ); - - } - - this._gizmoMatrixState.copy( _gizmoMatrixStateTemp ); - - this._cameraMatrixState.copy( _cameraMatrixStateTemp ); - - }; - - this.drawGrid = () => { - - if ( this.scene != null ) { - - const color = 0x888888; - const multiplier = 3; - let size, divisions, maxLength, tick; - - if ( this.camera.isOrthographicCamera ) { - - const width = this.camera.right - this.camera.left; - const height = this.camera.bottom - this.camera.top; - maxLength = Math.max( width, height ); - tick = maxLength / 20; - size = maxLength / this.camera.zoom * multiplier; - divisions = size / tick * this.camera.zoom; - - } else if ( this.camera.isPerspectiveCamera ) { - - const distance = this.camera.position.distanceTo( this._gizmos.position ); - const halfFovV = THREE.MathUtils.DEG2RAD * this.camera.fov * 0.5; - const halfFovH = Math.atan( this.camera.aspect * Math.tan( halfFovV ) ); - maxLength = Math.tan( Math.max( halfFovV, halfFovH ) ) * distance * 2; - tick = maxLength / 20; - size = maxLength * multiplier; - divisions = size / tick; - - } - - 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 ); - - } - - } - - }; - - this.dispose = () => { - - if ( this._animationId != - 1 ) { - - window.cancelAnimationFrame( this._animationId ); - - } - - this.domElement.removeEventListener( 'pointerdown', this.onPointerDown ); - this.domElement.removeEventListener( 'pointercancel', this.onPointerCancel ); - this.domElement.removeEventListener( 'wheel', this.onWheel ); - this.domElement.removeEventListener( 'contextmenu', this.onContextMenu ); - window.removeEventListener( 'pointermove', this.onPointerMove ); - window.removeEventListener( 'pointerup', this.onPointerUp ); - window.removeEventListener( 'resize', this.onWindowResize ); - if ( this.scene !== null ) this.scene.remove( this._gizmos ); - this.disposeGrid(); - - }; - - this.disposeGrid = () => { - - if ( this._grid != null && this.scene != null ) { - - this.scene.remove( this._grid ); - this._grid = null; - - } - - }; - - this.easeOutCubic = t => { - - return 1 - Math.pow( 1 - t, 3 ); - - }; - - this.activateGizmos = isActive => { - - const gizmoX = this._gizmos.children[ 0 ]; - const gizmoY = this._gizmos.children[ 1 ]; - const gizmoZ = this._gizmos.children[ 2 ]; - - if ( isActive ) { - - gizmoX.material.setValues( { - opacity: 1 - } ); - gizmoY.material.setValues( { - opacity: 1 - } ); - gizmoZ.material.setValues( { - opacity: 1 - } ); - - } else { - - gizmoX.material.setValues( { - opacity: 0.6 - } ); - gizmoY.material.setValues( { - opacity: 0.6 - } ); - gizmoZ.material.setValues( { - opacity: 0.6 - } ); - - } - - }; - - 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(); - - }; - - 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(); - - }; - - this.setCamera = camera => { - - camera.lookAt( this.target ); - camera.updateMatrix(); //setting state - - if ( camera.type == 'PerspectiveCamera' ) { - - this._fov0 = camera.fov; - this._fovState = camera.fov; - - } - - 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; - this._nearPos0 = camera.position.distanceTo( this.target ) - camera.near; - this._nearPos = this._initialNear; - 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._tbRadius = this.calculateTbRadius( camera ); - this.makeGizmos( this.target, this._tbRadius ); - - }; - - this.makeGizmos = ( tbCenter, tbRadius ) => { - - const curve = new THREE.EllipseCurve( 0, 0, tbRadius, tbRadius ); - const points = curve.getPoints( this._curvePts ); //geometry - - const curveGeometry = new THREE.BufferGeometry().setFromPoints( points ); //material - - const curveMaterialX = new THREE.LineBasicMaterial( { - color: 0xff8080, - fog: false, - transparent: true, - opacity: 0.6 - } ); - const curveMaterialY = new THREE.LineBasicMaterial( { - color: 0x80ff80, - fog: false, - transparent: true, - opacity: 0.6 - } ); - const curveMaterialZ = new THREE.LineBasicMaterial( { - color: 0x8080ff, - fog: false, - transparent: true, - opacity: 0.6 - } ); //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 - - 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._gizmos.clear(); - - this._gizmos.add( gizmoX ); - - this._gizmos.add( gizmoY ); - - this._gizmos.add( gizmoZ ); - - }; - - this.onFocusAnim = ( time, point, cameraMatrix, gizmoMatrix ) => { - - if ( this._timeStart == - 1 ) { - - //animation start - this._timeStart = time; - - } - - if ( this._state == STATE.ANIMATION_FOCUS ) { - - 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.focus( point, this.scaleFactor ); - this._timeStart = - 1; - this.updateTbState( STATE.IDLE, false ); - this.activateGizmos( false ); - this.dispatchEvent( _changeEvent ); - - } else { - - 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; - this._animationId = window.requestAnimationFrame( function ( t ) { - - self.onFocusAnim( t, point, cameraMatrix, gizmoMatrix.clone() ); - - } ); - - } - - } else { - - //interrupt animation - this._animationId = - 1; - this._timeStart = - 1; - - } - - }; - - this.onRotationAnim = ( time, rotationAxis, w0 ) => { - - if ( this._timeStart == - 1 ) { - - //animation start - this._anglePrev = 0; - this._angleCurrent = 0; - this._timeStart = time; - - } - - if ( this._state == STATE.ANIMATION_ROTATE ) { - - //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 - this._angleCurrent = 0.5 * - this.dampingFactor * Math.pow( deltaTime, 2 ) + w0 * deltaTime + 0; - this.applyTransformMatrix( this.rotate( rotationAxis, this._angleCurrent ) ); - this.dispatchEvent( _changeEvent ); - const self = this; - this._animationId = window.requestAnimationFrame( function ( t ) { - - self.onRotationAnim( t, rotationAxis, w0 ); - - } ); - - } else { - - this._animationId = - 1; - this._timeStart = - 1; - this.updateTbState( STATE.IDLE, false ); - this.activateGizmos( false ); - this.dispatchEvent( _changeEvent ); - - } - - } else { - - //interrupt animation - this._animationId = - 1; - this._timeStart = - 1; - - if ( this._state != STATE.ROTATE ) { - - this.activateGizmos( false ); - this.dispatchEvent( _changeEvent ); - - } - - } - - }; - - this.pan = ( p0, p1, adjust = false ) => { - - const movement = p0.clone().sub( p1 ); - - if ( this.camera.isOrthographicCamera ) { - - //adjust movement amount - movement.multiplyScalar( 1 / this.camera.zoom ); - - } else if ( this.camera.isPerspectiveCamera && adjust ) { - - //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; - - }; - - this.reset = () => { - - this.camera.zoom = this._zoom0; - - if ( this.camera.isPerspectiveCamera ) { - - this.camera.fov = this._fov0; - - } - - 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 ); - this.updateTbState( STATE.IDLE, false ); - this.dispatchEvent( _changeEvent ); - - }; - - 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 ); //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; - - }; - - this.copyState = () => { - - let state; - - if ( this.camera.isOrthographicCamera ) { - - state = JSON.stringify( { - arcballState: { - cameraFar: this.camera.far, - cameraMatrix: this.camera.matrix, - cameraNear: this.camera.near, - cameraUp: this.camera.up, - cameraZoom: this.camera.zoom, - gizmoMatrix: this._gizmos.matrix - } - } ); - - } else if ( this.camera.isPerspectiveCamera ) { - - state = JSON.stringify( { - arcballState: { - cameraFar: this.camera.far, - cameraFov: this.camera.fov, - cameraMatrix: this.camera.matrix, - cameraNear: this.camera.near, - cameraUp: this.camera.up, - cameraZoom: this.camera.zoom, - gizmoMatrix: this._gizmos.matrix - } - } ); - - } - - navigator.clipboard.writeText( state ); - - }; - - this.pasteState = () => { - - const self = this; - navigator.clipboard.readText().then( function resolved( value ) { - - self.setStateFromJSON( value ); - - } ); - - }; - - 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; - - } - - }; - - 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 - - if ( this.camera.zoom > this.maxZoom ) { - - this.camera.zoom = this.maxZoom; - sizeInverse = this._zoomState / this.maxZoom; - - } else if ( this.camera.zoom < this.minZoom ) { - - this.camera.zoom = this.minZoom; - sizeInverse = this._zoomState / this.minZoom; - - } - - this.camera.updateProjectionMatrix(); - - this._v3_1.setFromMatrixPosition( this._gizmoMatrixState ); //gizmos position - //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 ); //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 ); //move camera - - - let distance = this._v3_1.distanceTo( _scalePointTemp ); - - let amount = distance - distance * sizeInverse; //check min and max distance - - const newDistance = distance - amount; - - if ( newDistance < this.minDistance ) { - - sizeInverse = this.minDistance / distance; - amount = distance - distance * sizeInverse; - - } else if ( newDistance > this.maxDistance ) { - - sizeInverse = this.maxDistance / distance; - amount = distance - distance * sizeInverse; - - } - - _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 { - - this.setTransformationMatrices( this._m4_1 ); - - } - - return _transformation; - - } - - }; - - this.setFov = value => { - - if ( this.camera.isPerspectiveCamera ) { - - this.camera.fov = THREE.MathUtils.clamp( value, this.minFov, this.maxFov ); - this.camera.updateProjectionMatrix(); - - } - - }; - - 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; - - }; - - this.unprojectOnObj = ( cursor, camera ) => { - - const raycaster = this.getRaycaster(); - raycaster.near = camera.near; - 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 ) { - - return intersect[ i ].point.clone(); - - } - - } - - return null; - - }; - - this.unprojectOnTbSurface = ( camera, cursorX, cursorY, canvas, tbRadius ) => { - - 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 - this._v3_1.setZ( Math.sqrt( r2 - ( x2 + y2 ) ) ); - - } else { - - //intersection with hyperboloid - this._v3_1.setZ( r2 * 0.5 / Math.sqrt( x2 + y2 ) ); - - } - - return this._v3_1; - - } else if ( camera.type == 'PerspectiveCamera' ) { - - //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 - // |\ - // | \ - // | \ - // h | \ - // | \ - // | \ - // _ _ | _ _ _\ _ _ 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 ) ); - - if ( l == 0 ) { - - //ray aligned with camera - rayDir.set( this._v3_1.x, this._v3_1.y, tbRadius ); - return rayDir; - - } - - const m = h / l; - const q = cameraGizmoDistance; - /* - * calculate intersection point between unprojected ray and trackball surface - *|y = m * x + q - *|x^2 + y^2 = r^2 - * - * (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; - return rayDir; - - } - - } //intersection with hyperboloid - - /* - *|y = m * x + q - *|y = (1 / x) * (r^2 / 2) - * - * 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; - return rayDir; - - } - - }; - - this.unprojectOnTbPlane = ( camera, cursorX, cursorY, canvas, initialDistance = false ) => { - - 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._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 - // |\ - // | \ - // | \ - // h | \ - // | \ - // | \ - // _ _ | _ _ _\ _ _ 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 ) ); - - } else { - - cameraGizmoDistance = camera.position.distanceTo( this._gizmos.position ); - - } - /* - * calculate intersection point between unprojected ray and the plane - *|y = mx + q - *|y = 0 - * - * x = -q/m - */ - - - if ( l == 0 ) { - - //ray aligned with camera - rayDir.set( 0, 0, 0 ); - return rayDir; - - } - - const m = h / l; - const q = cameraGizmoDistance; - const x = - q / m; - const rayLength = Math.sqrt( Math.pow( q, 2 ) + Math.pow( x, 2 ) ); - rayDir.multiplyScalar( rayLength ); - rayDir.z = 0; - return rayDir; - - } - - }; - - this.updateMatrixState = () => { - - //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; - - } else if ( this.camera.isPerspectiveCamera ) { - - this._fovState = this.camera.fov; - - } - - }; - - this.updateTbState = ( newState, updateMatrices ) => { - - this._state = newState; - - if ( updateMatrices ) { - - this.updateMatrixState(); - - } - - }; - - 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 - - - if ( this.camera.isOrthographicCamera ) { - - //check zoom - if ( this.camera.zoom > this.maxZoom || this.camera.zoom < this.minZoom ) { - - const newZoom = THREE.MathUtils.clamp( this.camera.zoom, this.minZoom, this.maxZoom ); - this.applyTransformMatrix( this.scale( newZoom / this.camera.zoom, this._gizmos.position, true ) ); - - } - - } else if ( this.camera.isPerspectiveCamera ) { - - //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 - - - if ( this.camera.fov < this.minFov || this.camera.fov > this.maxFov ) { - - this.camera.fov = THREE.MathUtils.clamp( this.camera.fov, this.minFov, this.maxFov ); - this.camera.updateProjectionMatrix(); - - } - - 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; - const newRadius = this._tbRadius / scale; - 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; - - } - - } - - } - - this.camera.lookAt( this._gizmos.position ); - - }; - - 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; - - } - - 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 ); - - } - - }; - - this.camera = null; - this.domElement = domElement; - this.scene = scene; - this.target = new THREE.Vector3(); - 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._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._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 - - this._cameraMatrixState = new THREE.Matrix4(); - this._cameraProjectionState = new THREE.Matrix4(); - this._fovState = 1; - this._upState = new THREE.Vector3(); - this._zoomState = 1; - this._nearPos = 0; - this._farPos = 0; - this._gizmoMatrixState = new THREE.Matrix4(); //initial values - - this._up0 = new THREE.Vector3(); - this._zoom0 = 1; - this._fov0 = 0; - this._initialNear = 0; - this._nearPos0 = 0; - this._initialFar = 0; - this._farPos0 = 0; - this._cameraMatrixState0 = new THREE.Matrix4(); - this._gizmoMatrixState0 = new THREE.Matrix4(); //pointers array - - this._button = - 1; - this._touchStart = []; - this._touchCurrent = []; - 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; //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._currentCursorPosition = new THREE.Vector3(); - this._startCursorPosition = new THREE.Vector3(); //grid - - this._grid = null; //grid to be visualized during pan operation - - this._gridPosition = new THREE.Vector3(); //gizmos - - this._gizmos = new THREE.Group(); - this._curvePts = 128; //animations - - this._timeStart = - 1; //initial time - - this._animationId = - 1; //focus animation - - this.focusAnimationTime = 500; //duration of focus animation in ms - //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 - - 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; - this.enablePan = true; - this.enableRotate = true; - this.enableZoom = true; - this.enableGizmos = true; - this.minDistance = 0; - this.maxDistance = Infinity; - this.minZoom = 0; - this.maxZoom = Infinity; //trackball parameters - - this._tbRadius = 1; //FSA - - this._state = STATE.IDLE; - this.setCamera( _camera ); - - if ( this.scene != null ) { - - this.scene.add( this._gizmos ); - - } - - this.domElement.style.touchAction = 'none'; - this._devPxRatio = window.devicePixelRatio; - this.initializeMouseActions(); - this.domElement.addEventListener( 'contextmenu', this.onContextMenu ); - this.domElement.addEventListener( 'wheel', this.onWheel ); - this.domElement.addEventListener( 'pointerdown', this.onPointerDown ); - this.domElement.addEventListener( 'pointercancel', this.onPointerCancel ); - window.addEventListener( 'resize', this.onWindowResize ); - - } //listeners - - - /** - * Apply a transformation matrix, to the camera and gizmos - * @param {Object} transformation Object containing matrices to apply to camera and gizmos - */ - applyTransformMatrix( transformation ) { - - 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(); //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 ); - - } - - } - - 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(); - - } - - 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 ); - const bb = new THREE.Box3(); - bb.setFromObject( this._gizmos ); - const sphere = new THREE.Sphere(); - bb.getBoundingSphere( sphere ); - const adjustedNearPosition = Math.max( this._nearPos0, sphere.radius + sphere.center.length() ); - const regularNearPosition = cameraDistance - this._initialNear; - const minNearPos = Math.min( adjustedNearPosition, regularNearPosition ); - this.camera.near = cameraDistance - minNearPos; - const adjustedFarPosition = Math.min( this._farPos0, - sphere.radius + sphere.center.length() ); - const regularFarPosition = cameraDistance - this._initialFar; - const minFarPos = Math.min( adjustedFarPosition, regularFarPosition ); - this.camera.far = cameraDistance - minFarPos; - this.camera.updateProjectionMatrix(); - - } else { - - let update = false; - - if ( this.camera.near != this._initialNear ) { - - this.camera.near = this._initialNear; - update = true; - - } - - if ( this.camera.far != this._initialFar ) { - - this.camera.far = this._initialFar; - update = true; - - } - - if ( update ) { - - this.camera.updateProjectionMatrix(); - - } - - } - - } - - } - /** - * Calculate the angular speed - * @param {Number} p0 Position at t0 - * @param {Number} p1 Position at t1 - * @param {Number} t0 Initial time in milliseconds - * @param {Number} t1 Ending time in milliseconds - */ - - - /** - * Set gizmos visibility - * @param {Boolean} value Value of gizmos visibility - */ - setGizmosVisible( value ) { - - this._gizmos.visible = value; - this.dispatchEvent( _changeEvent ); - - } - /** - * Set gizmos radius factor and redraws gizmos - * @param {Float} value Value of radius factor - */ - - - setTbRadius( value ) { - - this.radiusFactor = value; - this._tbRadius = this.calculateTbRadius( this.camera ); - 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; - - } - - 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 - * @param {Matrix4} gizmos Transformation to be applied to gizmos - */ - setTransformationMatrices( camera = null, gizmos = null ) { - - if ( camera != null ) { - - if ( _transformation.camera != null ) { - - _transformation.camera.copy( camera ); - - } else { - - _transformation.camera = camera.clone(); - - } - - } else { - - _transformation.camera = null; - - } - - if ( gizmos != null ) { - - if ( _transformation.gizmos != null ) { - - _transformation.gizmos.copy( gizmos ); - - } else { - - _transformation.gizmos = gizmos.clone(); - - } - - } else { - - _transformation.gizmos = null; - - } - - } - /** - * 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 - * @param {Number} angle Angle in radians - * @returns The computed transormation matix - */ - - - getRaycaster() { - - return _raycaster; - - } - /** - * Unproject the cursor on the 3D object surface - * @param {Vector2} cursor Cursor coordinates in NDC - * @param {Camera} camera Virtual camera - * @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 deleted file mode 100644 index d034b641ad7ff1..00000000000000 --- a/examples/js/controls/DragControls.js +++ /dev/null @@ -1,230 +0,0 @@ -( 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 ) { - - super(); - _domElement.style.touchAction = 'none'; // disable touch scroll - - let _selected = null, - _hovered = null; - const _intersections = []; // - - const scope = this; - - function activate() { - - _domElement.addEventListener( 'pointermove', onPointerMove ); - - _domElement.addEventListener( 'pointerdown', onPointerDown ); - - _domElement.addEventListener( 'pointerup', onPointerCancel ); - - _domElement.addEventListener( 'pointerleave', onPointerCancel ); - - } - - function deactivate() { - - _domElement.removeEventListener( 'pointermove', onPointerMove ); - - _domElement.removeEventListener( 'pointerdown', onPointerDown ); - - _domElement.removeEventListener( 'pointerup', onPointerCancel ); - - _domElement.removeEventListener( 'pointerleave', onPointerCancel ); - - _domElement.style.cursor = ''; - - } - - function dispose() { - - deactivate(); - - } - - function getObjects() { - - return _objects; - - } - - function getRaycaster() { - - return _raycaster; - - } - - function onPointerMove( event ) { - - if ( scope.enabled === false ) return; - updatePointer( event ); - - _raycaster.setFromCamera( _pointer, _camera ); - - if ( _selected ) { - - if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { - - _selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) ); - - } - - scope.dispatchEvent( { - type: 'drag', - object: _selected - } ); - return; - - } // 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( { - type: 'hoveroff', - object: _hovered - } ); - _domElement.style.cursor = 'auto'; - _hovered = null; - - } - - if ( _hovered !== object ) { - - scope.dispatchEvent( { - type: 'hoveron', - object: object - } ); - _domElement.style.cursor = 'pointer'; - _hovered = object; - - } - - } else { - - if ( _hovered !== null ) { - - scope.dispatchEvent( { - type: 'hoveroff', - object: _hovered - } ); - _domElement.style.cursor = 'auto'; - _hovered = null; - - } - - } - - } - - } - - function onPointerDown( event ) { - - 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 ) ); - - } - - _domElement.style.cursor = 'move'; - scope.dispatchEvent( { - type: 'dragstart', - object: _selected - } ); - - } - - } - - function onPointerCancel() { - - if ( scope.enabled === false ) return; - - if ( _selected ) { - - scope.dispatchEvent( { - type: 'dragend', - object: _selected - } ); - _selected = null; - - } - - _domElement.style.cursor = _hovered ? 'pointer' : 'auto'; - - } - - 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 - - this.enabled = true; - this.transformGroup = false; - this.activate = activate; - this.deactivate = deactivate; - this.dispose = dispose; - this.getObjects = getObjects; - this.getRaycaster = getRaycaster; - - } - - } - - THREE.DragControls = DragControls; - -} )(); diff --git a/examples/js/controls/FirstPersonControls.js b/examples/js/controls/FirstPersonControls.js deleted file mode 100644 index f21b0f021bf266..00000000000000 --- a/examples/js/controls/FirstPersonControls.js +++ /dev/null @@ -1,341 +0,0 @@ -( 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.enabled = true; - this.movementSpeed = 1.0; - this.lookSpeed = 0.005; - this.lookVertical = true; - this.autoForward = false; - this.activeLook = true; - this.heightSpeed = false; - this.heightCoef = 1.0; - this.heightMin = 0.0; - this.heightMax = 1.0; - this.constrainVertical = false; - this.verticalMin = 0; - this.verticalMax = Math.PI; - this.mouseDragOn = false; // internals - - this.autoSpeedFactor = 0.0; - this.mouseX = 0; - this.mouseY = 0; - this.moveForward = false; - this.moveBackward = false; - this.moveLeft = false; - this.moveRight = false; - this.viewHalfX = 0; - this.viewHalfY = 0; // private variables - - let lat = 0; - let lon = 0; // - - this.handleResize = function () { - - if ( this.domElement === document ) { - - this.viewHalfX = window.innerWidth / 2; - this.viewHalfY = window.innerHeight / 2; - - } else { - - this.viewHalfX = this.domElement.offsetWidth / 2; - this.viewHalfY = this.domElement.offsetHeight / 2; - - } - - }; - - this.onMouseDown = function ( event ) { - - if ( this.domElement !== document ) { - - this.domElement.focus(); - - } - - if ( this.activeLook ) { - - switch ( event.button ) { - - case 0: - this.moveForward = true; - break; - - case 2: - this.moveBackward = true; - break; - - } - - } - - this.mouseDragOn = true; - - }; - - this.onMouseUp = function ( event ) { - - if ( this.activeLook ) { - - switch ( event.button ) { - - case 0: - this.moveForward = false; - break; - - case 2: - this.moveBackward = false; - break; - - } - - } - - this.mouseDragOn = false; - - }; - - this.onMouseMove = function ( event ) { - - if ( this.domElement === document ) { - - this.mouseX = event.pageX - this.viewHalfX; - this.mouseY = event.pageY - this.viewHalfY; - - } else { - - this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX; - this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY; - - } - - }; - - this.onKeyDown = function ( event ) { - - switch ( event.code ) { - - case 'ArrowUp': - 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; - - } - - }; - - this.onKeyUp = function ( event ) { - - switch ( event.code ) { - - case 'ArrowUp': - 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; - - } - - }; - - this.lookAt = function ( x, y, z ) { - - if ( x.isVector3 ) { - - _target.copy( x ); - - } else { - - _target.set( x, y, z ); - - } - - this.object.lookAt( _target ); - setOrientation( this ); - return this; - - }; - - this.update = function () { - - const targetPosition = new THREE.Vector3(); - 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 ); - const heightDelta = y - this.heightMin; - this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef ); - - } else { - - this.autoSpeedFactor = 0.0; - - } - - const actualMoveSpeed = delta * this.movementSpeed; - if ( this.moveForward || this.autoForward && ! this.moveBackward ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) ); - if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed ); - if ( this.moveLeft ) this.object.translateX( - actualMoveSpeed ); - if ( this.moveRight ) this.object.translateX( actualMoveSpeed ); - if ( this.moveUp ) this.object.translateY( actualMoveSpeed ); - if ( this.moveDown ) this.object.translateY( - actualMoveSpeed ); - let actualLookSpeed = delta * this.lookSpeed; - - if ( ! this.activeLook ) { - - actualLookSpeed = 0; - - } - - 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; - 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 ); - - } - - const position = this.object.position; - targetPosition.setFromSphericalCoords( 1, phi, theta ).add( position ); - this.object.lookAt( targetPosition ); - - }; - - }(); - - this.dispose = function () { - - this.domElement.removeEventListener( 'contextmenu', contextmenu ); - this.domElement.removeEventListener( 'mousedown', _onMouseDown ); - this.domElement.removeEventListener( 'mousemove', _onMouseMove ); - this.domElement.removeEventListener( 'mouseup', _onMouseUp ); - 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 _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 ); - 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 ); - - } - - this.handleResize(); - setOrientation( this ); - - } - - } - - function contextmenu( event ) { - - event.preventDefault(); - - } - - THREE.FirstPersonControls = FirstPersonControls; - -} )(); diff --git a/examples/js/controls/FlyControls.js b/examples/js/controls/FlyControls.js deleted file mode 100644 index 223915d7be29be..00000000000000 --- a/examples/js/controls/FlyControls.js +++ /dev/null @@ -1,355 +0,0 @@ -( function () { - - 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.movementSpeed = 1.0; - this.rollSpeed = 0.005; - this.dragToLook = false; - this.autoForward = false; // disable default target object behavior - // internals - - const scope = this; - const EPS = 0.000001; - const lastQuaternion = new THREE.Quaternion(); - const lastPosition = new THREE.Vector3(); - this.tmpQuaternion = new THREE.Quaternion(); - this.mouseStatus = 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 THREE.Vector3( 0, 0, 0 ); - this.rotationVector = new THREE.Vector3( 0, 0, 0 ); - - this.keydown = function ( event ) { - - if ( event.altKey ) { - - return; - - } - - switch ( event.code ) { - - case 'ShiftLeft': - 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; - - } - - this.updateMovementVector(); - this.updateRotationVector(); - - }; - - this.keyup = function ( event ) { - - switch ( event.code ) { - - case 'ShiftLeft': - 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; - - } - - this.updateMovementVector(); - this.updateRotationVector(); - - }; - - this.mousedown = function ( event ) { - - if ( this.dragToLook ) { - - this.mouseStatus ++; - - } else { - - switch ( event.button ) { - - case 0: - this.moveState.forward = 1; - break; - - case 2: - this.moveState.back = 1; - break; - - } - - this.updateMovementVector(); - - } - - }; - - this.mousemove = function ( event ) { - - if ( ! this.dragToLook || this.mouseStatus > 0 ) { - - const container = this.getContainerDimensions(); - const halfWidth = container.size[ 0 ] / 2; - const halfHeight = container.size[ 1 ] / 2; - this.moveState.yawLeft = - ( event.pageX - container.offset[ 0 ] - halfWidth ) / halfWidth; - this.moveState.pitchDown = ( event.pageY - container.offset[ 1 ] - halfHeight ) / halfHeight; - this.updateRotationVector(); - - } - - }; - - this.mouseup = function ( event ) { - - if ( this.dragToLook ) { - - this.mouseStatus --; - this.moveState.yawLeft = this.moveState.pitchDown = 0; - - } else { - - switch ( event.button ) { - - case 0: - this.moveState.forward = 0; - break; - - case 2: - this.moveState.back = 0; - break; - - } - - this.updateMovementVector(); - - } - - this.updateRotationVector(); - - }; - - this.update = function ( delta ) { - - const moveMult = delta * scope.movementSpeed; - const rotMult = delta * scope.rollSpeed; - scope.object.translateX( scope.moveVector.x * moveMult ); - scope.object.translateY( scope.moveVector.y * moveMult ); - 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 ); - lastQuaternion.copy( scope.object.quaternion ); - lastPosition.copy( scope.object.position ); - - } - - }; - - this.updateMovementVector = function () { - - 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.updateRotationVector = function () { - - 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.getContainerDimensions = function () { - - if ( this.domElement != document ) { - - return { - size: [ this.domElement.offsetWidth, this.domElement.offsetHeight ], - offset: [ this.domElement.offsetLeft, this.domElement.offsetTop ] - }; - - } else { - - return { - size: [ window.innerWidth, window.innerHeight ], - offset: [ 0, 0 ] - }; - - } - - }; - - this.dispose = function () { - - this.domElement.removeEventListener( 'contextmenu', contextmenu ); - this.domElement.removeEventListener( 'mousedown', _mousedown ); - this.domElement.removeEventListener( 'mousemove', _mousemove ); - this.domElement.removeEventListener( 'mouseup', _mouseup ); - 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 _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 ); - window.addEventListener( 'keydown', _keydown ); - window.addEventListener( 'keyup', _keyup ); - this.updateMovementVector(); - this.updateRotationVector(); - - } - - } - - function contextmenu( event ) { - - event.preventDefault(); - - } - - THREE.FlyControls = FlyControls; - -} )(); diff --git a/examples/js/controls/OrbitControls.js b/examples/js/controls/OrbitControls.js deleted file mode 100644 index fc3a1cd6bafdc4..00000000000000 --- a/examples/js/controls/OrbitControls.js +++ /dev/null @@ -1,1079 +0,0 @@ -( function () { - - // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default). - // - // Orbit - left mouse / touch: one-finger move - // Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish - // Pan - right mouse, or left mouse + ctrl/meta/shiftKey, or arrow keys / touch: two-finger move - - const _changeEvent = { - type: 'change' - }; - const _startEvent = { - type: 'start' - }; - 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 - - 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.minZoom = 0; - 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.enableZoom = true; - this.zoomSpeed = 1.0; // Set to false to disable rotating - - this.enableRotate = true; - 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 - - this.keys = { - LEFT: 'ArrowLeft', - UP: 'ArrowUp', - RIGHT: 'ArrowRight', - BOTTOM: 'ArrowDown' - }; // Mouse buttons - - this.mouseButtons = { - LEFT: THREE.MOUSE.ROTATE, - MIDDLE: THREE.MOUSE.DOLLY, - RIGHT: THREE.MOUSE.PAN - }; // Touch fingers - - this.touches = { - ONE: THREE.TOUCH.ROTATE, - TWO: THREE.TOUCH.DOLLY_PAN - }; // 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._domElementKeyEvents = null; // - // public methods - // - - this.getPolarAngle = function () { - - return spherical.phi; - - }; - - this.getAzimuthalAngle = function () { - - return spherical.theta; - - }; - - this.getDistance = function () { - - return this.object.position.distanceTo( this.target ); - - }; - - this.listenToKeyEvents = function ( domElement ) { - - domElement.addEventListener( 'keydown', onKeyDown ); - this._domElementKeyEvents = domElement; - - }; - - this.saveState = function () { - - scope.target0.copy( scope.target ); - scope.position0.copy( scope.object.position ); - scope.zoom0 = scope.object.zoom; - - }; - - this.reset = function () { - - scope.target.copy( scope.target0 ); - scope.object.position.copy( scope.position0 ); - scope.object.zoom = scope.zoom0; - scope.object.updateProjectionMatrix(); - scope.dispatchEvent( _changeEvent ); - scope.update(); - state = STATE.NONE; - - }; // 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 quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) ); - const quatInverse = quat.clone().invert(); - const lastPosition = new THREE.Vector3(); - const lastQuaternion = new THREE.Quaternion(); - const twoPI = 2 * Math.PI; - return function update() { - - const position = scope.object.position; - offset.copy( position ).sub( scope.target ); // 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() ); - - } - - if ( scope.enableDamping ) { - - spherical.theta += sphericalDelta.theta * scope.dampingFactor; - spherical.phi += sphericalDelta.phi * scope.dampingFactor; - - } else { - - spherical.theta += sphericalDelta.theta; - spherical.phi += sphericalDelta.phi; - - } // 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 ) ); - - } else { - - spherical.theta = spherical.theta > ( min + max ) / 2 ? Math.max( min, spherical.theta ) : Math.min( max, spherical.theta ); - - } - - } // 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 = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) ); // move target to panned location - - if ( scope.enableDamping === true ) { - - scope.target.addScaledVector( panOffset, scope.dampingFactor ); - - } else { - - scope.target.add( panOffset ); - - } - - 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; - sphericalDelta.phi *= 1 - scope.dampingFactor; - panOffset.multiplyScalar( 1 - scope.dampingFactor ); - - } else { - - sphericalDelta.set( 0, 0, 0 ); - panOffset.set( 0, 0, 0 ); - - } - - 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 - - if ( zoomChanged || lastPosition.distanceToSquared( scope.object.position ) > EPS || 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) { - - scope.dispatchEvent( _changeEvent ); - lastPosition.copy( scope.object.position ); - lastQuaternion.copy( scope.object.quaternion ); - zoomChanged = false; - return true; - - } - - return false; - - }; - - }(); - - this.dispose = function () { - - scope.domElement.removeEventListener( 'contextmenu', onContextMenu ); - scope.domElement.removeEventListener( 'pointerdown', onPointerDown ); - scope.domElement.removeEventListener( 'pointercancel', onPointerCancel ); - 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? - - }; // - // internals - // - - - const scope = this; - const STATE = { - NONE: - 1, - ROTATE: 0, - DOLLY: 1, - PAN: 2, - TOUCH_ROTATE: 3, - TOUCH_PAN: 4, - TOUCH_DOLLY_PAN: 5, - TOUCH_DOLLY_ROTATE: 6 - }; - let state = STATE.NONE; - const EPS = 0.000001; // current position in spherical coordinates - - const spherical = new THREE.Spherical(); - const sphericalDelta = new THREE.Spherical(); - let scale = 1; - const panOffset = new THREE.Vector3(); - let zoomChanged = false; - const rotateStart = new THREE.Vector2(); - const rotateEnd = new THREE.Vector2(); - const rotateDelta = new THREE.Vector2(); - const panStart = new THREE.Vector2(); - const panEnd = new THREE.Vector2(); - const panDelta = new THREE.Vector2(); - const dollyStart = new THREE.Vector2(); - const dollyEnd = new THREE.Vector2(); - const dollyDelta = new THREE.Vector2(); - const pointers = []; - const pointerPositions = {}; - - function getAutoRotationAngle() { - - return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; - - } - - function getZoomScale() { - - return Math.pow( 0.95, scope.zoomSpeed ); - - } - - function rotateLeft( angle ) { - - sphericalDelta.theta -= angle; - - } - - function rotateUp( angle ) { - - sphericalDelta.phi -= angle; - - } - - const panLeft = function () { - - const v = new THREE.Vector3(); - 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(); - return function panUp( distance, objectMatrix ) { - - if ( scope.screenSpacePanning === true ) { - - v.setFromMatrixColumn( objectMatrix, 1 ); - - } else { - - v.setFromMatrixColumn( objectMatrix, 0 ); - v.crossVectors( scope.object.up, v ); - - } - - v.multiplyScalar( distance ); - panOffset.add( v ); - - }; - - }(); // 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 - - 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 ); - - } else if ( scope.object.isOrthographicCamera ) { - - // orthographic - panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix ); - panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix ); - - } else { - - // camera neither orthographic nor perspective - console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' ); - scope.enablePan = false; - - } - - }; - - }(); - - function dollyOut( dollyScale ) { - - if ( scope.object.isPerspectiveCamera ) { - - scale /= dollyScale; - - } else if ( scope.object.isOrthographicCamera ) { - - scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) ); - scope.object.updateProjectionMatrix(); - zoomChanged = true; - - } else { - - console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); - scope.enableZoom = false; - - } - - } - - function dollyIn( dollyScale ) { - - if ( scope.object.isPerspectiveCamera ) { - - scale *= dollyScale; - - } else if ( scope.object.isOrthographicCamera ) { - - scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) ); - scope.object.updateProjectionMatrix(); - zoomChanged = true; - - } else { - - console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); - scope.enableZoom = false; - - } - - } // - // event callbacks - update the object state - // - - - function handleMouseDownRotate( event ) { - - rotateStart.set( event.clientX, event.clientY ); - - } - - function handleMouseDownDolly( event ) { - - dollyStart.set( event.clientX, event.clientY ); - - } - - function handleMouseDownPan( event ) { - - panStart.set( event.clientX, event.clientY ); - - } - - function handleMouseMoveRotate( event ) { - - rotateEnd.set( event.clientX, event.clientY ); - rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); - const element = scope.domElement; - rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height - - rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); - rotateStart.copy( rotateEnd ); - scope.update(); - - } - - function handleMouseMoveDolly( event ) { - - dollyEnd.set( event.clientX, event.clientY ); - dollyDelta.subVectors( dollyEnd, dollyStart ); - - if ( dollyDelta.y > 0 ) { - - dollyOut( getZoomScale() ); - - } else if ( dollyDelta.y < 0 ) { - - dollyIn( getZoomScale() ); - - } - - dollyStart.copy( dollyEnd ); - scope.update(); - - } - - function handleMouseMovePan( event ) { - - panEnd.set( event.clientX, event.clientY ); - panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); - pan( panDelta.x, panDelta.y ); - panStart.copy( panEnd ); - scope.update(); - - } - - function handleMouseWheel( event ) { - - if ( event.deltaY < 0 ) { - - dollyIn( getZoomScale() ); - - } else if ( event.deltaY > 0 ) { - - dollyOut( getZoomScale() ); - - } - - scope.update(); - - } - - function handleKeyDown( event ) { - - let needsUpdate = false; - - switch ( event.code ) { - - case scope.keys.UP: - pan( 0, scope.keyPanSpeed ); - needsUpdate = true; - break; - - case scope.keys.BOTTOM: - pan( 0, - scope.keyPanSpeed ); - needsUpdate = true; - break; - - case scope.keys.LEFT: - pan( scope.keyPanSpeed, 0 ); - needsUpdate = true; - break; - - case scope.keys.RIGHT: - pan( - scope.keyPanSpeed, 0 ); - needsUpdate = true; - break; - - } - - if ( needsUpdate ) { - - // prevent the browser from scrolling on cursor keys - event.preventDefault(); - scope.update(); - - } - - } - - function handleTouchStartRotate() { - - if ( pointers.length === 1 ) { - - rotateStart.set( pointers[ 0 ].pageX, pointers[ 0 ].pageY ); - - } else { - - const x = 0.5 * ( pointers[ 0 ].pageX + pointers[ 1 ].pageX ); - const y = 0.5 * ( pointers[ 0 ].pageY + pointers[ 1 ].pageY ); - rotateStart.set( x, y ); - - } - - } - - function handleTouchStartPan() { - - if ( pointers.length === 1 ) { - - panStart.set( pointers[ 0 ].pageX, pointers[ 0 ].pageY ); - - } else { - - const x = 0.5 * ( pointers[ 0 ].pageX + pointers[ 1 ].pageX ); - const y = 0.5 * ( pointers[ 0 ].pageY + pointers[ 1 ].pageY ); - panStart.set( x, y ); - - } - - } - - function handleTouchStartDolly() { - - const dx = pointers[ 0 ].pageX - pointers[ 1 ].pageX; - const dy = pointers[ 0 ].pageY - pointers[ 1 ].pageY; - const distance = Math.sqrt( dx * dx + dy * dy ); - dollyStart.set( 0, distance ); - - } - - function handleTouchStartDollyPan() { - - if ( scope.enableZoom ) handleTouchStartDolly(); - if ( scope.enablePan ) handleTouchStartPan(); - - } - - function handleTouchStartDollyRotate() { - - if ( scope.enableZoom ) handleTouchStartDolly(); - if ( scope.enableRotate ) handleTouchStartRotate(); - - } - - function handleTouchMoveRotate( event ) { - - if ( pointers.length == 1 ) { - - rotateEnd.set( event.pageX, event.pageY ); - - } else { - - const position = getSecondPointerPosition( event ); - const x = 0.5 * ( event.pageX + position.x ); - const y = 0.5 * ( event.pageY + position.y ); - rotateEnd.set( x, y ); - - } - - rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); - const element = scope.domElement; - rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height - - rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); - rotateStart.copy( rotateEnd ); - - } - - function handleTouchMovePan( event ) { - - if ( pointers.length === 1 ) { - - panEnd.set( event.pageX, event.pageY ); - - } else { - - const position = getSecondPointerPosition( event ); - const x = 0.5 * ( event.pageX + position.x ); - const y = 0.5 * ( event.pageY + position.y ); - panEnd.set( x, y ); - - } - - panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); - pan( panDelta.x, panDelta.y ); - panStart.copy( panEnd ); - - } - - function handleTouchMoveDolly( event ) { - - const position = getSecondPointerPosition( event ); - const dx = event.pageX - position.x; - const dy = event.pageY - position.y; - const distance = Math.sqrt( dx * dx + dy * dy ); - dollyEnd.set( 0, distance ); - dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) ); - dollyOut( dollyDelta.y ); - dollyStart.copy( dollyEnd ); - - } - - function handleTouchMoveDollyPan( event ) { - - if ( scope.enableZoom ) handleTouchMoveDolly( event ); - if ( scope.enablePan ) handleTouchMovePan( event ); - - } - - function handleTouchMoveDollyRotate( event ) { - - 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 ); - - } else { - - onMouseDown( event ); - - } - - } - - function onPointerMove( event ) { - - if ( scope.enabled === false ) return; - - if ( event.pointerType === 'touch' ) { - - onTouchMove( event ); - - } else { - - onMouseMove( event ); - - } - - } - - function onPointerUp( event ) { - - removePointer( event ); - - if ( pointers.length === 0 ) { - - scope.domElement.releasePointerCapture( event.pointerId ); - scope.domElement.removeEventListener( 'pointermove', onPointerMove ); - scope.domElement.removeEventListener( 'pointerup', onPointerUp ); - - } - - scope.dispatchEvent( _endEvent ); - state = STATE.NONE; - - } - - function onPointerCancel( event ) { - - removePointer( event ); - - } - - 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; - - } - - switch ( mouseAction ) { - - case THREE.MOUSE.DOLLY: - if ( scope.enableZoom === false ) return; - handleMouseDownDolly( event ); - state = STATE.DOLLY; - break; - - case THREE.MOUSE.ROTATE: - if ( event.ctrlKey || event.metaKey || event.shiftKey ) { - - if ( scope.enablePan === false ) return; - handleMouseDownPan( event ); - state = STATE.PAN; - - } else { - - if ( scope.enableRotate === false ) return; - handleMouseDownRotate( event ); - state = STATE.ROTATE; - - } - - break; - - case THREE.MOUSE.PAN: - if ( event.ctrlKey || event.metaKey || event.shiftKey ) { - - if ( scope.enableRotate === false ) return; - handleMouseDownRotate( event ); - state = STATE.ROTATE; - - } else { - - if ( scope.enablePan === false ) return; - handleMouseDownPan( event ); - state = STATE.PAN; - - } - - break; - - default: - state = STATE.NONE; - - } - - if ( state !== STATE.NONE ) { - - scope.dispatchEvent( _startEvent ); - - } - - } - - function onMouseMove( event ) { - - if ( scope.enabled === false ) return; - - switch ( state ) { - - case STATE.ROTATE: - 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 ); - break; - - } - - } - - function onMouseWheel( event ) { - - if ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE ) return; - event.preventDefault(); - scope.dispatchEvent( _startEvent ); - handleMouseWheel( event ); - scope.dispatchEvent( _endEvent ); - - } - - function onKeyDown( event ) { - - if ( scope.enabled === false || scope.enablePan === false ) return; - handleKeyDown( event ); - - } - - function onTouchStart( event ) { - - trackPointer( event ); - - switch ( pointers.length ) { - - case 1: - switch ( scope.touches.ONE ) { - - case THREE.TOUCH.ROTATE: - if ( scope.enableRotate === false ) return; - 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 ) { - - case THREE.TOUCH.DOLLY_PAN: - if ( scope.enableZoom === false && scope.enablePan === false ) return; - 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; - - } - - if ( state !== STATE.NONE ) { - - scope.dispatchEvent( _startEvent ); - - } - - } - - function onTouchMove( event ) { - - trackPointer( event ); - - switch ( state ) { - - case STATE.TOUCH_ROTATE: - if ( scope.enableRotate === false ) return; - 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; - - } - - } - - function onContextMenu( event ) { - - if ( scope.enabled === false ) return; - event.preventDefault(); - - } - - function addPointer( event ) { - - pointers.push( event ); - - } - - 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; - - } - - } - - } - - function trackPointer( event ) { - - let position = pointerPositions[ event.pointerId ]; - - if ( position === undefined ) { - - position = new THREE.Vector2(); - pointerPositions[ event.pointerId ] = position; - - } - - position.set( event.pageX, event.pageY ); - - } - - function getSecondPointerPosition( event ) { - - 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 - - this.update(); - - } - - } // 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 - // - // Orbit - right mouse, or left mouse + ctrl/meta/shiftKey / touch: two-finger rotate - // 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 ) { - - super( object, domElement ); - this.screenSpacePanning = false; // pan orthogonal to world-space direction camera.up - - this.mouseButtons.LEFT = THREE.MOUSE.PAN; - this.mouseButtons.RIGHT = THREE.MOUSE.ROTATE; - this.touches.ONE = THREE.TOUCH.PAN; - this.touches.TWO = THREE.TOUCH.DOLLY_ROTATE; - - } - - } - - THREE.MapControls = MapControls; - THREE.OrbitControls = OrbitControls; - -} )(); diff --git a/examples/js/controls/PointerLockControls.js b/examples/js/controls/PointerLockControls.js deleted file mode 100644 index a329286f5862ea..00000000000000 --- a/examples/js/controls/PointerLockControls.js +++ /dev/null @@ -1,161 +0,0 @@ -( function () { - - const _euler = new THREE.Euler( 0, 0, 0, 'YXZ' ); - - const _vector = new THREE.Vector3(); - - const _changeEvent = { - type: 'change' - }; - const _lockEvent = { - type: 'lock' - }; - 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.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 ) ); - camera.quaternion.setFromEuler( _euler ); - scope.dispatchEvent( _changeEvent ); - - } - - function onPointerlockChange() { - - if ( scope.domElement.ownerDocument.pointerLockElement === scope.domElement ) { - - scope.dispatchEvent( _lockEvent ); - scope.isLocked = true; - - } else { - - scope.dispatchEvent( _unlockEvent ); - scope.isLocked = false; - - } - - } - - function onPointerlockError() { - - console.error( 'THREE.PointerLockControls: Unable to use Pointer Lock API' ); - - } - - this.connect = function () { - - scope.domElement.ownerDocument.addEventListener( 'mousemove', onMouseMove ); - scope.domElement.ownerDocument.addEventListener( 'pointerlockchange', onPointerlockChange ); - scope.domElement.ownerDocument.addEventListener( 'pointerlockerror', onPointerlockError ); - - }; - - this.disconnect = function () { - - scope.domElement.ownerDocument.removeEventListener( 'mousemove', onMouseMove ); - scope.domElement.ownerDocument.removeEventListener( 'pointerlockchange', onPointerlockChange ); - scope.domElement.ownerDocument.removeEventListener( 'pointerlockerror', onPointerlockError ); - - }; - - this.dispose = function () { - - this.disconnect(); - - }; - - this.getObject = function () { - - // retaining this method for backward compatibility - return camera; - - }; - - this.getDirection = function () { - - const direction = new THREE.Vector3( 0, 0, - 1 ); - return function ( v ) { - - return v.copy( direction ).applyQuaternion( camera.quaternion ); - - }; - - }(); - - this.moveForward = function ( distance ) { - - // move forward parallel to the xz-plane - // assumes camera.up is y-up - _vector.setFromMatrixColumn( camera.matrix, 0 ); - - _vector.crossVectors( camera.up, _vector ); - - camera.position.addScaledVector( _vector, distance ); - - }; - - this.moveRight = function ( distance ) { - - _vector.setFromMatrixColumn( camera.matrix, 0 ); - - camera.position.addScaledVector( _vector, distance ); - - }; - - this.lock = function () { - - this.domElement.requestPointerLock(); - - }; - - this.unlock = function () { - - scope.domElement.ownerDocument.exitPointerLock(); - - }; - - this.connect(); - - } - - } - - THREE.PointerLockControls = PointerLockControls; - -} )(); diff --git a/examples/js/controls/TrackballControls.js b/examples/js/controls/TrackballControls.js deleted file mode 100644 index 54a1acaa0b1479..00000000000000 --- a/examples/js/controls/TrackballControls.js +++ /dev/null @@ -1,784 +0,0 @@ -( function () { - - const _changeEvent = { - type: 'change' - }; - const _startEvent = { - type: 'start' - }; - 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, - ROTATE: 0, - ZOOM: 1, - PAN: 2, - TOUCH_ROTATE: 3, - TOUCH_ZOOM_PAN: 4 - }; - this.object = object; - this.domElement = domElement; - this.domElement.style.touchAction = 'none'; // disable touch scroll - // API - - this.enabled = true; - this.screen = { - left: 0, - top: 0, - width: 0, - height: 0 - }; - this.rotateSpeed = 1.0; - this.zoomSpeed = 1.2; - this.panSpeed = 0.3; - this.noRotate = false; - this.noZoom = false; - this.noPan = false; - this.staticMoving = false; - this.dynamicDampingFactor = 0.2; - this.minDistance = 0; - this.maxDistance = Infinity; - this.keys = [ 'KeyA', - /*A*/ - 'KeyS', - /*S*/ - 'KeyD' - /*D*/ - ]; - this.mouseButtons = { - LEFT: THREE.MOUSE.ROTATE, - MIDDLE: THREE.MOUSE.DOLLY, - RIGHT: THREE.MOUSE.PAN - }; // internals - - this.target = new THREE.Vector3(); - const EPS = 0.000001; - const lastPosition = new THREE.Vector3(); - let lastZoom = 1; - let _state = STATE.NONE, - _keyState = STATE.NONE, - _touchZoomDistanceStart = 0, - _touchZoomDistanceEnd = 0, - _lastAngle = 0; - - const _eye = new THREE.Vector3(), - _movePrev = new THREE.Vector2(), - _moveCurr = new THREE.Vector2(), - _lastAxis = new THREE.Vector3(), - _zoomStart = new THREE.Vector2(), - _zoomEnd = new THREE.Vector2(), - _panStart = new THREE.Vector2(), - _panEnd = new THREE.Vector2(), - _pointers = [], - _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.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; - scope.screen.width = box.width; - scope.screen.height = box.height; - - }; - - const getMouseOnScreen = function () { - - const vector = new THREE.Vector2(); - return function getMouseOnScreen( pageX, pageY ) { - - vector.set( ( pageX - scope.screen.left ) / scope.screen.width, ( pageY - scope.screen.top ) / scope.screen.height ); - return vector; - - }; - - }(); - - const getMouseOnCircle = function () { - - const vector = new THREE.Vector2(); - return function getMouseOnCircle( pageX, pageY ) { - - 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(), - quaternion = new THREE.Quaternion(), - eyeDirection = new THREE.Vector3(), - objectUpDirection = new THREE.Vector3(), - objectSidewaysDirection = new THREE.Vector3(), - moveDirection = new THREE.Vector3(); - return function rotateCamera() { - - 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(); - objectUpDirection.setLength( _moveCurr.y - _movePrev.y ); - objectSidewaysDirection.setLength( _moveCurr.x - _movePrev.x ); - moveDirection.copy( objectUpDirection.add( objectSidewaysDirection ) ); - 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 ); - - } - - _movePrev.copy( _moveCurr ); - - }; - - }(); - - this.zoomCamera = function () { - - let factor; - - if ( _state === STATE.TOUCH_ZOOM_PAN ) { - - factor = _touchZoomDistanceStart / _touchZoomDistanceEnd; - _touchZoomDistanceStart = _touchZoomDistanceEnd; - - if ( scope.object.isPerspectiveCamera ) { - - _eye.multiplyScalar( factor ); - - } else if ( scope.object.isOrthographicCamera ) { - - scope.object.zoom /= factor; - scope.object.updateProjectionMatrix(); - - } else { - - console.warn( 'THREE.TrackballControls: Unsupported camera type' ); - - } - - } else { - - factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * scope.zoomSpeed; - - if ( factor !== 1.0 && factor > 0.0 ) { - - if ( scope.object.isPerspectiveCamera ) { - - _eye.multiplyScalar( factor ); - - } else if ( scope.object.isOrthographicCamera ) { - - scope.object.zoom /= factor; - scope.object.updateProjectionMatrix(); - - } else { - - console.warn( 'THREE.TrackballControls: Unsupported camera type' ); - - } - - } - - if ( scope.staticMoving ) { - - _zoomStart.copy( _zoomEnd ); - - } else { - - _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor; - - } - - } - - }; - - this.panCamera = function () { - - const mouseChange = new THREE.Vector2(), - objectUp = new THREE.Vector3(), - pan = new THREE.Vector3(); - return function panCamera() { - - mouseChange.copy( _panEnd ).sub( _panStart ); - - if ( mouseChange.lengthSq() ) { - - if ( scope.object.isOrthographicCamera ) { - - const scale_x = ( scope.object.right - scope.object.left ) / scope.object.zoom / scope.domElement.clientWidth; - const scale_y = ( scope.object.top - scope.object.bottom ) / scope.object.zoom / scope.domElement.clientWidth; - mouseChange.x *= scale_x; - mouseChange.y *= scale_y; - - } - - mouseChange.multiplyScalar( _eye.length() * scope.panSpeed ); - pan.copy( _eye ).cross( scope.object.up ).setLength( mouseChange.x ); - 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 ); - - } else { - - _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( scope.dynamicDampingFactor ) ); - - } - - } - - }; - - }(); - - this.checkDistances = function () { - - if ( ! scope.noZoom || ! scope.noPan ) { - - if ( _eye.lengthSq() > scope.maxDistance * scope.maxDistance ) { - - scope.object.position.addVectors( scope.target, _eye.setLength( scope.maxDistance ) ); - - _zoomStart.copy( _zoomEnd ); - - } - - if ( _eye.lengthSq() < scope.minDistance * scope.minDistance ) { - - scope.object.position.addVectors( scope.target, _eye.setLength( scope.minDistance ) ); - - _zoomStart.copy( _zoomEnd ); - - } - - } - - }; - - this.update = function () { - - _eye.subVectors( scope.object.position, scope.target ); - - if ( ! scope.noRotate ) { - - scope.rotateCamera(); - - } - - if ( ! scope.noZoom ) { - - scope.zoomCamera(); - - } - - if ( ! scope.noPan ) { - - scope.panCamera(); - - } - - 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 ); - lastPosition.copy( scope.object.position ); - - } - - } else if ( scope.object.isOrthographicCamera ) { - - scope.object.lookAt( scope.target ); - - if ( lastPosition.distanceToSquared( scope.object.position ) > EPS || lastZoom !== scope.object.zoom ) { - - scope.dispatchEvent( _changeEvent ); - lastPosition.copy( scope.object.position ); - lastZoom = scope.object.zoom; - - } - - } else { - - console.warn( 'THREE.TrackballControls: Unsupported camera type' ); - - } - - }; - - this.reset = function () { - - _state = STATE.NONE; - _keyState = STATE.NONE; - scope.target.copy( scope.target0 ); - scope.object.position.copy( scope.position0 ); - 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 - - - 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 ); - - } else { - - onMouseDown( event ); - - } - - } - - function onPointerMove( event ) { - - if ( scope.enabled === false ) return; - - if ( event.pointerType === 'touch' ) { - - onTouchMove( event ); - - } else { - - onMouseMove( event ); - - } - - } - - function onPointerUp( event ) { - - if ( scope.enabled === false ) return; - - if ( event.pointerType === 'touch' ) { - - onTouchEnd( event ); - - } else { - - onMouseUp(); - - } // - - - removePointer( event ); - - if ( _pointers.length === 0 ) { - - scope.domElement.releasePointerCapture( event.pointerId ); - scope.domElement.removeEventListener( 'pointermove', onPointerMove ); - scope.domElement.removeEventListener( 'pointerup', onPointerUp ); - - } - - } - - function onPointerCancel( event ) { - - removePointer( event ); - - } - - function keydown( event ) { - - if ( scope.enabled === false ) return; - window.removeEventListener( 'keydown', keydown ); - - if ( _keyState !== STATE.NONE ) { - - return; - - } else if ( event.code === scope.keys[ STATE.ROTATE ] && ! scope.noRotate ) { - - _keyState = STATE.ROTATE; - - } else if ( event.code === scope.keys[ STATE.ZOOM ] && ! scope.noZoom ) { - - _keyState = STATE.ZOOM; - - } else if ( event.code === scope.keys[ STATE.PAN ] && ! scope.noPan ) { - - _keyState = STATE.PAN; - - } - - } - - function keyup() { - - if ( scope.enabled === false ) return; - _keyState = STATE.NONE; - window.addEventListener( 'keydown', keydown ); - - } - - function onMouseDown( event ) { - - if ( _state === STATE.NONE ) { - - switch ( event.button ) { - - case scope.mouseButtons.LEFT: - _state = STATE.ROTATE; - break; - - case scope.mouseButtons.MIDDLE: - _state = STATE.ZOOM; - break; - - case scope.mouseButtons.RIGHT: - _state = STATE.PAN; - break; - - } - - } - - 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 ); - - } - - scope.dispatchEvent( _startEvent ); - - } - - 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 ) { - - _zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) ); - - } else if ( state === STATE.PAN && ! scope.noPan ) { - - _panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) ); - - } - - } - - function onMouseUp() { - - _state = STATE.NONE; - scope.dispatchEvent( _endEvent ); - - } - - function onMouseWheel( event ) { - - 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; - break; - - } - - scope.dispatchEvent( _startEvent ); - scope.dispatchEvent( _endEvent ); - - } - - 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; - const dx = _pointers[ 0 ].pageX - _pointers[ 1 ].pageX; - const dy = _pointers[ 0 ].pageY - _pointers[ 1 ].pageY; - _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; - - } - - scope.dispatchEvent( _startEvent ); - - } - - 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; - - } - - } - - function onTouchEnd( event ) { - - switch ( _pointers.length ) { - - 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; - - _moveCurr.copy( getMouseOnCircle( event.pageX - _movePrev.x, event.pageY - _movePrev.y ) ); - - _movePrev.copy( _moveCurr ); - - break; - - } - - scope.dispatchEvent( _endEvent ); - - } - - function contextmenu( event ) { - - if ( scope.enabled === false ) return; - event.preventDefault(); - - } - - function addPointer( event ) { - - _pointers.push( event ); - - } - - 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; - - } - - } - - } - - function trackPointer( event ) { - - let position = _pointerPositions[ event.pointerId ]; - - if ( position === undefined ) { - - position = new THREE.Vector2(); - _pointerPositions[ event.pointerId ] = position; - - } - - position.set( event.pageX, event.pageY ); - - } - - function getSecondPointerPosition( event ) { - - const pointer = event.pointerId === _pointers[ 0 ].pointerId ? _pointers[ 1 ] : _pointers[ 0 ]; - return _pointerPositions[ pointer.pointerId ]; - - } - - this.dispose = function () { - - scope.domElement.removeEventListener( 'contextmenu', contextmenu ); - scope.domElement.removeEventListener( 'pointerdown', onPointerDown ); - scope.domElement.removeEventListener( 'pointercancel', onPointerCancel ); - scope.domElement.removeEventListener( 'wheel', onMouseWheel ); - scope.domElement.removeEventListener( 'pointermove', onPointerMove ); - scope.domElement.removeEventListener( 'pointerup', onPointerUp ); - window.removeEventListener( 'keydown', keydown ); - window.removeEventListener( 'keyup', keyup ); - - }; - - this.domElement.addEventListener( 'contextmenu', contextmenu ); - this.domElement.addEventListener( 'pointerdown', onPointerDown ); - this.domElement.addEventListener( 'pointercancel', onPointerCancel ); - this.domElement.addEventListener( 'wheel', onMouseWheel, { - passive: false - } ); - window.addEventListener( 'keydown', keydown ); - window.addEventListener( 'keyup', keyup ); - this.handleResize(); // force an update at start - - this.update(); - - } - - } - - THREE.TrackballControls = TrackballControls; - -} )(); diff --git a/examples/js/controls/TransformControls.js b/examples/js/controls/TransformControls.js deleted file mode 100644 index 3de1ad1ed756c8..00000000000000 --- a/examples/js/controls/TransformControls.js +++ /dev/null @@ -1,1382 +0,0 @@ -( 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 ), - Z: new THREE.Vector3( 0, 0, 1 ) - }; - const _changeEvent = { - type: 'change' - }; - const _mouseDownEvent = { - type: 'mouseDown' - }; - const _mouseUpEvent = { - type: 'mouseUp', - mode: null - }; - 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.' ); - domElement = document; - - } - - this.isTransformControls = true; - this.visible = false; - this.domElement = domElement; - 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 - - function defineProperty( propName, defaultValue ) { - - let propValue = defaultValue; - Object.defineProperty( scope, propName, { - get: function () { - - return propValue !== undefined ? propValue : defaultValue; - - }, - set: function ( value ) { - - if ( propValue !== value ) { - - propValue = value; - _plane[ propName ] = value; - _gizmo[ propName ] = value; - scope.dispatchEvent( { - type: propName + '-changed', - value: value - } ); - scope.dispatchEvent( _changeEvent ); - - } - - } - } ); - scope[ propName ] = defaultValue; - _plane[ propName ] = defaultValue; - _gizmo[ propName ] = defaultValue; - - } // 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 ); - defineProperty( 'axis', null ); - defineProperty( 'mode', 'translate' ); - defineProperty( 'translationSnap', null ); - defineProperty( 'rotationSnap', null ); - defineProperty( 'scaleSnap', null ); - defineProperty( 'space', 'world' ); - defineProperty( 'size', 1 ); - defineProperty( 'dragging', false ); - defineProperty( 'showX', true ); - defineProperty( 'showY', true ); - defineProperty( 'showZ', true ); // Reusable utility variables - - const worldPosition = new THREE.Vector3(); - const worldPositionStart = new THREE.Vector3(); - const worldQuaternion = new THREE.Quaternion(); - const worldQuaternionStart = new THREE.Quaternion(); - const cameraPosition = new THREE.Vector3(); - const cameraQuaternion = new THREE.Quaternion(); - const pointStart = new THREE.Vector3(); - 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 - - defineProperty( 'worldPosition', worldPosition ); - defineProperty( 'worldPositionStart', worldPositionStart ); - defineProperty( 'worldQuaternion', worldQuaternion ); - defineProperty( 'worldQuaternionStart', worldQuaternionStart ); - defineProperty( 'cameraPosition', cameraPosition ); - defineProperty( 'cameraQuaternion', cameraQuaternion ); - defineProperty( 'pointStart', pointStart ); - defineProperty( 'pointEnd', pointEnd ); - defineProperty( 'rotationAxis', rotationAxis ); - defineProperty( 'rotationAngle', rotationAngle ); - defineProperty( 'eye', eye ); - this._offset = new THREE.Vector3(); - this._startNorm = new THREE.Vector3(); - this._endNorm = new THREE.Vector3(); - this._cameraScale = new THREE.Vector3(); - this._parentPosition = new THREE.Vector3(); - this._parentQuaternion = new THREE.Quaternion(); - this._parentQuaternionInv = new THREE.Quaternion(); - this._parentScale = new THREE.Vector3(); - this._worldScaleStart = new THREE.Vector3(); - this._worldQuaternionInv = new THREE.Quaternion(); - this._worldScale = new THREE.Vector3(); - this._positionStart = new THREE.Vector3(); - this._quaternionStart = new THREE.Quaternion(); - this._scaleStart = new THREE.Vector3(); - this._getPointer = getPointer.bind( this ); - this._onPointerDown = onPointerDown.bind( this ); - this._onPointerHover = onPointerHover.bind( this ); - this._onPointerMove = onPointerMove.bind( this ); - this._onPointerUp = onPointerUp.bind( this ); - this.domElement.addEventListener( 'pointerdown', this._onPointerDown ); - this.domElement.addEventListener( 'pointermove', this._onPointerHover ); - this.domElement.addEventListener( 'pointerup', this._onPointerUp ); - - } // 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.' ); - - } else { - - this.object.parent.matrixWorld.decompose( this._parentPosition, this._parentQuaternion, this._parentScale ); - - } - - 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 ); - this.eye.copy( this.cameraPosition ).sub( this.worldPosition ).normalize(); - 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; - - } else { - - this.axis = null; - - } - - } - - 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 ); - - } - - this.dragging = true; - _mouseDownEvent.mode = this.mode; - this.dispatchEvent( _mouseDownEvent ); - - } - - } - - pointerMove( pointer ) { - - const axis = this.axis; - const mode = this.mode; - const object = this.object; - let space = this.space; - - if ( mode === 'scale' ) { - - space = 'local'; - - } else if ( axis === 'E' || axis === 'XYZE' || axis === 'XYZ' ) { - - space = 'world'; - - } - - 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 ); - - if ( space === 'local' && axis !== 'XYZ' ) { - - this._offset.applyQuaternion( this._worldQuaternionInv ); - - } - - 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 ); - - } else { - - this._offset.applyQuaternion( this._parentQuaternionInv ).divide( this._parentScale ); - - } - - 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; - - } - - if ( axis.search( 'Y' ) !== - 1 ) { - - object.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap; - - } - - if ( axis.search( 'Z' ) !== - 1 ) { - - object.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap; - - } - - object.position.applyQuaternion( this._quaternionStart ); - - } - - if ( space === 'world' ) { - - if ( object.parent ) { - - object.position.add( _tempVector.setFromMatrixPosition( object.parent.matrixWorld ) ); - - } - - if ( axis.search( 'X' ) !== - 1 ) { - - object.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap; - - } - - if ( axis.search( 'Y' ) !== - 1 ) { - - object.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap; - - } - - if ( axis.search( 'Z' ) !== - 1 ) { - - object.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap; - - } - - if ( object.parent ) { - - object.position.sub( _tempVector.setFromMatrixPosition( object.parent.matrixWorld ) ); - - } - - } - - } - - } else if ( mode === 'scale' ) { - - if ( axis.search( 'XYZ' ) !== - 1 ) { - - 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; - - } - - if ( axis.search( 'Y' ) === - 1 ) { - - _tempVector2.y = 1; - - } - - if ( axis.search( 'Z' ) === - 1 ) { - - _tempVector2.z = 1; - - } - - } // Apply scale - - - object.scale.copy( this._scaleStart ).multiply( _tempVector2 ); - - if ( this.scaleSnap ) { - - if ( axis.search( 'X' ) !== - 1 ) { - - object.scale.x = Math.round( object.scale.x / this.scaleSnap ) * this.scaleSnap || this.scaleSnap; - - } - - if ( axis.search( 'Y' ) !== - 1 ) { - - object.scale.y = Math.round( object.scale.y / this.scaleSnap ) * this.scaleSnap || this.scaleSnap; - - } - - if ( axis.search( 'Z' ) !== - 1 ) { - - object.scale.z = Math.round( object.scale.z / this.scaleSnap ) * this.scaleSnap || this.scaleSnap; - - } - - } - - } 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' ) { - - this.rotationAxis.copy( this._offset ).cross( this.eye ).normalize(); - this.rotationAngle = this._offset.dot( _tempVector.copy( this.rotationAxis ).cross( this.eye ) ) * ROTATION_SPEED; - - } else if ( axis === 'X' || axis === 'Y' || axis === 'Z' ) { - - this.rotationAxis.copy( _unit[ axis ] ); - - _tempVector.copy( _unit[ axis ] ); - - if ( space === 'local' ) { - - _tempVector.applyQuaternion( this.worldQuaternion ); - - } - - this.rotationAngle = this._offset.dot( _tempVector.cross( this.eye ).normalize() ) * ROTATION_SPEED; - - } // Apply rotation snap - - - 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 ); - object.quaternion.multiply( _tempQuaternion.setFromAxisAngle( this.rotationAxis, this.rotationAngle ) ).normalize(); - - } else { - - this.rotationAxis.applyQuaternion( this._parentQuaternionInv ); - object.quaternion.copy( _tempQuaternion.setFromAxisAngle( this.rotationAxis, this.rotationAngle ) ); - object.quaternion.multiply( this._quaternionStart ).normalize(); - - } - - } - - this.dispatchEvent( _changeEvent ); - this.dispatchEvent( _objectChangeEvent ); - - } - - pointerUp( pointer ) { - - if ( pointer.button !== 0 ) return; - - if ( this.dragging && this.axis !== null ) { - - _mouseUpEvent.mode = this.mode; - this.dispatchEvent( _mouseUpEvent ); - - } - - this.dragging = false; - this.axis = null; - - } - - dispose() { - - this.domElement.removeEventListener( 'pointerdown', this._onPointerDown ); - this.domElement.removeEventListener( 'pointermove', this._onPointerHover ); - this.domElement.removeEventListener( 'pointermove', this._onPointerMove ); - this.domElement.removeEventListener( 'pointerup', this._onPointerUp ); - this.traverse( function ( child ) { - - if ( child.geometry ) child.geometry.dispose(); - if ( child.material ) child.material.dispose(); - - } ); - - } // Set current object - - - attach( object ) { - - this.object = object; - this.visible = true; - return this; - - } // Detatch from object - - - detach() { - - this.object = undefined; - this.visible = false; - this.axis = null; - return this; - - } - - reset() { - - if ( ! this.enabled ) return; - - if ( this.dragging ) { - - this.object.position.copy( this._positionStart ); - this.object.quaternion.copy( this._quaternionStart ); - this.object.scale.copy( this._scaleStart ); - this.dispatchEvent( _changeEvent ); - this.dispatchEvent( _objectChangeEvent ); - this.pointStart.copy( this.pointEnd ); - - } - - } - - getRaycaster() { - - return _raycaster; - - } // 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 - - - function getPointer( event ) { - - if ( this.domElement.ownerDocument.pointerLockElement ) { - - return { - x: 0, - y: 0, - button: event.button - }; - - } else { - - const rect = this.domElement.getBoundingClientRect(); - return { - x: ( event.clientX - rect.left ) / rect.width * 2 - 1, - y: - ( event.clientY - rect.top ) / rect.height * 2 + 1, - button: event.button - }; - - } - - } - - function onPointerHover( event ) { - - if ( ! this.enabled ) return; - - switch ( event.pointerType ) { - - case 'mouse': - case 'pen': - this.pointerHover( this._getPointer( event ) ); - break; - - } - - } - - function onPointerDown( event ) { - - if ( ! this.enabled ) return; - - if ( ! document.pointerLockElement ) { - - this.domElement.setPointerCapture( event.pointerId ); - - } - - this.domElement.addEventListener( 'pointermove', this._onPointerMove ); - this.pointerHover( this._getPointer( event ) ); - this.pointerDown( this._getPointer( event ) ); - - } - - function onPointerMove( event ) { - - if ( ! this.enabled ) return; - this.pointerMove( this._getPointer( event ) ); - - } - - function onPointerUp( event ) { - - if ( ! this.enabled ) return; - this.domElement.releasePointerCapture( event.pointerId ); - this.domElement.removeEventListener( 'pointermove', this._onPointerMove ); - this.pointerUp( this._getPointer( event ) ); - - } - - 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 ) { - - return allIntersections[ i ]; - - } - - } - - return false; - - } // - // 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 - - const gizmoMaterial = new THREE.MeshBasicMaterial( { - depthTest: false, - depthWrite: false, - fog: false, - toneMapped: false, - transparent: true - } ); - const gizmoLineMaterial = new THREE.LineBasicMaterial( { - depthTest: false, - depthWrite: false, - fog: false, - toneMapped: false, - transparent: true - } ); // Make unique material for each axis/color - - const matInvisible = gizmoMaterial.clone(); - matInvisible.opacity = 0.15; - const matHelper = gizmoLineMaterial.clone(); - matHelper.opacity = 0.5; - const matRed = gizmoMaterial.clone(); - matRed.color.setHex( 0xff0000 ); - const matGreen = gizmoMaterial.clone(); - matGreen.color.setHex( 0x00ff00 ); - const matBlue = gizmoMaterial.clone(); - matBlue.color.setHex( 0x0000ff ); - const matRedTransparent = gizmoMaterial.clone(); - matRedTransparent.color.setHex( 0xff0000 ); - matRedTransparent.opacity = 0.5; - const matGreenTransparent = gizmoMaterial.clone(); - matGreenTransparent.color.setHex( 0x00ff00 ); - matGreenTransparent.opacity = 0.5; - const matBlueTransparent = gizmoMaterial.clone(); - matBlueTransparent.color.setHex( 0x0000ff ); - matBlueTransparent.opacity = 0.5; - const matWhiteTransparent = gizmoMaterial.clone(); - matWhiteTransparent.opacity = 0.25; - const matYellowTransparent = gizmoMaterial.clone(); - matYellowTransparent.color.setHex( 0xffff00 ); - matYellowTransparent.opacity = 0.25; - const matYellow = gizmoMaterial.clone(); - matYellow.color.setHex( 0xffff00 ); - const matGray = gizmoMaterial.clone(); - matGray.color.setHex( 0x787878 ); // reusable geometry - - const arrowGeometry = new THREE.CylinderGeometry( 0, 0.04, 0.1, 12 ); - arrowGeometry.translate( 0, 0.05, 0 ); - const scaleHandleGeometry = new THREE.BoxGeometry( 0.08, 0.08, 0.08 ); - scaleHandleGeometry.translate( 0, 0.04, 0 ); - const lineGeometry = new THREE.BufferGeometry(); - 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 ); - geometry.rotateY( Math.PI / 2 ); - 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 - - - function TranslateHelperGeometry() { - - const geometry = new THREE.BufferGeometry(); - geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 1, 1 ], 3 ) ); - return geometry; - - } // 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 ]]], - Y: [[ new THREE.Mesh( arrowGeometry, matGreen ), [ 0, 0.5, 0 ]], [ new THREE.Mesh( arrowGeometry, matGreen ), [ 0, - 0.5, 0 ], [ Math.PI, 0, 0 ]], [ new THREE.Mesh( lineGeometry2, matGreen ) ]], - Z: [[ new THREE.Mesh( arrowGeometry, matBlue ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ]], [ new THREE.Mesh( arrowGeometry, matBlue ), [ 0, 0, - 0.5 ], [ - Math.PI / 2, 0, 0 ]], [ new THREE.Mesh( lineGeometry2, matBlue ), null, [ Math.PI / 2, 0, 0 ]]], - XYZ: [[ new THREE.Mesh( new THREE.OctahedronGeometry( 0.1, 0 ), matWhiteTransparent.clone() ), [ 0, 0, 0 ]]], - XY: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.15, 0.15, 0.01 ), matBlueTransparent.clone() ), [ 0.15, 0.15, 0 ]]], - YZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.15, 0.15, 0.01 ), matRedTransparent.clone() ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]], - XZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.15, 0.15, 0.01 ), matGreenTransparent.clone() ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]] - }; - const pickerTranslate = { - X: [[ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0.3, 0, 0 ], [ 0, 0, - Math.PI / 2 ]], [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ - 0.3, 0, 0 ], [ 0, 0, Math.PI / 2 ]]], - Y: [[ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0.3, 0 ]], [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, - 0.3, 0 ], [ 0, 0, Math.PI ]]], - Z: [[ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, 0.3 ], [ Math.PI / 2, 0, 0 ]], [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, - 0.3 ], [ - Math.PI / 2, 0, 0 ]]], - XYZ: [[ new THREE.Mesh( new THREE.OctahedronGeometry( 0.2, 0 ), matInvisible ) ]], - XY: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0.15, 0 ]]], - YZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]], - XZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]] - }; - const helperTranslate = { - START: [[ new THREE.Mesh( new THREE.OctahedronGeometry( 0.01, 2 ), matHelper ), null, null, null, 'helper' ]], - END: [[ new THREE.Mesh( new THREE.OctahedronGeometry( 0.01, 2 ), matHelper ), null, null, null, 'helper' ]], - DELTA: [[ new THREE.Line( TranslateHelperGeometry(), matHelper ), null, null, null, 'helper' ]], - 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' ]] - }; - const gizmoRotate = { - XYZE: [[ new THREE.Mesh( CircleGeometry( 0.5, 1 ), matGray ), null, [ 0, Math.PI / 2, 0 ]]], - X: [[ new THREE.Mesh( CircleGeometry( 0.5, 0.5 ), matRed ) ]], - Y: [[ new THREE.Mesh( CircleGeometry( 0.5, 0.5 ), matGreen ), null, [ 0, 0, - Math.PI / 2 ]]], - Z: [[ new THREE.Mesh( CircleGeometry( 0.5, 0.5 ), matBlue ), null, [ 0, Math.PI / 2, 0 ]]], - E: [[ new THREE.Mesh( CircleGeometry( 0.75, 1 ), matYellowTransparent ), null, [ 0, Math.PI / 2, 0 ]]] - }; - const helperRotate = { - AXIS: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]] - }; - const pickerRotate = { - XYZE: [[ new THREE.Mesh( new THREE.SphereGeometry( 0.25, 10, 8 ), matInvisible ) ]], - X: [[ new THREE.Mesh( new THREE.TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ 0, - Math.PI / 2, - Math.PI / 2 ]]], - Y: [[ new THREE.Mesh( new THREE.TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ]]], - Z: [[ new THREE.Mesh( new THREE.TorusGeometry( 0.5, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]]], - E: [[ new THREE.Mesh( new THREE.TorusGeometry( 0.75, 0.1, 2, 24 ), matInvisible ) ]] - }; - const gizmoScale = { - X: [[ new THREE.Mesh( scaleHandleGeometry, matRed ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]], [ new THREE.Mesh( lineGeometry2, matRed ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]], [ new THREE.Mesh( scaleHandleGeometry, matRed ), [ - 0.5, 0, 0 ], [ 0, 0, Math.PI / 2 ]]], - Y: [[ new THREE.Mesh( scaleHandleGeometry, matGreen ), [ 0, 0.5, 0 ]], [ new THREE.Mesh( lineGeometry2, matGreen ) ], [ new THREE.Mesh( scaleHandleGeometry, matGreen ), [ 0, - 0.5, 0 ], [ 0, 0, Math.PI ]]], - Z: [[ new THREE.Mesh( scaleHandleGeometry, matBlue ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ]], [ new THREE.Mesh( lineGeometry2, matBlue ), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ]], [ new THREE.Mesh( scaleHandleGeometry, matBlue ), [ 0, 0, - 0.5 ], [ - Math.PI / 2, 0, 0 ]]], - XY: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.15, 0.15, 0.01 ), matBlueTransparent ), [ 0.15, 0.15, 0 ]]], - YZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.15, 0.15, 0.01 ), matRedTransparent ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]], - XZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.15, 0.15, 0.01 ), matGreenTransparent ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]], - XYZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.1, 0.1, 0.1 ), matWhiteTransparent.clone() ) ]] - }; - const pickerScale = { - X: [[ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0.3, 0, 0 ], [ 0, 0, - Math.PI / 2 ]], [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ - 0.3, 0, 0 ], [ 0, 0, Math.PI / 2 ]]], - Y: [[ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0.3, 0 ]], [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, - 0.3, 0 ], [ 0, 0, Math.PI ]]], - Z: [[ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, 0.3 ], [ Math.PI / 2, 0, 0 ]], [ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.6, 4 ), matInvisible ), [ 0, 0, - 0.3 ], [ - Math.PI / 2, 0, 0 ]]], - XY: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0.15, 0 ]]], - YZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]]], - XZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.2, 0.2, 0.01 ), matInvisible ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]]], - XYZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.2, 0.2, 0.2 ), matInvisible ), [ 0, 0, 0 ]]] - }; - const helperScale = { - 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. - - function setupGizmo( gizmoMap ) { - - const gizmo = new THREE.Object3D(); - - for ( const name in gizmoMap ) { - - for ( let i = gizmoMap[ name ].length; i --; ) { - - const object = gizmoMap[ name ][ i ][ 0 ].clone(); - 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. - - object.name = name; - object.tag = tag; - - if ( position ) { - - object.position.set( position[ 0 ], position[ 1 ], position[ 2 ] ); - - } - - if ( rotation ) { - - object.rotation.set( rotation[ 0 ], rotation[ 1 ], rotation[ 2 ] ); - - } - - if ( scale ) { - - object.scale.set( scale[ 0 ], scale[ 1 ], scale[ 2 ] ); - - } - - object.updateMatrix(); - const tempGeometry = object.geometry.clone(); - tempGeometry.applyMatrix4( object.matrix ); - object.geometry = tempGeometry; - object.renderOrder = Infinity; - object.position.set( 0, 0, 0 ); - object.rotation.set( 0, 0, 0 ); - object.scale.set( 1, 1, 1 ); - gizmo.add( object ); - - } - - } - - return gizmo; - - } // Gizmo creation - - - this.gizmo = {}; - this.picker = {}; - this.helper = {}; - this.add( this.gizmo[ 'translate' ] = setupGizmo( gizmoTranslate ) ); - this.add( this.gizmo[ 'rotate' ] = setupGizmo( gizmoRotate ) ); - this.add( this.gizmo[ 'scale' ] = setupGizmo( gizmoScale ) ); - this.add( this.picker[ 'translate' ] = setupGizmo( pickerTranslate ) ); - this.add( this.picker[ 'rotate' ] = setupGizmo( pickerRotate ) ); - 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.picker[ 'translate' ].visible = false; - this.picker[ 'rotate' ].visible = false; - this.picker[ 'scale' ].visible = false; - - } // 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 - - this.gizmo[ 'translate' ].visible = this.mode === 'translate'; - this.gizmo[ 'rotate' ].visible = this.mode === 'rotate'; - this.gizmo[ 'scale' ].visible = this.mode === 'scale'; - this.helper[ 'translate' ].visible = this.mode === 'translate'; - this.helper[ 'rotate' ].visible = this.mode === 'rotate'; - this.helper[ 'scale' ].visible = this.mode === 'scale'; - let handles = []; - 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 - - 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; - - } else { - - factor = this.worldPosition.distanceTo( this.cameraPosition ) * Math.min( 1.9 * Math.tan( Math.PI * this.camera.fov / 360 ) / this.camera.zoom, 7 ); - - } - - 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; - - } - - } - - 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; - - } - - } - - 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; - - } - - } - - 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; - - } - - if ( this.axis === 'E' ) { - - handle.visible = false; - - } - - } else if ( handle.name === 'START' ) { - - handle.position.copy( this.worldPositionStart ); - handle.visible = this.dragging; - - } else if ( handle.name === 'END' ) { - - handle.position.copy( this.worldPosition ); - handle.visible = this.dragging; - - } else if ( handle.name === 'DELTA' ) { - - 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 ); - - } else { - - handle.position.copy( this.worldPosition ); - - } - - if ( this.axis ) { - - handle.visible = this.axis.search( handle.name ) !== - 1; - - } - - } // If updating helper, skip rest of the loop - - - continue; - - } // 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; - - if ( handle.name === 'X' ) { - - if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) { - - handle.scale.set( 1e-10, 1e-10, 1e-10 ); - handle.visible = false; - - } - - } - - if ( handle.name === 'Y' ) { - - if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) { - - handle.scale.set( 1e-10, 1e-10, 1e-10 ); - handle.visible = false; - - } - - } - - if ( handle.name === 'Z' ) { - - if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) { - - handle.scale.set( 1e-10, 1e-10, 1e-10 ); - handle.visible = false; - - } - - } - - if ( handle.name === 'XY' ) { - - if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) { - - handle.scale.set( 1e-10, 1e-10, 1e-10 ); - handle.visible = false; - - } - - } - - if ( handle.name === 'YZ' ) { - - if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) { - - handle.scale.set( 1e-10, 1e-10, 1e-10 ); - handle.visible = false; - - } - - } - - if ( handle.name === 'XZ' ) { - - if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) { - - handle.scale.set( 1e-10, 1e-10, 1e-10 ); - handle.visible = false; - - } - - } - - } else if ( this.mode === 'rotate' ) { - - // Align handles to current local or world rotation - _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 ) ); - - } - - if ( handle.name === 'X' ) { - - _tempQuaternion.setFromAxisAngle( _unitX, Math.atan2( - _alignVector.y, _alignVector.z ) ); - - _tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion ); - - handle.quaternion.copy( _tempQuaternion ); - - } - - if ( handle.name === 'Y' ) { - - _tempQuaternion.setFromAxisAngle( _unitY, Math.atan2( _alignVector.x, _alignVector.z ) ); - - _tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion ); - - handle.quaternion.copy( _tempQuaternion ); - - } - - if ( handle.name === 'Z' ) { - - _tempQuaternion.setFromAxisAngle( _unitZ, Math.atan2( _alignVector.y, _alignVector.x ) ); - - _tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion ); - - handle.quaternion.copy( _tempQuaternion ); - - } - - } // 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.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 ) { - - handle.material.color.setHex( 0xffff00 ); - handle.material.opacity = 1.0; - - } else if ( this.axis.split( '' ).some( function ( a ) { - - return handle.name === a; - - } ) ) { - - handle.material.color.setHex( 0xffff00 ); - handle.material.opacity = 1.0; - - } - - } - - } - - super.updateMatrixWorld( force ); - - } - - } // - - - class TransformControlsPlane extends THREE.Mesh { - - constructor() { - - super( new THREE.PlaneGeometry( 100000, 100000, 2, 2 ), new THREE.MeshBasicMaterial( { - visible: false, - wireframe: true, - side: THREE.DoubleSide, - transparent: true, - opacity: 0.1, - toneMapped: false - } ) ); - this.isTransformControlsPlane = true; - this.type = 'TransformControlsPlane'; - - } - - updateMatrixWorld( force ) { - - let space = this.space; - this.position.copy( this.worldPosition ); - 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 ); // Align the plane for current transform mode, axis and space. - - - _alignVector.copy( _v2 ); - - switch ( this.mode ) { - - case 'translate': - case 'scale': - switch ( this.axis ) { - - 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 - _dirVector.set( 0, 0, 0 ); - - } - - if ( _dirVector.length() === 0 ) { - - // If in rotate mode, make the plane parallel to camera - this.quaternion.copy( this.cameraQuaternion ); - - } else { - - _tempMatrix.lookAt( _tempVector.set( 0, 0, 0 ), _dirVector, _alignVector ); - - this.quaternion.setFromRotationMatrix( _tempMatrix ); - - } - - super.updateMatrixWorld( force ); - - } - - } - - THREE.TransformControls = TransformControls; - THREE.TransformControlsGizmo = TransformControlsGizmo; - THREE.TransformControlsPlane = TransformControlsPlane; - -} )(); diff --git a/examples/js/controls/experimental/CameraControls.js b/examples/js/controls/experimental/CameraControls.js deleted file mode 100644 index fd294deed0d1fd..00000000000000 --- a/examples/js/controls/experimental/CameraControls.js +++ /dev/null @@ -1,1048 +0,0 @@ -( function () { - - var CameraControls = function ( object, domElement ) { - - if ( domElement === undefined ) console.warn( 'THREE.CameraControls: The second parameter "domElement" is now mandatory.' ); - if ( domElement === document ) console.error( 'THREE.CameraControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.' ); - this.object = object; - this.domElement = domElement; // Set to false to disable this control - - this.enabled = true; // "target" sets the location of focus, where the object orbits around - - this.target = new THREE.Vector3(); // Set to true to enable trackball behavior - - this.trackball = false; // 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.minZoom = 0; - 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, must be a sub-interval of the interval [ - Math.PI, Math.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 enables dollying in and out; property named 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.enableRotate = true; - this.rotateSpeed = 1.0; // Set to false to disable panning - - this.enablePan = true; - this.panSpeed = 1.0; - this.screenSpacePanning = false; // if true, pan in screen-space - - 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 - // auto-rotate is not supported for trackball behavior - - this.autoRotate = false; - this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 - // Set to false to disable use of the keys - - this.enableKeys = true; // The four arrow keys - - this.keys = { - LEFT: 37, - UP: 38, - RIGHT: 39, - BOTTOM: 40 - }; // Mouse buttons - - this.mouseButtons = { - LEFT: THREE.MOUSE.ROTATE, - MIDDLE: THREE.MOUSE.DOLLY, - RIGHT: THREE.MOUSE.PAN - }; // Touch fingers - - this.touches = { - ONE: THREE.TOUCH.ROTATE, - TWO: THREE.TOUCH.DOLLY_PAN - }; // for reset - - this.target0 = this.target.clone(); - this.position0 = this.object.position.clone(); - this.quaternion0 = this.object.quaternion.clone(); - this.zoom0 = this.object.zoom; // - // public methods - // - - this.getPolarAngle = function () { - - return spherical.phi; - - }; - - this.getAzimuthalAngle = function () { - - return spherical.theta; - - }; - - this.saveState = function () { - - scope.target0.copy( scope.target ); - scope.position0.copy( scope.object.position ); - scope.quaternion0.copy( scope.object.quaternion ); - scope.zoom0 = scope.object.zoom; - - }; - - this.reset = function () { - - scope.target.copy( scope.target0 ); - scope.object.position.copy( scope.position0 ); - scope.object.quaternion.copy( scope.quaternion0 ); - scope.object.zoom = scope.zoom0; - scope.object.updateProjectionMatrix(); - scope.dispatchEvent( changeEvent ); - scope.update(); - state = STATE.NONE; - - }; // this method is exposed, but perhaps it would be better if we can make it private... - - - this.update = function () { - - var offset = new THREE.Vector3(); // so camera.up is the orbit axis - - var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) ); - var quatInverse = quat.clone().invert(); - var lastPosition = new THREE.Vector3(); - var lastQuaternion = new THREE.Quaternion(); - var q = new THREE.Quaternion(); - var vec = new THREE.Vector3(); - return function update() { - - var position = scope.object.position; - offset.copy( position ).sub( scope.target ); - - if ( scope.trackball ) { - - // rotate around screen-space y-axis - if ( sphericalDelta.theta ) { - - vec.set( 0, 1, 0 ).applyQuaternion( scope.object.quaternion ); - const factor = scope.enableDamping ? scope.dampingFactor : 1; - q.setFromAxisAngle( vec, sphericalDelta.theta * factor ); - scope.object.quaternion.premultiply( q ); - offset.applyQuaternion( q ); - - } // rotate around screen-space x-axis - - - if ( sphericalDelta.phi ) { - - vec.set( 1, 0, 0 ).applyQuaternion( scope.object.quaternion ); - const factor = scope.enableDamping ? scope.dampingFactor : 1; - q.setFromAxisAngle( vec, sphericalDelta.phi * factor ); - scope.object.quaternion.premultiply( q ); - offset.applyQuaternion( q ); - - } - - offset.multiplyScalar( scale ); - offset.clampLength( scope.minDistance, scope.maxDistance ); - - } else { - - // rotate offset to "y-axis-is-up" space - offset.applyQuaternion( quat ); - - if ( scope.autoRotate && state === STATE.NONE ) { - - rotateLeft( getAutoRotationAngle() ); - - } - - spherical.setFromVector3( offset ); - - if ( scope.enableDamping ) { - - spherical.theta += sphericalDelta.theta * scope.dampingFactor; - spherical.phi += sphericalDelta.phi * scope.dampingFactor; - - } else { - - spherical.theta += sphericalDelta.theta; - spherical.phi += sphericalDelta.phi; - - } // restrict theta to be between desired limits - - - spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) ); // 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 = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) ); - offset.setFromSpherical( spherical ); // rotate offset back to "camera-up-vector-is-up" space - - offset.applyQuaternion( quatInverse ); - - } // move target to panned location - - - if ( scope.enableDamping === true ) { - - scope.target.addScaledVector( panOffset, scope.dampingFactor ); - - } else { - - scope.target.add( panOffset ); - - } - - position.copy( scope.target ).add( offset ); - - if ( scope.trackball === false ) { - - scope.object.lookAt( scope.target ); - - } - - if ( scope.enableDamping === true ) { - - sphericalDelta.theta *= 1 - scope.dampingFactor; - sphericalDelta.phi *= 1 - scope.dampingFactor; - panOffset.multiplyScalar( 1 - scope.dampingFactor ); - - } else { - - sphericalDelta.set( 0, 0, 0 ); - panOffset.set( 0, 0, 0 ); - - } - - 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 - - if ( zoomChanged || lastPosition.distanceToSquared( scope.object.position ) > EPS || 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) { - - scope.dispatchEvent( changeEvent ); - lastPosition.copy( scope.object.position ); - lastQuaternion.copy( scope.object.quaternion ); - zoomChanged = false; - return true; - - } - - return false; - - }; - - }(); - - this.dispose = function () { - - scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false ); - scope.domElement.removeEventListener( 'mousedown', onMouseDown, false ); - scope.domElement.removeEventListener( 'wheel', onMouseWheel, false ); - scope.domElement.removeEventListener( 'touchstart', onTouchStart, false ); - scope.domElement.removeEventListener( 'touchend', onTouchEnd, false ); - scope.domElement.removeEventListener( 'touchmove', onTouchMove, false ); - document.removeEventListener( 'mousemove', onMouseMove, false ); - document.removeEventListener( 'mouseup', onMouseUp, false ); - scope.domElement.removeEventListener( 'keydown', onKeyDown, false ); //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here? - - }; // - // internals - // - - - var scope = this; - var changeEvent = { - type: 'change' - }; - var startEvent = { - type: 'start' - }; - var endEvent = { - type: 'end' - }; - var STATE = { - NONE: - 1, - ROTATE: 0, - DOLLY: 1, - PAN: 2, - TOUCH_ROTATE: 3, - TOUCH_PAN: 4, - TOUCH_DOLLY_PAN: 5, - TOUCH_DOLLY_ROTATE: 6 - }; - var state = STATE.NONE; - var EPS = 0.000001; // current position in spherical coordinates - - var spherical = new THREE.Spherical(); - var sphericalDelta = new THREE.Spherical(); - var scale = 1; - var panOffset = new THREE.Vector3(); - var zoomChanged = false; - var rotateStart = new THREE.Vector2(); - var rotateEnd = new THREE.Vector2(); - var rotateDelta = new THREE.Vector2(); - var panStart = new THREE.Vector2(); - var panEnd = new THREE.Vector2(); - var panDelta = new THREE.Vector2(); - var dollyStart = new THREE.Vector2(); - var dollyEnd = new THREE.Vector2(); - var dollyDelta = new THREE.Vector2(); - - function getAutoRotationAngle() { - - return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; - - } - - function getZoomScale() { - - return Math.pow( 0.95, scope.zoomSpeed ); - - } - - function rotateLeft( angle ) { - - sphericalDelta.theta -= angle; - - } - - function rotateUp( angle ) { - - sphericalDelta.phi -= angle; - - } - - var panLeft = function () { - - var v = new THREE.Vector3(); - return function panLeft( distance, objectMatrix ) { - - v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix - - v.multiplyScalar( - distance ); - panOffset.add( v ); - - }; - - }(); - - var panUp = function () { - - var v = new THREE.Vector3(); - return function panUp( distance, objectMatrix ) { - - if ( scope.screenSpacePanning === true ) { - - v.setFromMatrixColumn( objectMatrix, 1 ); - - } else { - - v.setFromMatrixColumn( objectMatrix, 0 ); - v.crossVectors( scope.object.up, v ); - - } - - v.multiplyScalar( distance ); - panOffset.add( v ); - - }; - - }(); // deltaX and deltaY are in pixels; right and down are positive - - - var pan = function () { - - var offset = new THREE.Vector3(); - return function pan( deltaX, deltaY ) { - - var element = scope.domElement; - - if ( scope.object.isPerspectiveCamera ) { - - // perspective - var position = scope.object.position; - offset.copy( position ).sub( scope.target ); - var targetDistance = offset.length(); // 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 ); - - } else if ( scope.object.isOrthographicCamera ) { - - // orthographic - panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix ); - panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix ); - - } else { - - // camera neither orthographic nor perspective - console.warn( 'WARNING: CameraControls.js encountered an unknown camera type - pan disabled.' ); - scope.enablePan = false; - - } - - }; - - }(); - - function dollyIn( dollyScale ) { - - if ( scope.object.isPerspectiveCamera ) { - - scale /= dollyScale; - - } else if ( scope.object.isOrthographicCamera ) { - - scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) ); - scope.object.updateProjectionMatrix(); - zoomChanged = true; - - } else { - - console.warn( 'WARNING: CameraControls.js encountered an unknown camera type - dolly/zoom disabled.' ); - scope.enableZoom = false; - - } - - } - - function dollyOut( dollyScale ) { - - if ( scope.object.isPerspectiveCamera ) { - - scale *= dollyScale; - - } else if ( scope.object.isOrthographicCamera ) { - - scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) ); - scope.object.updateProjectionMatrix(); - zoomChanged = true; - - } else { - - console.warn( 'WARNING: CameraControls.js encountered an unknown camera type - dolly/zoom disabled.' ); - scope.enableZoom = false; - - } - - } // - // event callbacks - update the object state - // - - - function handleMouseDownRotate( event ) { - - rotateStart.set( event.clientX, event.clientY ); - - } - - function handleMouseDownDolly( event ) { - - dollyStart.set( event.clientX, event.clientY ); - - } - - function handleMouseDownPan( event ) { - - panStart.set( event.clientX, event.clientY ); - - } - - function handleMouseMoveRotate( event ) { - - rotateEnd.set( event.clientX, event.clientY ); - rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); - var element = scope.domElement; - rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height - - rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); - rotateStart.copy( rotateEnd ); - scope.update(); - - } - - function handleMouseMoveDolly( event ) { - - dollyEnd.set( event.clientX, event.clientY ); - dollyDelta.subVectors( dollyEnd, dollyStart ); - - if ( dollyDelta.y > 0 ) { - - dollyIn( getZoomScale() ); - - } else if ( dollyDelta.y < 0 ) { - - dollyOut( getZoomScale() ); - - } - - dollyStart.copy( dollyEnd ); - scope.update(); - - } - - function handleMouseMovePan( event ) { - - panEnd.set( event.clientX, event.clientY ); - panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); - pan( panDelta.x, panDelta.y ); - panStart.copy( panEnd ); - scope.update(); - - } - - function - /*event*/ - handleMouseUp() { // no-op - } - - function handleMouseWheel( event ) { - - if ( event.deltaY < 0 ) { - - dollyOut( getZoomScale() ); - - } else if ( event.deltaY > 0 ) { - - dollyIn( getZoomScale() ); - - } - - scope.update(); - - } - - function handleKeyDown( event ) { - - var needsUpdate = false; - - switch ( event.keyCode ) { - - case scope.keys.UP: - pan( 0, scope.keyPanSpeed ); - needsUpdate = true; - break; - - case scope.keys.BOTTOM: - pan( 0, - scope.keyPanSpeed ); - needsUpdate = true; - break; - - case scope.keys.LEFT: - pan( scope.keyPanSpeed, 0 ); - needsUpdate = true; - break; - - case scope.keys.RIGHT: - pan( - scope.keyPanSpeed, 0 ); - needsUpdate = true; - break; - - } - - if ( needsUpdate ) { - - // prevent the browser from scrolling on cursor keys - event.preventDefault(); - scope.update(); - - } - - } - - function handleTouchStartRotate( event ) { - - if ( event.touches.length == 1 ) { - - rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); - - } else { - - var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); - var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); - rotateStart.set( x, y ); - - } - - } - - function handleTouchStartPan( event ) { - - if ( event.touches.length == 1 ) { - - panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); - - } else { - - var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); - var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); - panStart.set( x, y ); - - } - - } - - function handleTouchStartDolly( event ) { - - var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; - var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; - var distance = Math.sqrt( dx * dx + dy * dy ); - dollyStart.set( 0, distance ); - - } - - function handleTouchStartDollyPan( event ) { - - if ( scope.enableZoom ) handleTouchStartDolly( event ); - if ( scope.enablePan ) handleTouchStartPan( event ); - - } - - function handleTouchStartDollyRotate( event ) { - - if ( scope.enableZoom ) handleTouchStartDolly( event ); - if ( scope.enableRotate ) handleTouchStartRotate( event ); - - } - - function handleTouchMoveRotate( event ) { - - if ( event.touches.length == 1 ) { - - rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); - - } else { - - var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); - var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); - rotateEnd.set( x, y ); - - } - - rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); - var element = scope.domElement; - rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height - - rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); - rotateStart.copy( rotateEnd ); - - } - - function handleTouchMovePan( event ) { - - if ( event.touches.length == 1 ) { - - panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); - - } else { - - var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); - var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); - panEnd.set( x, y ); - - } - - panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); - pan( panDelta.x, panDelta.y ); - panStart.copy( panEnd ); - - } - - function handleTouchMoveDolly( event ) { - - var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; - var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; - var distance = Math.sqrt( dx * dx + dy * dy ); - dollyEnd.set( 0, distance ); - dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) ); - dollyIn( dollyDelta.y ); - dollyStart.copy( dollyEnd ); - - } - - function handleTouchMoveDollyPan( event ) { - - if ( scope.enableZoom ) handleTouchMoveDolly( event ); - if ( scope.enablePan ) handleTouchMovePan( event ); - - } - - function handleTouchMoveDollyRotate( event ) { - - if ( scope.enableZoom ) handleTouchMoveDolly( event ); - if ( scope.enableRotate ) handleTouchMoveRotate( event ); - - } - - function - /*event*/ - handleTouchEnd() { // no-op - } // - // event handlers - FSM: listen for events and reset state - // - - - function onMouseDown( event ) { - - if ( scope.enabled === false ) return; // Prevent the browser from scrolling. - - event.preventDefault(); // Manually set the focus since calling preventDefault above - // prevents the browser from setting it automatically. - - scope.domElement.focus ? scope.domElement.focus() : window.focus(); - var 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; - - } - - switch ( mouseAction ) { - - case THREE.MOUSE.DOLLY: - if ( scope.enableZoom === false ) return; - handleMouseDownDolly( event ); - state = STATE.DOLLY; - break; - - case THREE.MOUSE.ROTATE: - if ( event.ctrlKey || event.metaKey || event.shiftKey ) { - - if ( scope.enablePan === false ) return; - handleMouseDownPan( event ); - state = STATE.PAN; - - } else { - - if ( scope.enableRotate === false ) return; - handleMouseDownRotate( event ); - state = STATE.ROTATE; - - } - - break; - - case THREE.MOUSE.PAN: - if ( event.ctrlKey || event.metaKey || event.shiftKey ) { - - if ( scope.enableRotate === false ) return; - handleMouseDownRotate( event ); - state = STATE.ROTATE; - - } else { - - if ( scope.enablePan === false ) return; - handleMouseDownPan( event ); - state = STATE.PAN; - - } - - break; - - default: - state = STATE.NONE; - - } - - if ( state !== STATE.NONE ) { - - document.addEventListener( 'mousemove', onMouseMove, false ); - document.addEventListener( 'mouseup', onMouseUp, false ); - scope.dispatchEvent( startEvent ); - - } - - } - - function onMouseMove( event ) { - - if ( scope.enabled === false ) return; - event.preventDefault(); - - switch ( state ) { - - case STATE.ROTATE: - 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 ); - break; - - } - - } - - function onMouseUp( event ) { - - if ( scope.enabled === false ) return; - handleMouseUp( event ); - document.removeEventListener( 'mousemove', onMouseMove, false ); - document.removeEventListener( 'mouseup', onMouseUp, false ); - scope.dispatchEvent( endEvent ); - state = STATE.NONE; - - } - - function onMouseWheel( event ) { - - if ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE && state !== STATE.ROTATE ) return; - event.preventDefault(); - event.stopPropagation(); - scope.dispatchEvent( startEvent ); - handleMouseWheel( event ); - scope.dispatchEvent( endEvent ); - - } - - function onKeyDown( event ) { - - if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return; - handleKeyDown( event ); - - } - - function onTouchStart( event ) { - - if ( scope.enabled === false ) return; - event.preventDefault(); - - switch ( event.touches.length ) { - - case 1: - switch ( scope.touches.ONE ) { - - case THREE.TOUCH.ROTATE: - if ( scope.enableRotate === false ) return; - handleTouchStartRotate( event ); - state = STATE.TOUCH_ROTATE; - break; - - case THREE.TOUCH.PAN: - if ( scope.enablePan === false ) return; - handleTouchStartPan( event ); - state = STATE.TOUCH_PAN; - break; - - default: - state = STATE.NONE; - - } - - break; - - case 2: - switch ( scope.touches.TWO ) { - - case THREE.TOUCH.DOLLY_PAN: - if ( scope.enableZoom === false && scope.enablePan === false ) return; - handleTouchStartDollyPan( event ); - state = STATE.TOUCH_DOLLY_PAN; - break; - - case THREE.TOUCH.DOLLY_ROTATE: - if ( scope.enableZoom === false && scope.enableRotate === false ) return; - handleTouchStartDollyRotate( event ); - state = STATE.TOUCH_DOLLY_ROTATE; - break; - - default: - state = STATE.NONE; - - } - - break; - - default: - state = STATE.NONE; - - } - - if ( state !== STATE.NONE ) { - - scope.dispatchEvent( startEvent ); - - } - - } - - function onTouchMove( event ) { - - if ( scope.enabled === false ) return; - event.preventDefault(); - event.stopPropagation(); - - switch ( state ) { - - case STATE.TOUCH_ROTATE: - if ( scope.enableRotate === false ) return; - 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; - - } - - } - - function onTouchEnd( event ) { - - if ( scope.enabled === false ) return; - handleTouchEnd( event ); - scope.dispatchEvent( endEvent ); - state = STATE.NONE; - - } - - function onContextMenu( event ) { - - if ( scope.enabled === false ) return; - event.preventDefault(); - - } // - - - scope.domElement.addEventListener( 'contextmenu', onContextMenu, false ); - scope.domElement.addEventListener( 'mousedown', onMouseDown, false ); - scope.domElement.addEventListener( 'wheel', onMouseWheel, false ); - scope.domElement.addEventListener( 'touchstart', onTouchStart, false ); - scope.domElement.addEventListener( 'touchend', onTouchEnd, false ); - scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); - scope.domElement.addEventListener( 'keydown', onKeyDown, false ); // make sure element can receive keys. - - if ( scope.domElement.tabIndex === - 1 ) { - - scope.domElement.tabIndex = 0; - - } // force an update at start - - - this.object.lookAt( scope.target ); - this.update(); - this.saveState(); - - }; - - CameraControls.prototype = Object.create( THREE.EventDispatcher.prototype ); - CameraControls.prototype.constructor = CameraControls; // OrbitControls maintains the "up" direction, camera.up (+Y by default). - // - // Orbit - left mouse / touch: one-finger move - // Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish - // Pan - right mouse, or left mouse + ctrl/meta/shiftKey, or arrow keys / touch: two-finger move - - var OrbitControls = function ( object, domElement ) { - - CameraControls.call( this, object, domElement ); - this.mouseButtons.LEFT = THREE.MOUSE.ROTATE; - this.mouseButtons.RIGHT = THREE.MOUSE.PAN; - this.touches.ONE = THREE.TOUCH.ROTATE; - this.touches.TWO = THREE.TOUCH.DOLLY_PAN; - - }; - - OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); - OrbitControls.prototype.constructor = OrbitControls; // MapControls maintains the "up" direction, camera.up (+Y by default) - // - // Orbit - right mouse, or left mouse + ctrl/meta/shiftKey / touch: two-finger rotate - // Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish - // Pan - left mouse, or left right + ctrl/meta/shiftKey, or arrow keys / touch: one-finger move - - var MapControls = function ( object, domElement ) { - - CameraControls.call( this, object, domElement ); - this.mouseButtons.LEFT = THREE.MOUSE.PAN; - this.mouseButtons.RIGHT = THREE.MOUSE.ROTATE; - this.touches.ONE = THREE.TOUCH.PAN; - this.touches.TWO = THREE.TOUCH.DOLLY_ROTATE; - - }; - - MapControls.prototype = Object.create( THREE.EventDispatcher.prototype ); - MapControls.prototype.constructor = MapControls; // TrackballControls allows the camera to rotate over the polls and does not maintain camera.up - // - // Orbit - left mouse / touch: one-finger move - // Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish - // Pan - right mouse, or left mouse + ctrl/meta/shiftKey, or arrow keys / touch: two-finger move - - var TrackballControls = function ( object, domElement ) { - - CameraControls.call( this, object, domElement ); - this.trackball = true; - this.screenSpacePanning = true; - this.autoRotate = false; - this.mouseButtons.LEFT = THREE.MOUSE.ROTATE; - this.mouseButtons.RIGHT = THREE.MOUSE.PAN; - this.touches.ONE = THREE.TOUCH.ROTATE; - this.touches.TWO = THREE.TOUCH.DOLLY_PAN; - - }; - - TrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype ); - TrackballControls.prototype.constructor = TrackballControls; - - THREE.CameraControls = CameraControls; - THREE.MapControls = MapControls; - THREE.OrbitControls = OrbitControls; - THREE.TrackballControls = TrackballControls; - -} )(); diff --git a/examples/js/csm/CSM.js b/examples/js/csm/CSM.js deleted file mode 100644 index c8d5326bad891b..00000000000000 --- a/examples/js/csm/CSM.js +++ /dev/null @@ -1,382 +0,0 @@ -( 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 { - - constructor( data ) { - - data = data || {}; - this.camera = data.camera; - this.parent = data.parent; - this.cascades = data.cascades || 3; - this.maxFar = data.maxFar || 100000; - this.mode = data.mode || 'practical'; - this.shadowMapSize = data.shadowMapSize || 2048; - this.shadowBias = data.shadowBias || 0.000001; - this.lightDirection = data.lightDirection || new THREE.Vector3( 1, - 1, 1 ).normalize(); - this.lightIntensity = data.lightIntensity || 1; - this.lightNear = data.lightNear || 1; - this.lightFar = data.lightFar || 2000; - this.lightMargin = data.lightMargin || 200; - this.customSplitsCallback = data.customSplitsCallback; - this.fade = false; - this.mainFrustum = new THREE.CSMFrustum(); - this.frustums = []; - this.breaks = []; - this.lights = []; - this.shaders = new Map(); - this.createLights(); - this.updateFrustums(); - this.injectInclude(); - - } - - createLights() { - - for ( let i = 0; i < this.cascades; i ++ ) { - - const light = new THREE.DirectionalLight( 0xffffff, this.lightIntensity ); - light.castShadow = true; - light.shadow.mapSize.width = this.shadowMapSize; - light.shadow.mapSize.height = this.shadowMapSize; - light.shadow.camera.near = this.lightNear; - light.shadow.camera.far = this.lightFar; - light.shadow.bias = this.shadowBias; - this.parent.add( light ); - this.parent.add( light.target ); - this.lights.push( light ); - - } - - } - - initCascades() { - - const camera = this.camera; - camera.updateProjectionMatrix(); - this.mainFrustum.setFromProjectionMatrix( camera.projectionMatrix, this.maxFar ); - 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 - // 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 ]; - - } else { - - point2 = nearVerts[ 2 ]; - - } - - let squaredBBWidth = point1.distanceTo( point2 ); - - if ( this.fade ) { - - // expand the shadow extents by the fade margin if fade is enabled. - const camera = this.camera; - const far = Math.max( camera.far, this.maxFar ); - const linearDepth = frustum.vertices.far[ 0 ].z / ( far - camera.near ); - const margin = 0.25 * Math.pow( linearDepth, 2.0 ) * ( far - camera.near ); - squaredBBWidth += margin; - - } - - shadowCam.left = - squaredBBWidth / 2; - shadowCam.right = squaredBBWidth / 2; - shadowCam.top = squaredBBWidth / 2; - shadowCam.bottom = - squaredBBWidth / 2; - shadowCam.updateProjectionMatrix(); - - } - - } - - 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 ); - break; - - } - - function uniformSplit( amount, near, far, target ) { - - for ( let i = 1; i < amount; i ++ ) { - - target.push( ( near + ( far - near ) * i / amount ) / far ); - - } - - target.push( 1 ); - - } - - function logarithmicSplit( amount, near, far, target ) { - - for ( let i = 1; i < amount; i ++ ) { - - target.push( near * ( far / near ) ** ( i / amount ) / far ); - - } - - target.push( 1 ); - - } - - function practicalSplit( amount, near, far, lambda, target ) { - - _uniformArray.length = 0; - _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 ) ); - - } - - target.push( 1 ); - - } - - } - - update() { - - const camera = this.camera; - const frustums = this.frustums; - - for ( let i = 0; i < frustums.length; i ++ ) { - - const light = this.lights[ i ]; - const shadowCam = light.shadow.camera; - 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; - light.target.position.y += this.lightDirection.y; - light.target.position.z += this.lightDirection.z; - - } - - } - - 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 = ''; - - } - - const breaksVec2 = []; - const scope = this; - const shaders = this.shaders; - - material.onBeforeCompile = function ( shader ) { - - const far = Math.min( scope.camera.far, scope.maxFar ); - scope.getExtendedBreaks( breaksVec2 ); - shader.uniforms.CSM_cascades = { - value: breaksVec2 - }; - shader.uniforms.cameraNear = { - value: scope.camera.near - }; - shader.uniforms.shadowFar = { - value: far - }; - shaders.set( material, shader ); - - }; - - shaders.set( material, null ); - - } - - updateUniforms() { - - const far = Math.min( this.camera.far, this.maxFar ); - const shaders = this.shaders; - shaders.forEach( function ( shader, material ) { - - if ( shader !== null ) { - - const uniforms = shader.uniforms; - this.getExtendedBreaks( uniforms.CSM_cascades.value ); - uniforms.cameraNear.value = this.camera.near; - uniforms.shadowFar.value = far; - - } - - if ( ! this.fade && 'CSM_FADE' in material.defines ) { - - delete material.defines.CSM_FADE; - material.needsUpdate = true; - - } else if ( this.fade && ! ( 'CSM_FADE' in material.defines ) ) { - - material.defines.CSM_FADE = ''; - material.needsUpdate = true; - - } - - }, this ); - - } - - getExtendedBreaks( target ) { - - while ( target.length < this.breaks.length ) { - - target.push( new THREE.Vector2() ); - - } - - target.length = this.breaks.length; - - for ( let i = 0; i < this.cascades; i ++ ) { - - const amount = this.breaks[ i ]; - const prev = this.breaks[ i - 1 ] || 0; - target[ i ].x = prev; - target[ i ].y = amount; - - } - - } - - updateFrustums() { - - this.getBreaks(); - this.initCascades(); - this.updateShadowBounds(); - this.updateUniforms(); - - } - - remove() { - - for ( let i = 0; i < this.lights.length; i ++ ) { - - this.parent.remove( this.lights[ i ] ); - - } - - } - - dispose() { - - const shaders = this.shaders; - shaders.forEach( function ( shader, material ) { - - delete material.onBeforeCompile; - delete material.defines.USE_CSM; - delete material.defines.CSM_CASCADES; - delete material.defines.CSM_FADE; - - if ( shader !== null ) { - - delete shader.uniforms.CSM_cascades; - delete shader.uniforms.cameraNear; - delete shader.uniforms.shadowFar; - - } - - material.needsUpdate = true; - - } ); - shaders.clear(); - - } - - } - - THREE.CSM = CSM; - -} )(); diff --git a/examples/js/csm/CSMFrustum.js b/examples/js/csm/CSMFrustum.js deleted file mode 100644 index 1c59239c9c688d..00000000000000 --- a/examples/js/csm/CSMFrustum.js +++ /dev/null @@ -1,133 +0,0 @@ -( function () { - - const inverseProjectionMatrix = new THREE.Matrix4(); - - class CSMFrustum { - - constructor( data ) { - - data = data || {}; - this.vertices = { - 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 ); - - } - - } - - setFromProjectionMatrix( projectionMatrix, maxFar ) { - - const isOrthographic = projectionMatrix.elements[ 2 * 4 + 3 ] === 0; - inverseProjectionMatrix.copy( projectionMatrix ).invert(); // 3 --- 0 vertices.near/far order - // | | - // 2 --- 1 - // clip space spans from [-1, 1] - - this.vertices.near[ 0 ].set( 1, 1, - 1 ); - this.vertices.near[ 1 ].set( 1, - 1, - 1 ); - this.vertices.near[ 2 ].set( - 1, - 1, - 1 ); - this.vertices.near[ 3 ].set( - 1, 1, - 1 ); - this.vertices.near.forEach( function ( v ) { - - v.applyMatrix4( inverseProjectionMatrix ); - - } ); - this.vertices.far[ 0 ].set( 1, 1, 1 ); - this.vertices.far[ 1 ].set( 1, - 1, 1 ); - this.vertices.far[ 2 ].set( - 1, - 1, 1 ); - this.vertices.far[ 3 ].set( - 1, 1, 1 ); - this.vertices.far.forEach( function ( v ) { - - v.applyMatrix4( inverseProjectionMatrix ); - const absZ = Math.abs( v.z ); - - if ( isOrthographic ) { - - v.z *= Math.min( maxFar / absZ, 1.0 ); - - } else { - - v.multiplyScalar( Math.min( maxFar / absZ, 1.0 ) ); - - } - - } ); - return this.vertices; - - } - - split( breaks, target ) { - - while ( breaks.length > target.length ) { - - target.push( new CSMFrustum() ); - - } - - 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 ++ ) { - - cascade.vertices.near[ j ].copy( this.vertices.near[ j ] ); - - } - - } else { - - for ( let j = 0; j < 4; j ++ ) { - - cascade.vertices.near[ j ].lerpVectors( this.vertices.near[ j ], this.vertices.far[ j ], breaks[ i - 1 ] ); - - } - - } - - if ( i === breaks.length - 1 ) { - - for ( let j = 0; j < 4; j ++ ) { - - cascade.vertices.far[ j ].copy( this.vertices.far[ j ] ); - - } - - } else { - - for ( let j = 0; j < 4; j ++ ) { - - cascade.vertices.far[ j ].lerpVectors( this.vertices.near[ j ], this.vertices.far[ j ], breaks[ i ] ); - - } - - } - - } - - } - - toSpace( cameraMatrix, target ) { - - for ( let i = 0; i < 4; i ++ ) { - - target.vertices.near[ i ].copy( this.vertices.near[ i ] ).applyMatrix4( cameraMatrix ); - target.vertices.far[ i ].copy( this.vertices.far[ i ] ).applyMatrix4( cameraMatrix ); - - } - - } - - } - - THREE.CSMFrustum = CSMFrustum; - -} )(); diff --git a/examples/js/csm/CSMHelper.js b/examples/js/csm/CSMHelper.js deleted file mode 100644 index df372b8058accf..00000000000000 --- a/examples/js/csm/CSMHelper.js +++ /dev/null @@ -1,145 +0,0 @@ -( function () { - - class CSMHelper extends THREE.Group { - - constructor( csm ) { - - super(); - this.csm = csm; - this.displayFrustum = true; - this.displayPlanes = true; - this.displayShadowBounds = true; - 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 ] ); - const positions = new Float32Array( 24 ); - const frustumGeometry = new THREE.BufferGeometry(); - frustumGeometry.setIndex( new THREE.BufferAttribute( indices, 1 ) ); - frustumGeometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3, false ) ); - const frustumLines = new THREE.LineSegments( frustumGeometry, new THREE.LineBasicMaterial() ); - this.add( frustumLines ); - this.frustumLines = frustumLines; - this.cascadeLines = []; - this.cascadePlanes = []; - this.shadowLines = []; - - } - - updateVisibility() { - - const displayFrustum = this.displayFrustum; - const displayPlanes = this.displayPlanes; - const displayShadowBounds = this.displayShadowBounds; - const frustumLines = this.frustumLines; - 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 ]; - const cascadePlane = cascadePlanes[ i ]; - const shadowLineGroup = shadowLines[ i ]; - cascadeLine.visible = displayFrustum; - cascadePlane.visible = displayFrustum && displayPlanes; - shadowLineGroup.visible = displayShadowBounds; - - } - - frustumLines.visible = displayFrustum; - - } - - update() { - - const csm = this.csm; - const camera = csm.camera; - const cascades = csm.cascades; - const mainFrustum = csm.mainFrustum; - const frustums = csm.frustums; - const lights = csm.lights; - const frustumLines = this.frustumLines; - const frustumLinePositions = frustumLines.geometry.getAttribute( 'position' ); - const cascadeLines = this.cascadeLines; - const cascadePlanes = this.cascadePlanes; - const shadowLines = this.shadowLines; - this.position.copy( camera.position ); - this.quaternion.copy( camera.quaternion ); - this.scale.copy( camera.scale ); - this.updateMatrixWorld( true ); - - while ( cascadeLines.length > cascades ) { - - this.remove( cascadeLines.pop() ); - this.remove( cascadePlanes.pop() ); - this.remove( shadowLines.pop() ); - - } - - while ( cascadeLines.length < cascades ) { - - const cascadeLine = new THREE.Box3Helper( new THREE.Box3(), 0xffffff ); - const planeMat = new THREE.MeshBasicMaterial( { - transparent: true, - opacity: 0.1, - depthWrite: false, - side: THREE.DoubleSide - } ); - const cascadePlane = new THREE.Mesh( new THREE.PlaneGeometry(), planeMat ); - const shadowLineGroup = new THREE.Group(); - const shadowLine = new THREE.Box3Helper( new THREE.Box3(), 0xffff00 ); - shadowLineGroup.add( shadowLine ); - this.add( cascadeLine ); - this.add( cascadePlane ); - this.add( shadowLineGroup ); - cascadeLines.push( cascadeLine ); - cascadePlanes.push( cascadePlane ); - shadowLines.push( shadowLineGroup ); - - } - - for ( let i = 0; i < cascades; i ++ ) { - - const frustum = frustums[ i ]; - const light = lights[ i ]; - const shadowCam = light.shadow.camera; - const farVerts = frustum.vertices.far; - const cascadeLine = cascadeLines[ i ]; - const cascadePlane = cascadePlanes[ i ]; - const shadowLineGroup = shadowLines[ i ]; - const shadowLine = shadowLineGroup.children[ 0 ]; - cascadeLine.box.min.copy( farVerts[ 2 ] ); - cascadeLine.box.max.copy( farVerts[ 0 ] ); - cascadeLine.box.max.z += 1e-4; - cascadePlane.position.addVectors( farVerts[ 0 ], farVerts[ 2 ] ); - cascadePlane.position.multiplyScalar( 0.5 ); - cascadePlane.scale.subVectors( farVerts[ 0 ], farVerts[ 2 ] ); - cascadePlane.scale.z = 1e-4; - this.remove( shadowLineGroup ); - shadowLineGroup.position.copy( shadowCam.position ); - shadowLineGroup.quaternion.copy( shadowCam.quaternion ); - shadowLineGroup.scale.copy( shadowCam.scale ); - shadowLineGroup.updateMatrixWorld( true ); - this.attach( shadowLineGroup ); - shadowLine.box.min.set( shadowCam.bottom, shadowCam.left, - shadowCam.far ); - shadowLine.box.max.set( shadowCam.top, shadowCam.right, - shadowCam.near ); - - } - - const nearVerts = mainFrustum.vertices.near; - const farVerts = mainFrustum.vertices.far; - frustumLinePositions.setXYZ( 0, farVerts[ 0 ].x, farVerts[ 0 ].y, farVerts[ 0 ].z ); - frustumLinePositions.setXYZ( 1, farVerts[ 3 ].x, farVerts[ 3 ].y, farVerts[ 3 ].z ); - frustumLinePositions.setXYZ( 2, farVerts[ 2 ].x, farVerts[ 2 ].y, farVerts[ 2 ].z ); - frustumLinePositions.setXYZ( 3, farVerts[ 1 ].x, farVerts[ 1 ].y, farVerts[ 1 ].z ); - frustumLinePositions.setXYZ( 4, nearVerts[ 0 ].x, nearVerts[ 0 ].y, nearVerts[ 0 ].z ); - frustumLinePositions.setXYZ( 5, nearVerts[ 3 ].x, nearVerts[ 3 ].y, nearVerts[ 3 ].z ); - frustumLinePositions.setXYZ( 6, nearVerts[ 2 ].x, nearVerts[ 2 ].y, nearVerts[ 2 ].z ); - frustumLinePositions.setXYZ( 7, nearVerts[ 1 ].x, nearVerts[ 1 ].y, nearVerts[ 1 ].z ); - frustumLinePositions.needsUpdate = true; - - } - - } - - THREE.CSMHelper = CSMHelper; - -} )(); diff --git a/examples/js/csm/CSMShader.js b/examples/js/csm/CSMShader.js deleted file mode 100644 index 398634b2f6525b..00000000000000 --- a/examples/js/csm/CSMShader.js +++ /dev/null @@ -1,257 +0,0 @@ -( function () { - - const CSMShader = { - lights_fragment_begin: - /* glsl */ - ` -GeometricContext geometry; - -geometry.position = - vViewPosition; -geometry.normal = normal; -geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition ); - -#ifdef CLEARCOAT - - geometry.clearcoatNormal = clearcoatNormal; - -#endif - -IncidentLight directLight; - -#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct ) - - PointLight pointLight; - #if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0 - PointLightShadow pointLightShadow; - #endif - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) { - - pointLight = pointLights[ i ]; - - getPointLightInfo( pointLight, geometry, directLight ); - - #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS ) - pointLightShadow = pointLightShadows[ i ]; - directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0; - #endif - - RE_Direct( directLight, geometry, material, reflectedLight ); - - } - #pragma unroll_loop_end - -#endif - -#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct ) - - SpotLight spotLight; - #if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0 - SpotLightShadow spotLightShadow; - #endif - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) { - - spotLight = spotLights[ i ]; - - getSpotLightInfo( spotLight, geometry, directLight ); - - #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; - #endif - - RE_Direct( directLight, geometry, material, reflectedLight ); - - } - #pragma unroll_loop_end - -#endif - -#if ( NUM_DIR_LIGHTS > 0) && defined( RE_Direct ) && defined( USE_CSM ) && defined( CSM_CASCADES ) - - DirectionalLight directionalLight; - float linearDepth = (vViewPosition.z) / (shadowFar - cameraNear); - #if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0 - DirectionalLightShadow directionalLightShadow; - #endif - - #if defined( USE_SHADOWMAP ) && defined( CSM_FADE ) - vec2 cascade; - float cascadeCenter; - float closestEdge; - float margin; - float csmx; - float csmy; - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) { - - directionalLight = directionalLights[ i ]; - getDirectionalLightInfo( directionalLight, geometry, directLight ); - - #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS ) - // NOTE: Depth gets larger away from the camera. - // cascade.x is closer, cascade.y is further - cascade = CSM_cascades[ i ]; - cascadeCenter = ( cascade.x + cascade.y ) / 2.0; - closestEdge = linearDepth < cascadeCenter ? cascade.x : cascade.y; - margin = 0.25 * pow( closestEdge, 2.0 ); - csmx = cascade.x - margin / 2.0; - csmy = cascade.y + margin / 2.0; - if( linearDepth >= csmx && ( linearDepth < csmy || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 ) ) { - - float dist = min( linearDepth - csmx, csmy - linearDepth ); - float ratio = clamp( dist / margin, 0.0, 1.0 ); - - vec3 prevColor = directLight.color; - directionalLightShadow = directionalLightShadows[ i ]; - directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0; - - bool shouldFadeLastCascade = UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth > cascadeCenter; - directLight.color = mix( prevColor, directLight.color, shouldFadeLastCascade ? ratio : 1.0 ); - - ReflectedLight prevLight = reflectedLight; - RE_Direct( directLight, geometry, material, reflectedLight ); - - bool shouldBlend = UNROLLED_LOOP_INDEX != CSM_CASCADES - 1 || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth < cascadeCenter; - float blendRatio = shouldBlend ? ratio : 1.0; - - reflectedLight.directDiffuse = mix( prevLight.directDiffuse, reflectedLight.directDiffuse, blendRatio ); - reflectedLight.directSpecular = mix( prevLight.directSpecular, reflectedLight.directSpecular, blendRatio ); - reflectedLight.indirectDiffuse = mix( prevLight.indirectDiffuse, reflectedLight.indirectDiffuse, blendRatio ); - reflectedLight.indirectSpecular = mix( prevLight.indirectSpecular, reflectedLight.indirectSpecular, blendRatio ); - - } - #endif - - } - #pragma unroll_loop_end - #else - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) { - - directionalLight = directionalLights[ i ]; - getDirectionalLightInfo( directionalLight, geometry, directLight ); - - #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS ) - - directionalLightShadow = directionalLightShadows[ i ]; - if(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y) directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0; - - if(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && (linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1)) RE_Direct( directLight, geometry, material, reflectedLight ); - - #endif - - } - #pragma unroll_loop_end - - #endif - - #if ( NUM_DIR_LIGHTS > NUM_DIR_LIGHT_SHADOWS) - // compute the lights not casting shadows (if any) - - #pragma unroll_loop_start - for ( int i = NUM_DIR_LIGHT_SHADOWS; i < NUM_DIR_LIGHTS; i ++ ) { - - directionalLight = directionalLights[ i ]; - - getDirectionalLightInfo( directionalLight, geometry, directLight ); - - RE_Direct( directLight, geometry, material, reflectedLight ); - - } - #pragma unroll_loop_end - - #endif - -#endif - - -#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct ) && !defined( USE_CSM ) && !defined( CSM_CASCADES ) - - DirectionalLight directionalLight; - #if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0 - DirectionalLightShadow directionalLightShadow; - #endif - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) { - - directionalLight = directionalLights[ i ]; - - getDirectionalLightInfo( directionalLight, geometry, directLight ); - - #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS ) - directionalLightShadow = directionalLightShadows[ i ]; - directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0; - #endif - - RE_Direct( directLight, geometry, material, reflectedLight ); - - } - #pragma unroll_loop_end - -#endif - -#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea ) - - RectAreaLight rectAreaLight; - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) { - - rectAreaLight = rectAreaLights[ i ]; - RE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight ); - - } - #pragma unroll_loop_end - -#endif - -#if defined( RE_IndirectDiffuse ) - - vec3 iblIrradiance = vec3( 0.0 ); - - vec3 irradiance = getAmbientLightIrradiance( ambientLightColor ); - - irradiance += getLightProbeIrradiance( lightProbe, geometry.normal ); - - #if ( NUM_HEMI_LIGHTS > 0 ) - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) { - - irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal ); - - } - #pragma unroll_loop_end - - #endif - -#endif - -#if defined( RE_IndirectSpecular ) - - vec3 radiance = vec3( 0.0 ); - vec3 clearcoatRadiance = vec3( 0.0 ); - -#endif -`, - lights_pars_begin: - /* glsl */ - ` -#if defined( USE_CSM ) && defined( CSM_CASCADES ) -uniform vec2 CSM_cascades[CSM_CASCADES]; -uniform float cameraNear; -uniform float shadowFar; -#endif - ` + THREE.ShaderChunk.lights_pars_begin - }; - - THREE.CSMShader = CSMShader; - -} )(); diff --git a/examples/js/curves/CurveExtras.js b/examples/js/curves/CurveExtras.js deleted file mode 100644 index f7772f0191e2ea..00000000000000 --- a/examples/js/curves/CurveExtras.js +++ /dev/null @@ -1,348 +0,0 @@ -( function () { - - /** - * A bunch of parametric curves - * - * Formulas collected from various sources - * http://mathworld.wolfram.com/HeartCurve.html - * http://en.wikipedia.org/wiki/Viviani%27s_curve - * 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 { - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - t = 2 * Math.PI * t; - const x = - 0.22 * Math.cos( t ) - 1.28 * Math.sin( t ) - 0.44 * Math.cos( 3 * t ) - 0.78 * Math.sin( 3 * t ); - const y = - 0.1 * Math.cos( 2 * t ) - 0.27 * Math.sin( 2 * t ) + 0.38 * Math.cos( 4 * t ) + 0.46 * Math.sin( 4 * t ); - const z = 0.7 * Math.cos( 3 * t ) - 0.4 * Math.sin( 3 * t ); - return point.set( x, y, z ).multiplyScalar( 20 ); - - } - - } // HeartCurve - - - class HeartCurve extends THREE.Curve { - - constructor( scale = 5 ) { - - super(); - this.scale = scale; - - } - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - t *= 2 * Math.PI; - const x = 16 * Math.pow( Math.sin( t ), 3 ); - const y = 13 * Math.cos( t ) - 5 * Math.cos( 2 * t ) - 2 * Math.cos( 3 * t ) - Math.cos( 4 * t ); - const z = 0; - return point.set( x, y, z ).multiplyScalar( this.scale ); - - } - - } // Viviani's THREE.Curve - - - class VivianiCurve extends THREE.Curve { - - constructor( scale = 70 ) { - - super(); - 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 ); - const z = 2 * a * Math.sin( t / 2 ); - return point.set( x, y, z ); - - } - - } // KnotCurve - - - class KnotCurve extends THREE.Curve { - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - t *= 2 * Math.PI; - const R = 10; - const s = 50; - const x = s * Math.sin( t ); - const y = Math.cos( t ) * ( R + s * Math.cos( t ) ); - const z = Math.sin( t ) * ( R + s * Math.cos( t ) ); - return point.set( x, y, z ); - - } - - } // HelixCurve - - - class HelixCurve extends THREE.Curve { - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - const a = 30; // radius - - const b = 150; // height - - const t2 = 2 * Math.PI * t * b / 30; - const x = Math.cos( t2 ) * a; - const y = Math.sin( t2 ) * a; - const z = b * t; - return point.set( x, y, z ); - - } - - } // TrefoilKnot - - - class TrefoilKnot extends THREE.Curve { - - constructor( scale = 10 ) { - - super(); - this.scale = scale; - - } - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - t *= Math.PI * 2; - const x = ( 2 + Math.cos( 3 * t ) ) * Math.cos( 2 * t ); - const y = ( 2 + Math.cos( 3 * t ) ) * Math.sin( 2 * t ); - const z = Math.sin( 3 * t ); - return point.set( x, y, z ).multiplyScalar( this.scale ); - - } - - } // TorusKnot - - - class TorusKnot extends THREE.Curve { - - constructor( scale = 10 ) { - - super(); - this.scale = scale; - - } - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - const p = 3; - const q = 4; - t *= Math.PI * 2; - const x = ( 2 + Math.cos( q * t ) ) * Math.cos( p * t ); - const y = ( 2 + Math.cos( q * t ) ) * Math.sin( p * t ); - const z = Math.sin( q * t ); - return point.set( x, y, z ).multiplyScalar( this.scale ); - - } - - } // CinquefoilKnot - - - class CinquefoilKnot extends THREE.Curve { - - constructor( scale = 10 ) { - - super(); - this.scale = scale; - - } - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - const p = 2; - const q = 5; - t *= Math.PI * 2; - const x = ( 2 + Math.cos( q * t ) ) * Math.cos( p * t ); - const y = ( 2 + Math.cos( q * t ) ) * Math.sin( p * t ); - const z = Math.sin( q * t ); - return point.set( x, y, z ).multiplyScalar( this.scale ); - - } - - } // TrefoilPolynomialKnot - - - class TrefoilPolynomialKnot extends THREE.Curve { - - constructor( scale = 10 ) { - - super(); - this.scale = scale; - - } - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - t = t * 4 - 2; - const x = Math.pow( t, 3 ) - 3 * t; - const y = Math.pow( t, 4 ) - 4 * t * t; - const z = 1 / 5 * Math.pow( t, 5 ) - 2 * t; - return point.set( x, y, z ).multiplyScalar( this.scale ); - - } - - } - - function scaleTo( x, y, t ) { - - const r = y - x; - return t * r + x; - - } // FigureEightPolynomialKnot - - - class FigureEightPolynomialKnot extends THREE.Curve { - - constructor( scale = 1 ) { - - super(); - this.scale = scale; - - } - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - t = scaleTo( - 4, 4, t ); - const x = 2 / 5 * t * ( t * t - 7 ) * ( t * t - 10 ); - const y = Math.pow( t, 4 ) - 13 * t * t; - const z = 1 / 10 * t * ( t * t - 4 ) * ( t * t - 9 ) * ( t * t - 12 ); - return point.set( x, y, z ).multiplyScalar( this.scale ); - - } - - } // DecoratedTorusKnot4a - - - class DecoratedTorusKnot4a extends THREE.Curve { - - constructor( scale = 40 ) { - - super(); - this.scale = scale; - - } - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - t *= Math.PI * 2; - const x = Math.cos( 2 * t ) * ( 1 + 0.6 * ( Math.cos( 5 * t ) + 0.75 * Math.cos( 10 * t ) ) ); - const y = Math.sin( 2 * t ) * ( 1 + 0.6 * ( Math.cos( 5 * t ) + 0.75 * Math.cos( 10 * t ) ) ); - const z = 0.35 * Math.sin( 5 * t ); - return point.set( x, y, z ).multiplyScalar( this.scale ); - - } - - } // DecoratedTorusKnot4b - - - class DecoratedTorusKnot4b extends THREE.Curve { - - constructor( scale = 40 ) { - - super(); - this.scale = scale; - - } - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - const fi = t * Math.PI * 2; - const x = Math.cos( 2 * fi ) * ( 1 + 0.45 * Math.cos( 3 * fi ) + 0.4 * Math.cos( 9 * fi ) ); - const y = Math.sin( 2 * fi ) * ( 1 + 0.45 * Math.cos( 3 * fi ) + 0.4 * Math.cos( 9 * fi ) ); - const z = 0.2 * Math.sin( 9 * fi ); - return point.set( x, y, z ).multiplyScalar( this.scale ); - - } - - } // DecoratedTorusKnot5a - - - class DecoratedTorusKnot5a extends THREE.Curve { - - constructor( scale = 40 ) { - - super(); - this.scale = scale; - - } - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - const fi = t * Math.PI * 2; - const x = Math.cos( 3 * fi ) * ( 1 + 0.3 * Math.cos( 5 * fi ) + 0.5 * Math.cos( 10 * fi ) ); - const y = Math.sin( 3 * fi ) * ( 1 + 0.3 * Math.cos( 5 * fi ) + 0.5 * Math.cos( 10 * fi ) ); - const z = 0.2 * Math.sin( 20 * fi ); - return point.set( x, y, z ).multiplyScalar( this.scale ); - - } - - } // DecoratedTorusKnot5c - - - class DecoratedTorusKnot5c extends THREE.Curve { - - constructor( scale = 40 ) { - - super(); - this.scale = scale; - - } - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - const fi = t * Math.PI * 2; - const x = Math.cos( 4 * fi ) * ( 1 + 0.5 * ( Math.cos( 5 * fi ) + 0.4 * Math.cos( 20 * fi ) ) ); - const y = Math.sin( 4 * fi ) * ( 1 + 0.5 * ( Math.cos( 5 * fi ) + 0.4 * Math.cos( 20 * fi ) ) ); - const z = 0.35 * Math.sin( 15 * fi ); - return point.set( x, y, z ).multiplyScalar( this.scale ); - - } - - } - - THREE.CinquefoilKnot = CinquefoilKnot; - THREE.DecoratedTorusKnot4a = DecoratedTorusKnot4a; - THREE.DecoratedTorusKnot4b = DecoratedTorusKnot4b; - THREE.DecoratedTorusKnot5a = DecoratedTorusKnot5a; - THREE.DecoratedTorusKnot5c = DecoratedTorusKnot5c; - THREE.FigureEightPolynomialKnot = FigureEightPolynomialKnot; - THREE.GrannyKnot = GrannyKnot; - THREE.HeartCurve = HeartCurve; - THREE.HelixCurve = HelixCurve; - THREE.KnotCurve = KnotCurve; - THREE.TorusKnot = TorusKnot; - THREE.TrefoilKnot = TrefoilKnot; - THREE.TrefoilPolynomialKnot = TrefoilPolynomialKnot; - THREE.VivianiCurve = VivianiCurve; - -} )(); diff --git a/examples/js/curves/NURBSCurve.js b/examples/js/curves/NURBSCurve.js deleted file mode 100644 index 21d0ceecaa31a7..00000000000000 --- a/examples/js/curves/NURBSCurve.js +++ /dev/null @@ -1,75 +0,0 @@ -( function () { - - /** - * NURBS curve object - * - * Derives from THREE.Curve, overriding getPoint and getTangent. - * - * Implementation is based on (x, y [, z=0 [, w=1]]) control points with w=weight. - * - **/ - - 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 */ - ) { - - super(); - this.degree = degree; - this.knots = knots; - 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 - const point = controlPoints[ i ]; - this.controlPoints[ i ] = new THREE.Vector4( point.x, point.y, point.z, point.w ); - - } - - } - - 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 - - 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) - hpoint.divideScalar( hpoint.w ); - - } - - return point.set( hpoint.x, hpoint.y, hpoint.z ); - - } - - getTangent( t, optionalTarget = new THREE.Vector3() ) { - - const tangent = optionalTarget; - const u = this.knots[ 0 ] + t * ( this.knots[ this.knots.length - 1 ] - this.knots[ 0 ] ); - const ders = THREE.NURBSUtils.calcNURBSDerivatives( this.degree, this.knots, this.controlPoints, u, 1 ); - tangent.copy( ders[ 1 ] ).normalize(); - return tangent; - - } - - } - - THREE.NURBSCurve = NURBSCurve; - -} )(); diff --git a/examples/js/curves/NURBSSurface.js b/examples/js/curves/NURBSSurface.js deleted file mode 100644 index 7c67c0fd06e536..00000000000000 --- a/examples/js/curves/NURBSSurface.js +++ /dev/null @@ -1,54 +0,0 @@ -( function () { - - /** - * NURBS surface object - * - * Implementation is based on (x, y [, z=0 [, w=1]]) control points with w=weight. - **/ - - class NURBSSurface { - - constructor( degree1, degree2, knots1, knots2 - /* arrays of reals */ - , controlPoints - /* array^2 of Vector(2|3|4) */ - ) { - - this.degree1 = degree1; - this.degree2 = degree2; - this.knots1 = knots1; - this.knots2 = knots2; - this.controlPoints = []; - const len1 = knots1.length - degree1 - 1; - 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 ]; - this.controlPoints[ i ][ j ] = new THREE.Vector4( point.x, point.y, point.z, point.w ); - - } - - } - - } - - 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 ); - - } - - } - - THREE.NURBSSurface = NURBSSurface; - -} )(); diff --git a/examples/js/curves/NURBSUtils.js b/examples/js/curves/NURBSUtils.js deleted file mode 100644 index d42b0259f18b8d..00000000000000 --- a/examples/js/curves/NURBSUtils.js +++ /dev/null @@ -1,476 +0,0 @@ -( function () { - - /** - * NURBS utils - * - * See NURBSCurve and NURBSSurface. - **/ - - /************************************************************** - * NURBS Utils - **************************************************************/ - - /* -Finds knot vector span. - -p : degree -u : parametric value -U : knot vector - -returns the span -*/ - - function findSpan( p, u, U ) { - - const n = U.length - p - 1; - - if ( u >= U[ n ] ) { - - return n - 1; - - } - - if ( u <= U[ p ] ) { - - return p; - - } - - 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 ] ) { - - high = mid; - - } else { - - low = mid; - - } - - mid = Math.floor( ( low + high ) / 2 ); - - } - - return mid; - - } - /* -Calculate basis functions. See The NURBS Book, page 70, algorithm A2.2 - -span : span in which u lies -u : parametric point -p : degree -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 ]; - const lv = left[ j - r ]; - const temp = N[ r ] / ( rv + lv ); - N[ r ] = saved + rv * temp; - saved = lv * temp; - - } - - N[ j ] = saved; - - } - - return N; - - } - /* -Calculate B-Spline curve points. See The NURBS Book, page 82, algorithm A3.1. - -p : degree of B-Spline -U : knot vector -P : control points (x, y, z, w) -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 ]; - const Nj = N[ j ]; - const wNj = point.w * Nj; - C.x += point.x * wNj; - C.y += point.y * wNj; - C.z += point.z * wNj; - C.w += point.w * Nj; - - } - - return C; - - } - /* -Calculate basis functions derivatives. See The NURBS Book, page 72, algorithm A2.3. - -span : span in which u lies -u : parametric point -p : degree -n : number of derivatives to calculate -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 ]; - const lv = left[ j - r ]; - ndu[ j ][ r ] = rv + lv; - const temp = ndu[ r ][ j - 1 ] / ndu[ j ][ r ]; - ndu[ r ][ j ] = saved + rv * temp; - saved = lv * temp; - - } - - ndu[ j ][ j ] = saved; - - } - - for ( let j = 0; j <= p; ++ j ) { - - ders[ 0 ][ j ] = ndu[ j ][ p ]; - - } - - for ( let r = 0; r <= p; ++ r ) { - - let s1 = 0; - let s2 = 1; - const a = []; - - for ( let i = 0; i <= p; ++ i ) { - - a[ i ] = zeroArr.slice( 0 ); - - } - - 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 ]; - d = a[ s2 ][ 0 ] * ndu[ rk ][ pk ]; - - } - - 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 ]; - d += a[ s2 ][ j ] * ndu[ rk + j ][ pk ]; - - } - - if ( r <= pk ) { - - a[ s2 ][ k ] = - a[ s1 ][ k - 1 ] / ndu[ pk + 1 ][ r ]; - d += a[ s2 ][ k ] * ndu[ r ][ pk ]; - - } - - ders[ k ][ r ] = d; - const j = s1; - s1 = s2; - s2 = j; - - } - - } - - let r = p; - - for ( let k = 1; k <= n; ++ k ) { - - for ( let j = 0; j <= p; ++ j ) { - - ders[ k ][ j ] *= r; - - } - - r *= p - k; - - } - - return ders; - - } - /* - Calculate derivatives of a B-Spline. See The NURBS Book, page 93, algorithm A3.2. - - p : degree - U : knot vector - P : control points - u : Parametric points - nd : number of derivatives - - returns array[d+1] with derivatives - */ - - - function calcBSplineDerivatives( p, U, P, u, nd ) { - - const du = nd < p ? nd : p; - const CK = []; - 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(); - const w = point.w; - point.x *= w; - point.y *= w; - point.z *= w; - Pw[ i ] = point; - - } - - 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 ] ) ); - - } - - CK[ k ] = point; - - } - - for ( let k = du + 1; k <= nd + 1; ++ k ) { - - CK[ k ] = new THREE.Vector4( 0, 0, 0 ); - - } - - 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; - - } - - let denom = 1; - - for ( let j = 2; j <= i; ++ j ) { - - denom *= j; - - } - - for ( let j = 2; j <= k - i; ++ j ) { - - denom *= j; - - } - - return nom / denom; - - } - /* -Calculate derivatives (0-nd) of rational curve. See The NURBS Book, page 127, algorithm A4.2. - -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 ]; - Aders[ i ] = new THREE.Vector3( point.x, point.y, point.z ); - wders[ i ] = point.w; - - } - - 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 ] ) ); - - } - - CK[ k ] = v.divideScalar( wders[ 0 ] ); - - } - - return CK; - - } - /* -Calculate NURBS curve derivatives. See The NURBS Book, page 127, algorithm A4.2. - -p : degree -U : knot vector -P : control points in homogeneous space -u : parametric points -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. - -p1, p2 : degrees of B-Spline surface -U1, U2 : knot vectors -P : control points (x, y, z, w) -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 ); - const vspan = findSpan( q, v, 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(); - const w = point.w; - point.x *= w; - point.y *= w; - point.z *= w; - temp[ l ].add( point.multiplyScalar( Nu[ k ] ) ); - - } - - } - - const Sw = new THREE.Vector4( 0, 0, 0, 0 ); - - for ( let l = 0; l <= q; ++ l ) { - - Sw.add( temp[ l ].multiplyScalar( Nv[ l ] ) ); - - } - - Sw.divideScalar( Sw.w ); - target.set( Sw.x, Sw.y, Sw.z ); - - } - - THREE.NURBSUtils = {}; - THREE.NURBSUtils.calcBSplineDerivatives = calcBSplineDerivatives; - THREE.NURBSUtils.calcBSplinePoint = calcBSplinePoint; - THREE.NURBSUtils.calcBasisFunctionDerivatives = calcBasisFunctionDerivatives; - THREE.NURBSUtils.calcBasisFunctions = calcBasisFunctions; - THREE.NURBSUtils.calcKoverI = calcKoverI; - THREE.NURBSUtils.calcNURBSDerivatives = calcNURBSDerivatives; - THREE.NURBSUtils.calcRationalCurveDerivatives = calcRationalCurveDerivatives; - THREE.NURBSUtils.calcSurfacePoint = calcSurfacePoint; - THREE.NURBSUtils.findSpan = findSpan; - -} )(); diff --git a/examples/js/effects/AnaglyphEffect.js b/examples/js/effects/AnaglyphEffect.js deleted file mode 100644 index be737968f8ccee..00000000000000 --- a/examples/js/effects/AnaglyphEffect.js +++ /dev/null @@ -1,100 +0,0 @@ -( function () { - - class AnaglyphEffect { - - 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': { - value: _renderTargetL.texture - }, - 'mapRight': { - value: _renderTargetR.texture - }, - 'colorMatrixLeft': { - value: this.colorMatrixLeft - }, - 'colorMatrixRight': { - value: this.colorMatrixRight - } - }, - 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 - '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 ); - - }; - - this.render = function ( scene, camera ) { - - const currentRenderTarget = renderer.getRenderTarget(); - scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); - - _stereo.update( camera ); - - renderer.setRenderTarget( _renderTargetL ); - renderer.clear(); - renderer.render( scene, _stereo.cameraL ); - renderer.setRenderTarget( _renderTargetR ); - renderer.clear(); - renderer.render( scene, _stereo.cameraR ); - renderer.setRenderTarget( null ); - renderer.render( _scene, _camera ); - renderer.setRenderTarget( currentRenderTarget ); - - }; - - this.dispose = function () { - - _renderTargetL.dispose(); - - _renderTargetR.dispose(); - - _mesh.geometry.dispose(); - - _mesh.material.dispose(); - - }; - - } - - } - - THREE.AnaglyphEffect = AnaglyphEffect; - -} )(); diff --git a/examples/js/effects/AsciiEffect.js b/examples/js/effects/AsciiEffect.js deleted file mode 100644 index ecd24e03f5650e..00000000000000 --- a/examples/js/effects/AsciiEffect.js +++ /dev/null @@ -1,259 +0,0 @@ -( function () { - - /** - * Ascii generation is based on https://github.com/hassadee/jsascii/blob/master/jsascii.js - * - * 16 April 2012 - @blurspline - */ - class AsciiEffect { - - constructor( renderer, charSet = ' .:-=+*#%@', options = {} ) { - - // ' .,:;=|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 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' ); - domElement.style.cursor = 'default'; - const oAscii = document.createElement( 'table' ); - domElement.appendChild( oAscii ); - let iWidth, iHeight; - let oImg; - - this.setSize = function ( w, h ) { - - width = w; - height = h; - renderer.setSize( w, h ); - initAsciiSize(); - - }; - - this.render = function ( scene, camera ) { - - renderer.render( scene, camera ); - asciifyImage( oAscii ); - - }; - - 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.style.width = iWidth; - // oCanvas.style.height = iHeight; - - oImg = renderer.domElement; - - if ( oImg.style.backgroundColor ) { - - oAscii.rows[ 0 ].cells[ 0 ].style.backgroundColor = oImg.style.backgroundColor; - oAscii.rows[ 0 ].cells[ 0 ].style.color = oImg.style.color; - - } - - oAscii.cellSpacing = 0; - oAscii.cellPadding = 0; - const oStyle = oAscii.style; - oStyle.display = 'inline'; - oStyle.width = Math.round( iWidth / fResolution * iScale ) + 'px'; - oStyle.height = Math.round( iHeight / fResolution * iScale ) + 'px'; - oStyle.whiteSpace = 'pre'; - oStyle.margin = '0px'; - oStyle.padding = '0px'; - oStyle.letterSpacing = fLetterSpacing + 'px'; - oStyle.fontFamily = strFont; - oStyle.fontSize = fFontSize + 'px'; - oStyle.lineHeight = fLineHeight + 'px'; - oStyle.textAlign = 'left'; - oStyle.textDecoration = 'none'; - - } - - const aDefaultCharList = ' .,:;i1tfLCG08@'.split( '' ); - const aDefaultColorCharList = ' CGO08@'.split( '' ); - const strFont = 'courier new, monospace'; - const oCanvasImg = renderer.domElement; - const oCanvas = document.createElement( 'canvas' ); - - if ( ! oCanvas.getContext ) { - - return; - - } - - const oCtx = oCanvas.getContext( '2d' ); - - if ( ! oCtx.getImageData ) { - - return; - - } - - let aCharList = bColor ? aDefaultColorCharList : aDefaultCharList; - 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. - - let fLetterSpacing = 0; - - if ( strResolution == 'low' ) { - - switch ( iScale ) { - - 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; - - } - - } - - if ( strResolution == 'medium' ) { - - switch ( iScale ) { - - case 1: - fLetterSpacing = 0; - break; - - case 2: - fLetterSpacing = - 1; - break; - - case 3: - fLetterSpacing = - 1.04; - break; - - case 4: - case 5: - fLetterSpacing = - 2.1; - break; - - } - - } - - if ( strResolution == 'high' ) { - - switch ( iScale ) { - - case 1: - case 2: - fLetterSpacing = 0; - break; - - case 3: - case 4: - case 5: - fLetterSpacing = - 1; - break; - - } - - } // 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 - - let strChars = ''; // console.time('rendering'); - - for ( let y = 0; y < iHeight; y += 2 ) { - - for ( let x = 0; x < iWidth; x ++ ) { - - const iOffset = ( y * iWidth + x ) * 4; - const iRed = oImgData[ iOffset ]; - const iGreen = oImgData[ iOffset + 1 ]; - const iBlue = oImgData[ iOffset + 2 ]; - 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; - - if ( iAlpha == 0 ) { - - // should calculate alpha instead, but quick hack :) - //fBrightness *= (iAlpha / 255); - fBrightness = 1; - - } - - iCharIdx = Math.floor( ( 1 - fBrightness ) * ( aCharList.length - 1 ) ); - - if ( bInvert ) { - - iCharIdx = aCharList.length - iCharIdx - 1; - - } // good for debugging - //fBrightness = Math.floor(fBrightness * 10); - //strThisChar = fBrightness; - - - let strThisChar = aCharList[ iCharIdx ]; - if ( strThisChar === undefined || strThisChar == ' ' ) strThisChar = ' '; - - if ( bColor ) { - - strChars += '' + strThisChar + ''; - - } else { - - strChars += strThisChar; - - } - - } - - strChars += '
          '; - - } - - oAscii.innerHTML = '' + strChars + ''; // console.timeEnd('rendering'); - // return oAscii; - - } - - } - - } - - THREE.AsciiEffect = AsciiEffect; - -} )(); diff --git a/examples/js/effects/OutlineEffect.js b/examples/js/effects/OutlineEffect.js deleted file mode 100644 index 3d9bdbf89613bc..00000000000000 --- a/examples/js/effects/OutlineEffect.js +++ /dev/null @@ -1,474 +0,0 @@ -( function () { - - /** - * Reference: https://en.wikipedia.org/wiki/Cel_shading - * - * API - * - * 1. Traditional - * - * const effect = new OutlineEffect( renderer ); - * - * function render() { - * - * effect.render( scene, camera ); - * - * } - * - * 2. VR compatible - * - * const effect = new OutlineEffect( renderer ); - * let renderingOutline = false; - * - * scene.onAfterRender = function () { - * - * if ( renderingOutline ) return; - * - * renderingOutline = true; - * - * effect.renderOutline( scene, camera ); - * - * renderingOutline = false; - * - * }; - * - * function render() { - * - * renderer.render( scene, camera ); - * - * } - * - * // How to set default outline parameters - * new OutlineEffect( renderer, { - * defaultThickness: 0.01, - * defaultColor: [ 0, 0, 0 ], - * defaultAlpha: 0.8, - * defaultKeepAlive: true // keeps outline material in cache even if material is removed from scene - * } ); - * - * // How to set outline parameters for each material - * material.userData.outlineParameters = { - * thickness: 0.01, - * color: [ 0, 0, 0 ] - * alpha: 0.8, - * visible: true, - * keepAlive: true - * }; - */ - - class OutlineEffect { - - constructor( renderer, parameters = {} ) { - - this.enabled = true; - 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 - // 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 - // outlineMaterial.uuid -> object.material[ n ] - // save before render and release after render. - - const originalMaterials = {}; // object.uuid -> originalOnBeforeRender - // save before render and release after render. - - const originalOnBeforeRenders = {}; //this.cache = cache; // for debug - - const uniformsOutline = { - outlineThickness: { - value: defaultThickness - }, - outlineColor: { - value: defaultColor - }, - outlineAlpha: { - 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 - ' 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( { - type: 'OutlineEffect', - uniforms: THREE.UniformsUtils.merge( [ THREE.UniformsLib[ 'fog' ], THREE.UniformsLib[ 'displacementmap' ], uniformsOutline ] ), - vertexShader: vertexShader, - fragmentShader: fragmentShader, - side: THREE.BackSide - } ); - - } - - function getOutlineMaterialFromCache( originalMaterial ) { - - let data = cache[ originalMaterial.uuid ]; - - if ( data === undefined ) { - - data = { - material: createMaterial(), - used: true, - keepAlive: defaultKeepAlive, - count: 0 - }; - cache[ originalMaterial.uuid ] = data; - - } - - data.used = true; - return data.material; - - } - - function getOutlineMaterial( originalMaterial ) { - - const outlineMaterial = getOutlineMaterialFromCache( originalMaterial ); - originalMaterials[ outlineMaterial.uuid ] = originalMaterial; - updateOutlineMaterial( outlineMaterial, originalMaterial ); - return outlineMaterial; - - } - - function isCompatible( object ) { - - const geometry = object.geometry; - let hasNormals = false; - - if ( object.geometry !== undefined ) { - - if ( geometry.isBufferGeometry ) { - - hasNormals = geometry.attributes.normal !== undefined; - - } else { - - hasNormals = true; // the renderer always produces a normal attribute for Geometry - - } - - } - - return object.isMesh === true && object.material !== undefined && hasNormals === true; - - } - - function setOutlineMaterial( object ) { - - if ( isCompatible( object ) === false ) return; - - if ( Array.isArray( object.material ) ) { - - for ( let i = 0, il = object.material.length; i < il; i ++ ) { - - object.material[ i ] = getOutlineMaterial( object.material[ i ] ); - - } - - } else { - - object.material = getOutlineMaterial( object.material ); - - } - - originalOnBeforeRenders[ object.uuid ] = object.onBeforeRender; - object.onBeforeRender = onBeforeRender; - - } - - function restoreOriginalMaterial( object ) { - - if ( isCompatible( object ) === false ) return; - - if ( Array.isArray( object.material ) ) { - - for ( let i = 0, il = object.material.length; i < il; i ++ ) { - - object.material[ i ] = originalMaterials[ object.material[ i ].uuid ]; - - } - - } else { - - object.material = originalMaterials[ object.material.uuid ]; - - } - - object.onBeforeRender = originalOnBeforeRenders[ object.uuid ]; - - } - - function onBeforeRender( renderer, scene, camera, geometry, material ) { - - const originalMaterial = originalMaterials[ material.uuid ]; // just in case - - if ( originalMaterial === undefined ) return; - updateUniforms( material, originalMaterial ); - - } - - function updateUniforms( material, originalMaterial ) { - - const outlineParameters = originalMaterial.userData.outlineParameters; - material.uniforms.outlineAlpha.value = originalMaterial.opacity; - - if ( outlineParameters !== undefined ) { - - if ( outlineParameters.thickness !== undefined ) material.uniforms.outlineThickness.value = outlineParameters.thickness; - if ( outlineParameters.color !== undefined ) material.uniforms.outlineColor.value.fromArray( outlineParameters.color ); - if ( outlineParameters.alpha !== undefined ) material.uniforms.outlineAlpha.value = outlineParameters.alpha; - - } - - if ( originalMaterial.displacementMap ) { - - material.uniforms.displacementMap.value = originalMaterial.displacementMap; - material.uniforms.displacementScale.value = originalMaterial.displacementScale; - material.uniforms.displacementBias.value = originalMaterial.displacementBias; - - } - - } - - function updateOutlineMaterial( material, originalMaterial ) { - - if ( material.name === 'invisible' ) return; - const outlineParameters = originalMaterial.userData.outlineParameters; - material.fog = originalMaterial.fog; - material.toneMapped = originalMaterial.toneMapped; - material.premultipliedAlpha = originalMaterial.premultipliedAlpha; - material.displacementMap = originalMaterial.displacementMap; - - if ( outlineParameters !== undefined ) { - - if ( originalMaterial.visible === false ) { - - material.visible = false; - - } else { - - material.visible = outlineParameters.visible !== undefined ? outlineParameters.visible : true; - - } - - material.transparent = outlineParameters.alpha !== undefined && outlineParameters.alpha < 1.0 ? true : originalMaterial.transparent; - if ( outlineParameters.keepAlive !== undefined ) cache[ originalMaterial.uuid ].keepAlive = outlineParameters.keepAlive; - - } else { - - material.transparent = originalMaterial.transparent; - material.visible = originalMaterial.visible; - - } - - if ( originalMaterial.wireframe === true || originalMaterial.depthTest === false ) material.visible = false; - - if ( originalMaterial.clippingPlanes ) { - - material.clipping = true; - material.clippingPlanes = originalMaterial.clippingPlanes; - material.clipIntersection = originalMaterial.clipIntersection; - material.clipShadows = originalMaterial.clipShadows; - - } - - material.version = originalMaterial.version; // update outline material if necessary - - } - - function cleanupCache() { - - let keys; // clear originialMaterials - - keys = Object.keys( originalMaterials ); - - for ( let i = 0, il = keys.length; i < il; i ++ ) { - - originalMaterials[ keys[ i ] ] = undefined; - - } // 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 - - - 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 ]; - - } - - } else { - - cache[ key ].used = false; - cache[ key ].count = 0; - - } - - } - - } - - 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 ); - return; - - } - - const currentAutoClear = renderer.autoClear; - renderer.autoClear = this.autoClear; - renderer.render( scene, camera ); - renderer.autoClear = currentAutoClear; - this.renderOutline( scene, camera ); - - }; - - this.renderOutline = function ( scene, camera ) { - - const currentAutoClear = renderer.autoClear; - const currentSceneAutoUpdate = scene.autoUpdate; - const currentSceneBackground = scene.background; - const currentShadowMapEnabled = renderer.shadowMap.enabled; - scene.autoUpdate = false; - scene.background = null; - renderer.autoClear = false; - renderer.shadowMap.enabled = false; - scene.traverse( setOutlineMaterial ); - renderer.render( scene, camera ); - scene.traverse( restoreOriginalMaterial ); - cleanupCache(); - scene.autoUpdate = currentSceneAutoUpdate; - scene.background = currentSceneBackground; - renderer.autoClear = currentAutoClear; - renderer.shadowMap.enabled = currentShadowMapEnabled; - - }; - /* - * See #9918 - * - * The following property copies and wrapper methods enable - * OutlineEffect to be called from other *Effect, like - * - * effect = new StereoEffect( new OutlineEffect( renderer ) ); - * - * function render () { - * - * effect.render( scene, camera ); - * - * } - */ - - - this.autoClear = renderer.autoClear; - this.domElement = renderer.domElement; - this.shadowMap = renderer.shadowMap; - - this.clear = function ( color, depth, stencil ) { - - renderer.clear( color, depth, stencil ); - - }; - - this.getPixelRatio = function () { - - return renderer.getPixelRatio(); - - }; - - this.setPixelRatio = function ( value ) { - - renderer.setPixelRatio( value ); - - }; - - this.getSize = function ( target ) { - - return renderer.getSize( target ); - - }; - - this.setSize = function ( width, height, updateStyle ) { - - renderer.setSize( width, height, updateStyle ); - - }; - - this.setViewport = function ( x, y, width, height ) { - - renderer.setViewport( x, y, width, height ); - - }; - - this.setScissor = function ( x, y, width, height ) { - - renderer.setScissor( x, y, width, height ); - - }; - - this.setScissorTest = function ( boolean ) { - - renderer.setScissorTest( boolean ); - - }; - - this.setRenderTarget = function ( renderTarget ) { - - renderer.setRenderTarget( renderTarget ); - - }; - - } - - } - - THREE.OutlineEffect = OutlineEffect; - -} )(); diff --git a/examples/js/effects/ParallaxBarrierEffect.js b/examples/js/effects/ParallaxBarrierEffect.js deleted file mode 100644 index 409ea922573e41..00000000000000 --- a/examples/js/effects/ParallaxBarrierEffect.js +++ /dev/null @@ -1,75 +0,0 @@ -( function () { - - class ParallaxBarrierEffect { - - 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': { - value: _renderTargetL.texture - }, - 'mapRight': { - value: _renderTargetR.texture - } - }, - 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(); - - _stereo.update( camera ); - - renderer.setRenderTarget( _renderTargetL ); - renderer.clear(); - renderer.render( scene, _stereo.cameraL ); - renderer.setRenderTarget( _renderTargetR ); - renderer.clear(); - renderer.render( scene, _stereo.cameraR ); - renderer.setRenderTarget( null ); - renderer.render( _scene, _camera ); - - }; - - } - - } - - THREE.ParallaxBarrierEffect = ParallaxBarrierEffect; - -} )(); diff --git a/examples/js/effects/PeppersGhostEffect.js b/examples/js/effects/PeppersGhostEffect.js deleted file mode 100644 index b7ca0567e4c311..00000000000000 --- a/examples/js/effects/PeppersGhostEffect.js +++ /dev/null @@ -1,166 +0,0 @@ -( function () { - - /** - * peppers ghost effect based on http://www.instructables.com/id/Reflective-Prism/?ALLSTEPS - */ - - class PeppersGhostEffect { - - constructor( renderer ) { - - const scope = this; - scope.cameraDistance = 15; - 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(); // Initialization - - - renderer.autoClear = false; - - this.setSize = function ( width, height ) { - - _halfWidth = width / 2; - - if ( width < height ) { - - _width = width / 3; - _height = width / 3; - - } else { - - _width = height / 3; - _height = height / 3; - - } - - renderer.setSize( width, height ); - - }; - - this.render = function ( scene, camera ) { - - scene.updateMatrixWorld(); - if ( camera.parent === null ) 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 ); // back - - - _cameraB.position.copy( _position ); - - _cameraB.quaternion.copy( _quaternion ); - - _cameraB.translateZ( - scope.cameraDistance ); - - _cameraB.lookAt( scene.position ); - - _cameraB.rotation.z += 180 * ( Math.PI / 180 ); // left - - _cameraL.position.copy( _position ); - - _cameraL.quaternion.copy( _quaternion ); - - _cameraL.translateX( - scope.cameraDistance ); - - _cameraL.lookAt( scene.position ); - - _cameraL.rotation.x += 90 * ( Math.PI / 180 ); // 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 ); - - } else { - - renderer.render( scene, _cameraF ); - - } - - renderer.setScissor( _halfWidth - _width / 2, 0, _width, _height ); - renderer.setViewport( _halfWidth - _width / 2, 0, _width, _height ); - - if ( scope.reflectFromAbove ) { - - renderer.render( scene, _cameraF ); - - } else { - - renderer.render( scene, _cameraB ); - - } - - 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 ); - - } else { - - renderer.render( scene, _cameraL ); - - } - - renderer.setScissor( _halfWidth + _width / 2, _height, _width, _height ); - renderer.setViewport( _halfWidth + _width / 2, _height, _width, _height ); - - if ( scope.reflectFromAbove ) { - - renderer.render( scene, _cameraL ); - - } else { - - renderer.render( scene, _cameraR ); - - } - - renderer.setScissorTest( false ); - - }; - - } - - } - - THREE.PeppersGhostEffect = PeppersGhostEffect; - -} )(); diff --git a/examples/js/effects/StereoEffect.js b/examples/js/effects/StereoEffect.js deleted file mode 100644 index 8a7a0944affed9..00000000000000 --- a/examples/js/effects/StereoEffect.js +++ /dev/null @@ -1,50 +0,0 @@ -( function () { - - class StereoEffect { - - constructor( renderer ) { - - const _stereo = new THREE.StereoCamera(); - - _stereo.aspect = 0.5; - const size = new THREE.Vector2(); - - this.setEyeSeparation = function ( eyeSep ) { - - _stereo.eyeSep = eyeSep; - - }; - - this.setSize = function ( width, height ) { - - renderer.setSize( width, height ); - - }; - - this.render = function ( scene, camera ) { - - scene.updateMatrixWorld(); - if ( camera.parent === null ) camera.updateMatrixWorld(); - - _stereo.update( camera ); - - renderer.getSize( size ); - if ( renderer.autoClear ) renderer.clear(); - renderer.setScissorTest( true ); - renderer.setScissor( 0, 0, size.width / 2, size.height ); - renderer.setViewport( 0, 0, size.width / 2, size.height ); - renderer.render( scene, _stereo.cameraL ); - renderer.setScissor( size.width / 2, 0, size.width / 2, size.height ); - renderer.setViewport( size.width / 2, 0, size.width / 2, size.height ); - renderer.render( scene, _stereo.cameraR ); - renderer.setScissorTest( false ); - - }; - - } - - } - - THREE.StereoEffect = StereoEffect; - -} )(); diff --git a/examples/js/environments/DebugEnvironment.js b/examples/js/environments/DebugEnvironment.js deleted file mode 100644 index 5d30a317cfb2d2..00000000000000 --- a/examples/js/environments/DebugEnvironment.js +++ /dev/null @@ -1,53 +0,0 @@ -( function () { - - class DebugEnvironment extends THREE.Scene { - - constructor() { - - super(); - const geometry = new THREE.BoxGeometry(); - geometry.deleteAttribute( 'uv' ); - const roomMaterial = new THREE.MeshStandardMaterial( { - metalness: 0, - side: THREE.BackSide - } ); - const room = new THREE.Mesh( geometry, roomMaterial ); - room.scale.setScalar( 10 ); - this.add( room ); - const mainLight = new THREE.PointLight( 0xffffff, 50, 0, 2 ); - this.add( mainLight ); - const material1 = new THREE.MeshLambertMaterial( { - color: 0xff0000, - emissive: 0xffffff, - emissiveIntensity: 10 - } ); - const light1 = new THREE.Mesh( geometry, material1 ); - light1.position.set( - 5, 2, 0 ); - light1.scale.set( 0.1, 1, 1 ); - this.add( light1 ); - const material2 = new THREE.MeshLambertMaterial( { - color: 0x00ff00, - emissive: 0xffffff, - emissiveIntensity: 10 - } ); - const light2 = new THREE.Mesh( geometry, material2 ); - light2.position.set( 0, 5, 0 ); - light2.scale.set( 1, 0.1, 1 ); - this.add( light2 ); - const material3 = new THREE.MeshLambertMaterial( { - color: 0x0000ff, - emissive: 0xffffff, - emissiveIntensity: 10 - } ); - const light3 = new THREE.Mesh( geometry, material3 ); - light3.position.set( 2, 1, 5 ); - light3.scale.set( 1.5, 2, 0.1 ); - this.add( light3 ); - - } - - } - - THREE.DebugEnvironment = DebugEnvironment; - -} )(); diff --git a/examples/js/environments/RoomEnvironment.js b/examples/js/environments/RoomEnvironment.js deleted file mode 100644 index f698528f84338e..00000000000000 --- a/examples/js/environments/RoomEnvironment.js +++ /dev/null @@ -1,100 +0,0 @@ -( function () { - - /** - * https://github.com/google/model-viewer/blob/master/packages/model-viewer/src/three-components/EnvironmentScene.ts - */ - - class RoomEnvironment extends THREE.Scene { - - constructor() { - - super(); - const geometry = new THREE.BoxGeometry(); - geometry.deleteAttribute( 'uv' ); - const roomMaterial = new THREE.MeshStandardMaterial( { - side: THREE.BackSide - } ); - const boxMaterial = new THREE.MeshStandardMaterial(); - const mainLight = new THREE.PointLight( 0xffffff, 5.0, 28, 2 ); - mainLight.position.set( 0.418, 16.199, 0.300 ); - this.add( mainLight ); - const room = new THREE.Mesh( geometry, roomMaterial ); - room.position.set( - 0.757, 13.219, 0.717 ); - room.scale.set( 31.713, 28.305, 28.591 ); - this.add( room ); - const box1 = new THREE.Mesh( geometry, boxMaterial ); - box1.position.set( - 10.906, 2.009, 1.846 ); - box1.rotation.set( 0, - 0.195, 0 ); - box1.scale.set( 2.328, 7.905, 4.651 ); - this.add( box1 ); - const box2 = new THREE.Mesh( geometry, boxMaterial ); - box2.position.set( - 5.607, - 0.754, - 0.758 ); - box2.rotation.set( 0, 0.994, 0 ); - box2.scale.set( 1.970, 1.534, 3.955 ); - this.add( box2 ); - const box3 = new THREE.Mesh( geometry, boxMaterial ); - box3.position.set( 6.167, 0.857, 7.803 ); - box3.rotation.set( 0, 0.561, 0 ); - box3.scale.set( 3.927, 6.285, 3.687 ); - this.add( box3 ); - const box4 = new THREE.Mesh( geometry, boxMaterial ); - box4.position.set( - 2.017, 0.018, 6.124 ); - box4.rotation.set( 0, 0.333, 0 ); - box4.scale.set( 2.002, 4.566, 2.064 ); - this.add( box4 ); - const box5 = new THREE.Mesh( geometry, boxMaterial ); - box5.position.set( 2.291, - 0.756, - 2.621 ); - box5.rotation.set( 0, - 0.286, 0 ); - box5.scale.set( 1.546, 1.552, 1.496 ); - this.add( box5 ); - const box6 = new THREE.Mesh( geometry, boxMaterial ); - 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 - - 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 - - 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 - - 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 - - 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 - - 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 - - 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 ); - - } - - } - - function createAreaLightMaterial( intensity ) { - - const material = new THREE.MeshBasicMaterial(); - material.color.setScalar( intensity ); - return material; - - } - - THREE.RoomEnvironment = RoomEnvironment; - -} )(); diff --git a/examples/js/exporters/ColladaExporter.js b/examples/js/exporters/ColladaExporter.js deleted file mode 100644 index 6458e8ef07d866..00000000000000 --- a/examples/js/exporters/ColladaExporter.js +++ /dev/null @@ -1,513 +0,0 @@ -( function () { - - /** - * https://github.com/gkjohnson/collada-exporter-js - * - * Usage: - * const exporter = new ColladaExporter(); - * - * const data = exporter.parse(mesh); - * - * Format Definition: - * https://www.khronos.org/collada/ - */ - - class ColladaExporter { - - parse( object, onDone, options = {} ) { - - options = Object.assign( { - version: '1.4.1', - author: null, - textureDirectory: '', - upAxis: 'Y_UP', - 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.' ); - return null; - - } - - if ( options.unitName !== null && options.unitMeter === null ) { - - console.error( 'ColladaExporter: unitMeter needs to be specified if unitName is specified.' ); - return null; - - } - - if ( options.unitMeter !== null && options.unitName === null ) { - - console.error( 'ColladaExporter: unitName needs to be specified if unitMeter is specified.' ); - return null; - - } - - if ( options.textureDirectory !== '' ) { - - options.textureDirectory = `${options.textureDirectory}/`.replace( /\\/g, '/' ).replace( /\/+/g, '/' ); - - } - - 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 - - - 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 => { - - if ( ! HAS_TEXT.test( tag ) && ! IS_SELF_CLOSING.test( tag ) && IS_END_TAG.test( tag ) ) { - - tagnum --; - - } - - const res = `${pad( ' ', tagnum )}${tag}`; - - if ( ! HAS_TEXT.test( tag ) && ! IS_SELF_CLOSING.test( tag ) && ! IS_END_TAG.test( tag ) ) { - - tagnum ++; - - } - - return res; - - } ).join( '\n' ); - - } // 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 ); - - } - - return buf; - - } - - 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 - - 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 - - - const getFuncs = [ 'getX', 'getY', 'getZ', 'getW' ]; - const tempColor = new THREE.Color(); - - function attrBufferToArray( attr, isColor = false ) { - - if ( isColor ) { - - // 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(); - arr[ 3 * i + 0 ] = tempColor.r; - arr[ 3 * i + 1 ] = tempColor.g; - arr[ 3 * i + 2 ] = tempColor.b; - - } - - return arr; - - } else if ( attr.isInterleavedBufferAttribute ) { - - // 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 ++ ) { - - arr[ i * size + j ] = attr[ getFuncs[ j ] ]( i ); - - } - - } - - return arr; - - } else { - - return attr.array; - - } - - } // 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 - - - 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 - - - let transMat; - - function getTransform( o ) { - - // ensure the object's matrix is up to date - // before saving the transform - o.updateMatrix(); - transMat = transMat || new THREE.Matrix4(); - transMat.copy( o.matrix ); - 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 ); - - 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 : [ { - start: 0, - count: indexCount, - materialIndex: 0 - } ]; - const gname = g.name ? ` name="${g.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 - // 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 - - let triangleInputs = ``; - - if ( 'normal' in bufferGeometry.attributes ) { - - const normName = `${meshid}-normal`; - gnode += getAttribute( bufferGeometry.attributes.normal, normName, [ 'X', 'Y', 'Z' ], 'float' ); - triangleInputs += ``; - - } // serialize uvs - - - if ( 'uv' in bufferGeometry.attributes ) { - - const uvName = `${meshid}-texcoord`; - gnode += getAttribute( bufferGeometry.attributes.uv, uvName, [ 'S', 'T' ], 'float' ); - triangleInputs += ``; - - } // serialize lightmap uvs - - - if ( 'uv2' in bufferGeometry.attributes ) { - - const uvName = `${meshid}-texcoord2`; - gnode += getAttribute( bufferGeometry.attributes.uv2, uvName, [ 'S', 'T' ], 'float' ); - triangleInputs += ``; - - } // serialize colors - - - if ( 'color' in bufferGeometry.attributes ) { - - // colors are always written as floats - const colName = `${meshid}-color`; - gnode += getAttribute( bufferGeometry.attributes.color, colName, [ 'R', 'G', 'B' ], 'float', true ); - triangleInputs += ``; - - } - - let indexArray = null; - - if ( bufferGeometry.index ) { - - indexArray = attrBufferToArray( bufferGeometry.index ); - - } else { - - indexArray = new Array( indexCount ); - - for ( let i = 0, l = indexArray.length; i < l; i ++ ) indexArray[ i ] = i; - - } - - for ( let i = 0, l = groups.length; i < l; i ++ ) { - - const group = groups[ i ]; - const subarr = subArray( indexArray, group.start, group.count ); - const polycount = subarr.length / 3; - gnode += ``; - gnode += triangleInputs; - gnode += `

          ${subarr.join( ' ' )}

          `; - gnode += '
          '; - - } - - gnode += '
          '; - libraryGeometries.push( gnode ); - info = { - meshid: meshid, - bufferGeometry: bufferGeometry - }; - geometryInfo.set( g, info ); - - } - - return info; - - } // 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}`; - - } else { - - // version image node 1.4.1 - imageNode += `${options.textureDirectory}${name}.${ext}`; - - } - - imageNode += ''; - libraryImages.push( imageNode ); - imageMap.set( tex, texid ); - textures.push( { - directory: options.textureDirectory, - name, - ext, - data: imageToData( tex.image, ext ), - original: tex - } ); - - } - - return texid; - - } // 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'; - - } else if ( m.isMeshBasicMaterial === true ) { - - type = 'constant'; - - if ( m.map !== null ) { - - // The Collada spec does not support diffuse texture maps with the - // constant shader type. - // mrdoob/three.js#15469 - console.warn( 'ColladaExporter: Texture maps not supported with THREE.MeshBasicMaterial.' ); - - } - - } - - const emissive = m.emissive ? m.emissive : new THREE.Color( 0, 0, 0 ); - const diffuse = m.color ? m.color : new THREE.Color( 0, 0, 0 ); - const specular = m.specular ? m.specular : new THREE.Color( 1, 1, 1 ); - const shininess = m.shininess || 0; - const reflectivity = m.reflectivity || 0; - emissive.convertLinearToSRGB(); - specular.convertLinearToSRGB(); - 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}`; - - } - - } - - const techniqueNode = `<${type}>` + '' + ( m.emissiveMap ? '' : `${emissive.r} ${emissive.g} ${emissive.b} 1` ) + '' + ( type !== 'constant' ? '' + ( m.map ? '' : `${diffuse.r} ${diffuse.g} ${diffuse.b} 1` ) + '' : '' ) + ( type !== 'constant' ? '' + ( m.normalMap ? '' : '' ) + '' : '' ) + ( type === 'phong' ? `${specular.r} ${specular.g} ${specular.b} 1` + '' + ( m.specularMap ? '' : `${shininess}` ) + '' : '' ) + `${diffuse.r} ${diffuse.g} ${diffuse.b} 1` + `${reflectivity}` + transparencyNode + ``; - const effectnode = `` + '' + ( m.map ? '' + `${processTexture( m.map )}` + '' + 'diffuse-surface' : '' ) + ( m.specularMap ? '' + `${processTexture( m.specularMap )}` + '' + 'specular-surface' : '' ) + ( m.emissiveMap ? '' + `${processTexture( m.emissiveMap )}` + '' + 'emissive-surface' : '' ) + ( m.normalMap ? '' + `${processTexture( m.normalMap )}` + '' + 'bump-surface' : '' ) + techniqueNode + ( m.side === THREE.DoubleSide ? '1' : '' ) + '' + ''; - const materialName = m.name ? ` name="${m.name}"` : ''; - const materialNode = ``; - libraryMaterials.push( materialNode ); - libraryEffects.push( effectnode ); - materialMap.set( m, matid ); - - } - - return matid; - - } // 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 - - let matids = null; - 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 ); - - } else { - - matidsArray = new Array( materials.length ); - - } - - matids = matidsArray.fill().map( ( v, i ) => processMaterial( materials[ i % materials.length ] ) ); - node += `` + ( matids.length > 0 ? '' + matids.map( ( id, i ) => `` + '' + '' ).join( '' ) + '' : '' ) + ''; - - } - - o.children.forEach( c => node += processObject( c ) ); - node += ''; - return node; - - } - - const geometryInfo = new WeakMap(); - const materialMap = new WeakMap(); - const imageMap = new WeakMap(); - const textures = []; - const libraryImages = []; - const libraryGeometries = []; - const libraryEffects = []; - const libraryMaterials = []; - const libraryVisualScenes = processObject( object ); - const specLink = version === '1.4.1' ? 'http://www.collada.org/2005/11/COLLADASchema' : 'https://www.khronos.org/collada/'; - let dae = '' + `` + '' + ( '' + 'three.js Collada Exporter' + ( options.author !== null ? `${options.author}` : '' ) + '' + `${new Date().toISOString()}` + `${new Date().toISOString()}` + ( options.unitName !== null ? `` : '' ) + `${options.upAxis}` ) + ''; - dae += `${libraryImages.join( '' )}`; - dae += `${libraryEffects.join( '' )}`; - dae += `${libraryMaterials.join( '' )}`; - dae += `${libraryGeometries.join( '' )}`; - dae += `${libraryVisualScenes}`; - dae += ''; - dae += ''; - const res = { - data: format( dae ), - textures - }; - - if ( typeof onDone === 'function' ) { - - requestAnimationFrame( () => onDone( res ) ); - - } - - return res; - - } - - } - - THREE.ColladaExporter = ColladaExporter; - -} )(); diff --git a/examples/js/exporters/DRACOExporter.js b/examples/js/exporters/DRACOExporter.js deleted file mode 100644 index 3f71a8bbb8fef1..00000000000000 --- a/examples/js/exporters/DRACOExporter.js +++ /dev/null @@ -1,224 +0,0 @@ -( function () { - - /** - * Export draco compressed files from threejs geometry objects. - * - * Draco files are compressed and usually are smaller than conventional 3D file formats. - * - * The exporter receives a options object containing - * - decodeSpeed, indicates how to tune the encoder regarding decode speed (0 gives better speed but worst quality) - * - encodeSpeed, indicates how to tune the encoder parameters (0 gives better speed but worst quality) - * - encoderMethod - * - quantization, indicates the presision of each type of data stored in the draco file in the order (POSITION, NORMAL, COLOR, TEX_COORD, GENERIC) - * - exportUvs - * - exportNormals - */ - - /* global DracoEncoderModule */ - class DRACOExporter { - - parse( object, options = { - decodeSpeed: 5, - encodeSpeed: 5, - encoderMethod: DRACOExporter.MESH_EDGEBREAKER_ENCODING, - quantization: [ 16, 8, 8, 8, 8 ], - exportUvs: true, - exportNormals: true, - 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.' ); - - } - - const geometry = object.geometry; - const dracoEncoder = DracoEncoderModule(); - 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(); - dracoObject = new dracoEncoder.Mesh(); - 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 ); - - } else { - - const faces = new ( vertices.count > 65535 ? Uint32Array : Uint16Array )( vertices.count ); - - for ( let i = 0; i < faces.length; i ++ ) { - - faces[ i ] = i; - - } - - builder.AddFacesToMesh( dracoObject, vertices.count, faces ); - - } - - if ( options.exportNormals === true ) { - - const normals = geometry.getAttribute( 'normal' ); - - if ( normals !== undefined ) { - - builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.NORMAL, normals.count, normals.itemSize, normals.array ); - - } - - } - - if ( options.exportUvs === true ) { - - const uvs = geometry.getAttribute( 'uv' ); - - if ( uvs !== undefined ) { - - builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.TEX_COORD, uvs.count, uvs.itemSize, uvs.array ); - - } - - } - - if ( options.exportColor === true ) { - - const colors = geometry.getAttribute( 'color' ); - - if ( colors !== undefined ) { - - builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array ); - - } - - } - - } else if ( object.isPoints === true ) { - - builder = new dracoEncoder.PointCloudBuilder(); - 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 ); - - } - - } - - } else { - - throw new Error( 'DRACOExporter: Unsupported object type.' ); - - } //Compress using draco encoder - - - 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). - - 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. - - 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. - - - if ( options.quantization !== undefined ) { - - for ( let i = 0; i < 5; i ++ ) { - - if ( options.quantization[ i ] !== undefined ) { - - encoder.SetAttributeQuantization( i, options.quantization[ i ] ); - - } - - } - - } - - let length; - - if ( object.isMesh === true ) { - - length = encoder.EncodeMeshToDracoBuffer( dracoObject, encodedData ); - - } else { - - length = encoder.EncodePointCloudToDracoBuffer( dracoObject, true, encodedData ); - - } - - dracoEncoder.destroy( dracoObject ); - - if ( length === 0 ) { - - throw new Error( 'THREE.DRACOExporter: Draco encoding failed.' ); - - } //Copy encoded data to buffer. - - - const outputData = new Int8Array( new ArrayBuffer( length ) ); - - for ( let i = 0; i < length; i ++ ) { - - outputData[ i ] = encodedData.GetValue( i ); - - } - - dracoEncoder.destroy( encodedData ); - dracoEncoder.destroy( encoder ); - dracoEncoder.destroy( builder ); - return outputData; - - } - - } // Encoder methods - - - DRACOExporter.MESH_EDGEBREAKER_ENCODING = 1; - DRACOExporter.MESH_SEQUENTIAL_ENCODING = 0; // Geometry type - - DRACOExporter.POINT_CLOUD = 0; - DRACOExporter.TRIANGULAR_MESH = 1; // Attribute type - - DRACOExporter.INVALID = - 1; - DRACOExporter.POSITION = 0; - DRACOExporter.NORMAL = 1; - DRACOExporter.COLOR = 2; - DRACOExporter.TEX_COORD = 3; - DRACOExporter.GENERIC = 4; - - THREE.DRACOExporter = DRACOExporter; - -} )(); diff --git a/examples/js/exporters/EXRExporter.js b/examples/js/exporters/EXRExporter.js deleted file mode 100644 index d2153ea33f9a5c..00000000000000 --- a/examples/js/exporters/EXRExporter.js +++ /dev/null @@ -1,458 +0,0 @@ -( function () { - - /** - * @author sciecode / https://github.com/sciecode - * - * EXR format references: - * https://www.openexr.com/documentation/openexrfilelayout.pdf - */ - const textEncoder = new TextEncoder(); - const NO_COMPRESSION = 0; - const ZIPS_COMPRESSION = 2; - const ZIP_COMPRESSION = 3; - - class EXRExporter { - - parse( renderer, renderTarget, options ) { - - if ( ! supported( renderer, renderTarget ) ) return undefined; - const info = buildInfo( renderTarget, options ), - dataBuffer = getPixelData( renderer, renderTarget, info ), - rawContentBuffer = reorganizeDataBuffer( dataBuffer, info ), - chunks = compressData( rawContentBuffer, info ); - return fillData( chunks, info ); - - } - - } - - function supported( renderer, renderTarget ) { - - if ( ! renderer || ! renderer.isWebGLRenderer ) { - - console.error( 'EXRExporter.parse: Unsupported first parameter, expected instance of WebGLRenderer.' ); - return false; - - } - - if ( ! renderTarget || ! renderTarget.isWebGLRenderTarget ) { - - console.error( 'EXRExporter.parse: Unsupported second parameter, expected instance of WebGLRenderTarget.' ); - return false; - - } - - if ( renderTarget.texture.type !== THREE.FloatType && renderTarget.texture.type !== THREE.HalfFloatType ) { - - console.error( 'EXRExporter.parse: Unsupported WebGLRenderTarget texture type.' ); - return false; - - } - - if ( renderTarget.texture.format !== THREE.RGBAFormat ) { - - console.error( 'EXRExporter.parse: Unsupported WebGLRenderTarget texture format, expected THREE.RGBAFormat.' ); - return false; - - } - - return true; - - } - - function buildInfo( renderTarget, options = {} ) { - - const compressionSizes = { - 0: 1, - 2: 1, - 3: 16 - }; - const WIDTH = renderTarget.width, - HEIGHT = renderTarget.height, - TYPE = renderTarget.texture.type, - FORMAT = renderTarget.texture.format, - ENCODING = renderTarget.texture.encoding, - COMPRESSION = options.compression !== undefined ? options.compression : ZIP_COMPRESSION, - EXPORTER_TYPE = options.type !== undefined ? options.type : THREE.HalfFloatType, - OUT_TYPE = EXPORTER_TYPE === THREE.FloatType ? 2 : 1, - COMPRESSION_SIZE = compressionSizes[ COMPRESSION ], - NUM_CHANNELS = 4; - return { - width: WIDTH, - height: HEIGHT, - type: TYPE, - format: FORMAT, - encoding: ENCODING, - compression: COMPRESSION, - blockLines: COMPRESSION_SIZE, - dataType: OUT_TYPE, - dataSize: 2 * OUT_TYPE, - numBlocks: Math.ceil( HEIGHT / COMPRESSION_SIZE ), - numInputChannels: 4, - numOutputChannels: NUM_CHANNELS - }; - - } - - function getPixelData( renderer, rtt, info ) { - - let dataBuffer; - - if ( info.type === THREE.FloatType ) { - - dataBuffer = new Float32Array( info.width * info.height * info.numInputChannels ); - - } else { - - dataBuffer = new Uint16Array( info.width * info.height * info.numInputChannels ); - - } - - renderer.readRenderTargetPixels( rtt, 0, 0, info.width, info.height, dataBuffer ); - return dataBuffer; - - } - - function reorganizeDataBuffer( inBuffer, info ) { - - const w = info.width, - h = info.height, - dec = { - r: 0, - g: 0, - b: 0, - a: 0 - }, - offset = { - value: 0 - }, - cOffset = info.numOutputChannels == 4 ? 1 : 0, - getValue = info.type == THREE.FloatType ? getFloat32 : getFloat16, - 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 ) { - - const i = y * w * 4 + x * 4; - const r = getValue( inBuffer, i ); - const g = getValue( inBuffer, i + 1 ); - const b = getValue( inBuffer, i + 2 ); - const a = getValue( inBuffer, i + 3 ); - const line = ( h - y - 1 ) * w * ( 3 + cOffset ) * info.dataSize; - decodeLinear( dec, r, g, b, a ); - offset.value = line + x * info.dataSize; - setValue( dv, dec.a, offset ); - offset.value = line + cOffset * w * info.dataSize + x * info.dataSize; - setValue( dv, dec.b, offset ); - offset.value = line + ( 1 + cOffset ) * w * info.dataSize + x * info.dataSize; - setValue( dv, dec.g, offset ); - offset.value = line + ( 2 + cOffset ) * w * info.dataSize + x * info.dataSize; - setValue( dv, dec.r, offset ); - - } - - } - - return outBuffer; - - } - - function compressData( inBuffer, info ) { - - let compress, - tmpBuffer, - sum = 0; - const chunks = { - data: new Array(), - 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; - break; - - } - - if ( info.compression !== 0 ) { - - tmpBuffer = new Uint8Array( size ); - - } - - for ( let i = 0; i < info.numBlocks; ++ i ) { - - const arr = inBuffer.subarray( size * i, size * ( i + 1 ) ); - const block = compress( arr, tmpBuffer ); - sum += block.length; - chunks.data.push( { - dataChunk: block, - size: block.length - } ); - - } - - chunks.totalSize = sum; - return chunks; - - } - - function compressNONE( data ) { - - return data; - - } - - function compressZIP( data, tmpBuffer ) { - - // - // 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; - tmpBuffer[ t1 ++ ] = data[ s ++ ]; - 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 ); - p = tmpBuffer[ t ]; - tmpBuffer[ t ] = d; - - } - - if ( typeof fflate === 'undefined' ) { - - console.error( 'THREE.EXRLoader: External \`fflate.module.js\` required' ); - - } - - const deflate = fflate.zlibSync( tmpBuffer ); // eslint-disable-line no-undef - - return deflate; - - } - - function fillHeader( outBuffer, chunks, info ) { - - const offset = { - value: 0 - }; - const dv = new DataView( outBuffer.buffer ); - setUint32( dv, 20000630, offset ); // magic - - setUint32( dv, 2, offset ); // mask - // = HEADER = - - setString( dv, 'compression', offset ); - setString( dv, 'compression', offset ); - setUint32( dv, 1, offset ); - setUint8( dv, info.compression, offset ); - setString( dv, 'screenWindowCenter', offset ); - setString( dv, 'v2f', offset ); - setUint32( dv, 8, offset ); - setUint32( dv, 0, offset ); - setUint32( dv, 0, offset ); - setString( dv, 'screenWindowWidth', offset ); - setString( dv, 'float', offset ); - setUint32( dv, 4, offset ); - setFloat32( dv, 1.0, offset ); - setString( dv, 'pixelAspectRatio', offset ); - setString( dv, 'float', offset ); - setUint32( dv, 4, offset ); - setFloat32( dv, 1.0, offset ); - setString( dv, 'lineOrder', offset ); - setString( dv, 'lineOrder', offset ); - setUint32( dv, 1, offset ); - setUint8( dv, 0, offset ); - setString( dv, 'dataWindow', offset ); - setString( dv, 'box2i', offset ); - setUint32( dv, 16, offset ); - setUint32( dv, 0, offset ); - setUint32( dv, 0, offset ); - setUint32( dv, info.width - 1, offset ); - setUint32( dv, info.height - 1, offset ); - setString( dv, 'displayWindow', offset ); - setString( dv, 'box2i', offset ); - setUint32( dv, 16, offset ); - setUint32( dv, 0, offset ); - setUint32( dv, 0, offset ); - setUint32( dv, info.width - 1, offset ); - setUint32( dv, info.height - 1, offset ); - setString( dv, 'channels', offset ); - setString( dv, 'chlist', offset ); - setUint32( dv, info.numOutputChannels * 18 + 1, offset ); - setString( dv, 'A', offset ); - setUint32( dv, info.dataType, offset ); - offset.value += 4; - setUint32( dv, 1, offset ); - setUint32( dv, 1, offset ); - setString( dv, 'B', offset ); - setUint32( dv, info.dataType, offset ); - offset.value += 4; - setUint32( dv, 1, offset ); - setUint32( dv, 1, offset ); - setString( dv, 'G', offset ); - setUint32( dv, info.dataType, offset ); - offset.value += 4; - setUint32( dv, 1, offset ); - setUint32( dv, 1, offset ); - setString( dv, 'R', offset ); - setUint32( dv, info.dataType, offset ); - offset.value += 4; - setUint32( dv, 1, offset ); - setUint32( dv, 1, offset ); - setUint8( dv, 0, offset ); // null-byte - - setUint8( dv, 0, offset ); // = OFFSET TABLE = - - let sum = offset.value + info.numBlocks * 8; - - for ( let i = 0; i < chunks.data.length; ++ i ) { - - setUint64( dv, sum, offset ); - sum += chunks.data[ i ].size + 8; - - } - - } - - function fillData( chunks, info ) { - - const TableSize = info.numBlocks * 8, - HeaderSize = 259 + 18 * info.numOutputChannels, - // 259 + 18 * chlist - offset = { - value: HeaderSize + TableSize - }, - 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; - const size = chunks.data[ i ].size; - setUint32( dv, i * info.blockLines, offset ); - setUint32( dv, size, offset ); - outBuffer.set( data, offset.value ); - offset.value += size; - - } - - return outBuffer; - - } - - function decodeLinear( dec, r, g, b, a ) { - - dec.r = r; - dec.g = g; - dec.b = b; - dec.a = 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 ) { - - dv.setUint8( offset.value, value ); - offset.value += 1; - - } - - function setUint32( dv, value, offset ) { - - dv.setUint32( offset.value, value, true ); - offset.value += 4; - - } - - function setFloat16( dv, value, offset ) { - - dv.setUint16( offset.value, THREE.DataUtils.toHalfFloat( value ), true ); - offset.value += 2; - - } - - function setFloat32( dv, value, offset ) { - - dv.setFloat32( offset.value, value, true ); - offset.value += 4; - - } - - function setUint64( dv, value, offset ) { - - dv.setBigUint64( offset.value, BigInt( value ), true ); - offset.value += 8; - - } - - function setString( dv, string, offset ) { - - const tmp = textEncoder.encode( string + '\0' ); - - for ( let i = 0; i < tmp.length; ++ i ) { - - setUint8( dv, tmp[ i ], offset ); - - } - - } - - function decodeFloat16( binary ) { - - const exponent = ( binary & 0x7C00 ) >> 10, - fraction = binary & 0x03FF; - return ( binary >> 15 ? - 1 : 1 ) * ( exponent ? exponent === 0x1F ? fraction ? NaN : Infinity : Math.pow( 2, exponent - 15 ) * ( 1 + fraction / 0x400 ) : 6.103515625e-5 * ( fraction / 0x400 ) ); - - } - - function getFloat16( arr, i ) { - - return decodeFloat16( arr[ i ] ); - - } - - function getFloat32( arr, i ) { - - return arr[ i ]; - - } - - THREE.EXRExporter = EXRExporter; - THREE.NO_COMPRESSION = NO_COMPRESSION; - THREE.ZIPS_COMPRESSION = ZIPS_COMPRESSION; - THREE.ZIP_COMPRESSION = ZIP_COMPRESSION; - -} )(); diff --git a/examples/js/exporters/GLTFExporter.js b/examples/js/exporters/GLTFExporter.js deleted file mode 100644 index 4f4190d89d263c..00000000000000 --- a/examples/js/exporters/GLTFExporter.js +++ /dev/null @@ -1,2544 +0,0 @@ -( function () { - - class GLTFExporter { - - constructor() { - - this.pluginCallbacks = []; - this.register( function ( writer ) { - - return new GLTFLightExtension( writer ); - - } ); - this.register( function ( writer ) { - - return new GLTFMaterialsUnlitExtension( writer ); - - } ); - this.register( function ( writer ) { - - return new GLTFMaterialsPBRSpecularGlossiness( writer ); - - } ); - this.register( function ( writer ) { - - return new GLTFMaterialsTransmissionExtension( writer ); - - } ); - this.register( function ( writer ) { - - return new GLTFMaterialsVolumeExtension( writer ); - - } ); - this.register( function ( writer ) { - - return new GLTFMaterialsClearcoatExtension( writer ); - - } ); - this.register( function ( writer ) { - - return new GLTFMaterialsIridescenceExtension( writer ); - - } ); - - } - - register( callback ) { - - if ( this.pluginCallbacks.indexOf( callback ) === - 1 ) { - - this.pluginCallbacks.push( callback ); - - } - - return this; - - } - - unregister( callback ) { - - if ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) { - - this.pluginCallbacks.splice( this.pluginCallbacks.indexOf( callback ), 1 ); - - } - - return this; - - } - /** - * 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 {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 ) ); - - } - - writer.setPlugins( plugins ); - writer.write( input, onDone, options ).catch( onError ); - - } - - parseAsync( input, options ) { - - const scope = this; - return new Promise( function ( resolve, reject ) { - - scope.parse( input, resolve, reject, options ); - - } ); - - } - - } //------------------------------------------------------------------------------ - // Constants - //------------------------------------------------------------------------------ - - - const WEBGL_CONSTANTS = { - POINTS: 0x0000, - LINES: 0x0001, - LINE_LOOP: 0x0002, - LINE_STRIP: 0x0003, - TRIANGLES: 0x0004, - TRIANGLE_STRIP: 0x0005, - TRIANGLE_FAN: 0x0006, - UNSIGNED_BYTE: 0x1401, - UNSIGNED_SHORT: 0x1403, - FLOAT: 0x1406, - UNSIGNED_INT: 0x1405, - ARRAY_BUFFER: 0x8892, - ELEMENT_ARRAY_BUFFER: 0x8893, - NEAREST: 0x2600, - LINEAR: 0x2601, - NEAREST_MIPMAP_NEAREST: 0x2700, - LINEAR_MIPMAP_NEAREST: 0x2701, - NEAREST_MIPMAP_LINEAR: 0x2702, - LINEAR_MIPMAP_LINEAR: 0x2703, - CLAMP_TO_EDGE: 33071, - MIRRORED_REPEAT: 33648, - REPEAT: 10497 - }; - const THREE_TO_WEBGL = {}; - THREE_TO_WEBGL[ THREE.NearestFilter ] = WEBGL_CONSTANTS.NEAREST; - THREE_TO_WEBGL[ THREE.NearestMipmapNearestFilter ] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST; - THREE_TO_WEBGL[ THREE.NearestMipmapLinearFilter ] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR; - THREE_TO_WEBGL[ THREE.LinearFilter ] = WEBGL_CONSTANTS.LINEAR; - THREE_TO_WEBGL[ THREE.LinearMipmapNearestFilter ] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST; - THREE_TO_WEBGL[ THREE.LinearMipmapLinearFilter ] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR; - THREE_TO_WEBGL[ THREE.ClampToEdgeWrapping ] = WEBGL_CONSTANTS.CLAMP_TO_EDGE; - THREE_TO_WEBGL[ THREE.RepeatWrapping ] = WEBGL_CONSTANTS.REPEAT; - THREE_TO_WEBGL[ THREE.MirroredRepeatWrapping ] = WEBGL_CONSTANTS.MIRRORED_REPEAT; - const PATH_PROPERTIES = { - scale: 'scale', - position: 'translation', - quaternion: 'rotation', - morphTargetInfluences: 'weights' - }; // GLB constants - // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification - - const GLB_HEADER_BYTES = 12; - const GLB_HEADER_MAGIC = 0x46546C67; - const GLB_VERSION = 2; - const GLB_CHUNK_PREFIX_BYTES = 8; - const GLB_CHUNK_TYPE_JSON = 0x4E4F534A; - const GLB_CHUNK_TYPE_BIN = 0x004E4942; //------------------------------------------------------------------------------ - // Utility functions - //------------------------------------------------------------------------------ - - /** - * Compare two arrays - * @param {Array} array1 Array 1 to compare - * @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 ) { - - return element === array2[ index ]; - - } ); - - } - /** - * 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 - * @param {Integer} start - * @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 { - - if ( a === 0 ) value = attribute.getX( i ); else if ( a === 1 ) value = attribute.getY( i ); else if ( a === 2 ) value = attribute.getZ( i ); else if ( a === 3 ) value = attribute.getW( i ); - - } - - output.min[ a ] = Math.min( output.min[ a ], value ); - output.max[ a ] = Math.max( output.max[ a ], value ); - - } - - } - - 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 - * - * @param {Integer} bufferSize The size the original buffer. - * @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. - * - * @param {ArrayBuffer} arrayBuffer Buffer to pad - * @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 ++ ) { - - array[ i ] = paddingByte; - - } - - } - - return array.buffer; - - } - - return arrayBuffer; - - } - - let cachedCanvas = null; - - function getCanvas() { - - if ( cachedCanvas ) { - - return cachedCanvas; - - } - - if ( typeof document === 'undefined' && typeof OffscreenCanvas !== 'undefined' ) { - - cachedCanvas = new OffscreenCanvas( 1, 1 ); - - } else { - - cachedCanvas = document.createElement( 'canvas' ); - - } - - return cachedCanvas; - - } - - function getToBlobPromise( canvas, mimeType ) { - - if ( canvas.toBlob !== undefined ) { - - return new Promise( resolve => canvas.toBlob( resolve, mimeType ) ); - - } - - 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; - - } else if ( mimeType === 'image/webp' ) { - - quality = 0.8; - - } - - return canvas.convertToBlob( { - type: mimeType, - quality: quality - } ); - - } - /** - * Writer - */ - - - class GLTFWriter { - - constructor() { - - this.plugins = []; - this.options = {}; - this.pending = []; - this.buffers = []; - this.byteOffset = 0; - this.buffers = []; - this.nodeMap = new Map(); - this.skins = []; - this.extensionsUsed = {}; - this.uids = new Map(); - this.uid = 0; - this.json = { - asset: { - version: '2.0', - generator: 'THREE.GLTFExporter' - } - }; - this.cache = { - meshes: new Map(), - attributes: new Map(), - attributesNormalized: new Map(), - materials: new Map(), - textures: new Map(), - images: new Map() - }; - - } - - 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( {}, { - // default options - 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. - this.options.trs = true; - - } - - this.processInput( input ); - await Promise.all( this.pending ); - const writer = this; - const buffers = writer.buffers; - const json = writer.json; - options = writer.options; - const extensionsUsed = writer.extensionsUsed; // Merge buffers. - - const blob = new Blob( buffers, { - type: 'application/octet-stream' - } ); // Declare extensions. - - const extensionsUsedList = Object.keys( extensionsUsed ); - 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. - - 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. - - const header = new ArrayBuffer( GLB_HEADER_BYTES ); - const headerView = new DataView( header ); - headerView.setUint32( 0, GLB_HEADER_MAGIC, true ); - headerView.setUint32( 4, GLB_VERSION, true ); - const totalByteLength = GLB_HEADER_BYTES + jsonChunkPrefix.byteLength + jsonChunk.byteLength + binaryChunkPrefix.byteLength + binaryChunk.byteLength; - headerView.setUint32( 8, totalByteLength, true ); - const glbBlob = new Blob( [ header, jsonChunkPrefix, jsonChunk, binaryChunkPrefix, binaryChunk ], { - type: 'application/octet-stream' - } ); - const glbReader = new FileReader(); - glbReader.readAsArrayBuffer( glbBlob ); - - glbReader.onloadend = function () { - - onDone( glbReader.result ); - - }; - - }; - - } else { - - if ( json.buffers && json.buffers.length > 0 ) { - - const reader = new FileReader(); - reader.readAsDataURL( blob ); - - reader.onloadend = function () { - - const base64data = reader.result; - json.buffers[ 0 ].uri = base64data; - onDone( json ); - - }; - - } else { - - onDone( json ); - - } - - } - - } - /** - * 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 ]; - extensionsUsed[ extensionName ] = true; - - } - - delete json.gltfExtensions; - - } - - if ( Object.keys( json ).length > 0 ) objectDef.extras = json; - - } catch ( error ) { - - console.warn( 'THREE.GLTFExporter: userData of \'' + object.name + '\' ' + 'won\'t be serialized because of JSON.stringify error - ' + error.message ); - - } - - } - /** - * Returns ids for buffer attributes. - * @param {Object} object - * @return {Integer} - */ - - - getUID( attribute, isRelativeCopy = false ) { - - if ( this.uids.has( attribute ) === false ) { - - const uids = new Map(); - uids.set( true, this.uid ++ ); - uids.set( false, this.uid ++ ); - this.uids.set( attribute, uids ); - - } - - const uids = this.uids.get( attribute ); - 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 - if ( Math.abs( v.fromBufferAttribute( normal, i ).length() - 1.0 ) > 0.0005 ) return false; - - } - - return true; - - } - /** - * Creates normalized normal buffer attribute. - * - * @param {BufferAttribute} normal - * @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) - v.setX( 1.0 ); - - } else { - - v.normalize(); - - } - - attribute.setXYZ( i, v.x, v.y, v.z ); - - } - - cache.attributesNormalized.set( normal, attribute ); - return attribute; - - } - /** - * Applies a texture transform, if present, to the map definition. Requires - * the KHR_texture_transform extension. - * - * @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(); - didTransform = true; - - } - - if ( texture.rotation !== 0 ) { - - transformDef.rotation = texture.rotation; - didTransform = true; - - } - - if ( texture.repeat.x !== 1 || texture.repeat.y !== 1 ) { - - transformDef.scale = texture.repeat.toArray(); - didTransform = true; - - } - - if ( didTransform ) { - - mapDef.extensions = mapDef.extensions || {}; - mapDef.extensions[ 'KHR_texture_transform' ] = transformDef; - this.extensionsUsed[ 'KHR_texture_transform' ] = true; - - } - - } - - buildMetalRoughTexture( metalnessMap, roughnessMap ) { - - if ( metalnessMap === roughnessMap ) return metalnessMap; - console.warn( 'THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.' ); - const metalness = metalnessMap?.image; - const roughness = roughnessMap?.image; - const width = Math.max( metalness?.width || 0, roughness?.width || 0 ); - const height = Math.max( metalness?.height || 0, roughness?.height || 0 ); - const canvas = getCanvas(); - canvas.width = width; - canvas.height = height; - const context = canvas.getContext( '2d' ); - 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 data = context.getImageData( 0, 0, width, height ).data; - - for ( let i = 2; i < data.length; i += 4 ) { - - composite.data[ i ] = data[ i ]; - - } - - } - - if ( roughness ) { - - context.drawImage( roughness, 0, 0, width, height ); - const data = context.getImageData( 0, 0, width, height ).data; - - for ( let i = 1; i < data.length; i += 4 ) { - - composite.data[ i ] = data[ i ]; - - } - - } - - context.putImageData( composite, 0, 0 ); // - - const reference = metalnessMap || roughnessMap; - const texture = reference.clone(); - texture.source = new THREE.Source( canvas ); - 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. - - buffers.push( buffer ); - return 0; - - } - /** - * Process and generate a BufferView - * @param {BufferAttribute} attribute - * @param {number} componentType - * @param {number} start - * @param {number} count - * @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 - - let componentSize; - - if ( componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE ) { - - componentSize = 1; - - } else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ) { - - componentSize = 2; - - } else { - - componentSize = 4; - - } - - 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 { - - if ( a === 0 ) value = attribute.getX( i ); else if ( a === 1 ) value = attribute.getY( i ); else if ( a === 2 ) value = attribute.getZ( i ); else if ( a === 3 ) value = attribute.getW( i ); - - } - - if ( componentType === WEBGL_CONSTANTS.FLOAT ) { - - dataView.setFloat32( offset, value, true ); - - } else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_INT ) { - - dataView.setUint32( offset, value, true ); - - } else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ) { - - dataView.setUint16( offset, value, true ); - - } else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE ) { - - dataView.setUint8( offset, value ); - - } - - offset += componentSize; - - } - - } - - const bufferViewDef = { - buffer: this.processBuffer( dataView.buffer ), - byteOffset: this.byteOffset, - byteLength: byteLength - }; - if ( target !== undefined ) bufferViewDef.target = target; - - if ( target === WEBGL_CONSTANTS.ARRAY_BUFFER ) { - - // Only define byteStride for vertex attributes. - bufferViewDef.byteStride = attribute.itemSize * componentSize; - - } - - this.byteOffset += byteLength; - json.bufferViews.push( bufferViewDef ); // @TODO Merge bufferViews where possible. - - const output = { - id: json.bufferViews.length - 1, - byteLength: 0 - }; - return output; - - } - /** - * Process and generate a BufferView from an image Blob. - * @param {Blob} blob - * @return {Promise} - */ - - - processBufferViewImage( blob ) { - - const writer = this; - const json = writer.json; - if ( ! json.bufferViews ) json.bufferViews = []; - return new Promise( function ( resolve ) { - - const reader = new FileReader(); - reader.readAsArrayBuffer( blob ); - - reader.onloadend = function () { - - const buffer = getPaddedArrayBuffer( reader.result ); - const bufferViewDef = { - buffer: writer.processBuffer( buffer ), - byteOffset: writer.byteOffset, - byteLength: buffer.byteLength - }; - writer.byteOffset += buffer.byteLength; - resolve( json.bufferViews.push( bufferViewDef ) - 1 ); - - }; - - } ); - - } - /** - * Process attribute to generate an accessor - * @param {BufferAttribute} attribute Attribute to process - * @param {THREE.BufferGeometry} geometry (Optional) Geometry used for truncated draw range - * @param {Integer} start (Optional) - * @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', - 2: 'VEC2', - 3: 'VEC3', - 4: 'VEC4', - 16: 'MAT4' - }; - let componentType; // Detect the component type of the attribute array (float, uint or ushort) - - if ( attribute.array.constructor === Float32Array ) { - - componentType = WEBGL_CONSTANTS.FLOAT; - - } else if ( attribute.array.constructor === Uint32Array ) { - - componentType = WEBGL_CONSTANTS.UNSIGNED_INT; - - } else if ( attribute.array.constructor === Uint16Array ) { - - componentType = WEBGL_CONSTANTS.UNSIGNED_SHORT; - - } else if ( attribute.array.constructor === Uint8Array ) { - - componentType = WEBGL_CONSTANTS.UNSIGNED_BYTE; - - } else { - - throw new Error( 'THREE.GLTFExporter: Unsupported bufferAttribute component type.' ); - - } - - 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; - 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. - - if ( geometry !== undefined ) { - - bufferViewTarget = attribute === geometry.index ? WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER : WEBGL_CONSTANTS.ARRAY_BUFFER; - - } - - const bufferView = this.processBufferView( attribute, componentType, start, count, bufferViewTarget ); - const accessorDef = { - bufferView: bufferView.id, - byteOffset: bufferView.byteOffset, - componentType: componentType, - count: count, - max: minMax.max, - min: minMax.min, - type: types[ attribute.itemSize ] - }; - if ( attribute.normalized === true ) accessorDef.normalized = true; - if ( ! json.accessors ) json.accessors = []; - return json.accessors.push( accessorDef ) - 1; - - } - /** - * Process image - * @param {Image} image to process - * @param {Integer} format of the image (THREE.RGBAFormat) - * @param {Boolean} flipY before writing out the image - * @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; - const cache = writer.cache; - const json = writer.json; - const options = writer.options; - const pending = writer.pending; - if ( ! cache.images.has( image ) ) cache.images.set( image, {} ); - const cachedImages = cache.images.get( image ); - const key = mimeType + ':flipY/' + flipY.toString(); - if ( cachedImages[ key ] !== undefined ) return cachedImages[ key ]; - if ( ! json.images ) json.images = []; - const imageDef = { - mimeType: mimeType - }; - const canvas = getCanvas(); - 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 ); - ctx.scale( 1, - 1 ); - - } - - if ( image.data !== undefined ) { - - // THREE.DataTexture - if ( format !== THREE.RGBAFormat ) { - - console.error( 'GLTFExporter: Only THREE.RGBAFormat is supported.' ); - - } - - if ( image.width > options.maxTextureSize || image.height > options.maxTextureSize ) { - - console.warn( 'GLTFExporter: Image size is bigger than maxTextureSize', image ); - - } - - 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 ]; - data[ i + 1 ] = image.data[ i + 1 ]; - data[ i + 2 ] = image.data[ i + 2 ]; - data[ i + 3 ] = image.data[ i + 3 ]; - - } - - ctx.putImageData( new ImageData( data, image.width, image.height ), 0, 0 ); - - } else { - - ctx.drawImage( image, 0, 0, canvas.width, canvas.height ); - - } - - if ( options.binary === true ) { - - pending.push( getToBlobPromise( canvas, mimeType ).then( blob => writer.processBufferViewImage( blob ) ).then( bufferViewIndex => { - - imageDef.bufferView = bufferViewIndex; - - } ) ); - - } else { - - if ( canvas.toDataURL !== undefined ) { - - imageDef.uri = canvas.toDataURL( mimeType ); - - } else { - - pending.push( getToBlobPromise( canvas, mimeType ).then( blob => new FileReader().readAsDataURL( blob ) ).then( dataURL => { - - imageDef.uri = dataURL; - - } ) ); - - } - - } - - const index = json.images.push( imageDef ) - 1; - cachedImages[ key ] = index; - 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; - if ( ! json.samplers ) json.samplers = []; - const samplerDef = { - magFilter: THREE_TO_WEBGL[ map.magFilter ], - minFilter: THREE_TO_WEBGL[ map.minFilter ], - wrapS: THREE_TO_WEBGL[ map.wrapS ], - wrapT: THREE_TO_WEBGL[ map.wrapT ] - }; - 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; - const json = this.json; - if ( cache.textures.has( map ) ) return cache.textures.get( map ); - if ( ! json.textures ) json.textures = []; - let mimeType = map.userData.mimeType; - if ( mimeType === 'image/webp' ) mimeType = 'image/png'; - const textureDef = { - sampler: this.processSampler( map ), - 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.' ); - return null; - - } - - 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 - - - const color = material.color.toArray().concat( [ material.opacity ] ); - - if ( ! equalArray( color, [ 1, 1, 1, 1 ] ) ) { - - materialDef.pbrMetallicRoughness.baseColorFactor = color; - - } - - if ( material.isMeshStandardMaterial ) { - - materialDef.pbrMetallicRoughness.metallicFactor = material.metalness; - materialDef.pbrMetallicRoughness.roughnessFactor = material.roughness; - - } else { - - materialDef.pbrMetallicRoughness.metallicFactor = 0.5; - materialDef.pbrMetallicRoughness.roughnessFactor = 0.5; - - } // pbrMetallicRoughness.metallicRoughnessTexture - - - if ( material.metalnessMap || material.roughnessMap ) { - - const metalRoughTexture = this.buildMetalRoughTexture( material.metalnessMap, material.roughnessMap ); - const metalRoughMapDef = { - index: this.processTexture( metalRoughTexture ) - }; - this.applyTextureTransform( metalRoughMapDef, metalRoughTexture ); - materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef; - - } // pbrMetallicRoughness.baseColorTexture or pbrSpecularGlossiness diffuseTexture - - - if ( material.map ) { - - const baseColorMapDef = { - index: this.processTexture( material.map ) - }; - this.applyTextureTransform( baseColorMapDef, material.map ); - materialDef.pbrMetallicRoughness.baseColorTexture = baseColorMapDef; - - } - - if ( material.emissive ) { - - // 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 ); - console.warn( 'THREE.GLTFExporter: Some emissive components exceed 1; emissive has been limited' ); - - } - - if ( maxEmissiveComponent > 0 ) { - - materialDef.emissiveFactor = emissive.toArray(); - - } // emissiveTexture - - - if ( material.emissiveMap ) { - - const emissiveMapDef = { - index: this.processTexture( material.emissiveMap ) - }; - this.applyTextureTransform( emissiveMapDef, material.emissiveMap ); - materialDef.emissiveTexture = emissiveMapDef; - - } - - } // 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. - // Context: https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995 - normalMapDef.scale = material.normalScale.x; - - } - - this.applyTextureTransform( normalMapDef, material.normalMap ); - materialDef.normalTexture = normalMapDef; - - } // occlusionTexture - - - if ( material.aoMap ) { - - const occlusionMapDef = { - index: this.processTexture( material.aoMap ), - texCoord: 1 - }; - - if ( material.aoMapIntensity !== 1.0 ) { - - occlusionMapDef.strength = material.aoMapIntensity; - - } - - this.applyTextureTransform( occlusionMapDef, material.aoMap ); - materialDef.occlusionTexture = occlusionMapDef; - - } // alphaMode - - - if ( material.transparent ) { - - materialDef.alphaMode = 'BLEND'; - - } else { - - if ( material.alphaTest > 0.0 ) { - - materialDef.alphaMode = 'MASK'; - materialDef.alphaCutoff = material.alphaTest; - - } - - } // 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 ++ ) { - - meshCacheKeyParts.push( mesh.material[ i ].uuid ); - - } - - } else { - - meshCacheKeyParts.push( mesh.material.uuid ); - - } - - const meshCacheKey = meshCacheKeyParts.join( ':' ); - if ( cache.meshes.has( meshCacheKey ) ) return cache.meshes.get( meshCacheKey ); - const geometry = mesh.geometry; - let mode; // Use the correct mode - - if ( mesh.isLineSegments ) { - - mode = WEBGL_CONSTANTS.LINES; - - } else if ( mesh.isLineLoop ) { - - mode = WEBGL_CONSTANTS.LINE_LOOP; - - } else if ( mesh.isLine ) { - - mode = WEBGL_CONSTANTS.LINE_STRIP; - - } else if ( mesh.isPoints ) { - - mode = WEBGL_CONSTANTS.POINTS; - - } else { - - mode = mesh.material.wireframe ? WEBGL_CONSTANTS.LINES : WEBGL_CONSTANTS.TRIANGLES; - - } - - 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 nameConversion = { - uv: 'TEXCOORD_0', - uv2: 'TEXCOORD_1', - color: 'COLOR_0', - skinWeight: 'WEIGHTS_0', - 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 - - - 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. - - 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. - - - 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.' ); - modifiedAttribute = new THREE.BufferAttribute( new Uint16Array( array ), attribute.itemSize, attribute.normalized ); - - } - - const accessor = this.processAccessor( modifiedAttribute || attribute, geometry ); - - if ( accessor !== null ) { - - attributes[ attributeName ] = accessor; - cache.attributes.set( this.getUID( attribute ), accessor ); - - } - - } - - if ( originalNormal !== undefined ) geometry.setAttribute( 'normal', originalNormal ); // 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 ) { - - reverseDictionary[ mesh.morphTargetDictionary[ key ] ] = key; - - } - - } - - for ( let i = 0; i < mesh.morphTargetInfluences.length; ++ i ) { - - 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 ) { - - console.warn( 'GLTFExporter: Only POSITION and NORMAL morph are supported.' ); - warned = true; - - } - - continue; - - } - - 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. - // - // 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 - - - const relativeAttribute = attribute.clone(); - - if ( ! geometry.morphTargetsRelative ) { - - for ( let j = 0, jl = attribute.count; j < jl; j ++ ) { - - relativeAttribute.setXYZ( j, attribute.getX( j ) - baseAttribute.getX( j ), attribute.getY( j ) - baseAttribute.getY( j ), attribute.getZ( j ) - baseAttribute.getZ( j ) ); - - } - - } - - target[ gltfAttributeName ] = this.processAccessor( relativeAttribute, geometry ); - cache.attributes.set( this.getUID( baseAttribute, true ), target[ gltfAttributeName ] ); - - } - - targets.push( target ); - weights.push( mesh.morphTargetInfluences[ i ] ); - if ( mesh.morphTargetDictionary !== undefined ) targetNames.push( reverseDictionary[ i ] ); - - } - - meshDef.weights = weights; - - if ( targetNames.length > 0 ) { - - meshDef.extras = {}; - meshDef.extras.targetNames = targetNames; - - } - - } - - const isMultiMaterial = Array.isArray( mesh.material ); - if ( isMultiMaterial && geometry.groups.length === 0 ) return null; - const materials = isMultiMaterial ? mesh.material : [ mesh.material ]; - const groups = isMultiMaterial ? geometry.groups : [ { - materialIndex: 0, - start: undefined, - count: undefined - } ]; - - for ( let i = 0, il = groups.length; i < il; i ++ ) { - - const primitive = { - mode: mode, - attributes: attributes - }; - 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; - - } - - if ( cache.attributes.has( cacheKey ) ) { - - primitive.indices = cache.attributes.get( cacheKey ); - - } else { - - primitive.indices = this.processAccessor( geometry.index, geometry, groups[ i ].start, groups[ i ].count ); - cache.attributes.set( cacheKey, primitive.indices ); - - } - - if ( primitive.indices === null ) delete primitive.indices; - - } - - const material = this.processMaterial( materials[ groups[ i ].materialIndex ] ); - if ( material !== null ) primitive.material = material; - primitives.push( primitive ); - - } - - 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; - if ( ! json.cameras ) json.cameras = []; - const isOrtho = camera.isOrthographicCamera; - const cameraDef = { - type: isOrtho ? 'orthographic' : 'perspective' - }; - - if ( isOrtho ) { - - cameraDef.orthographic = { - xmag: camera.right * 2, - ymag: camera.top * 2, - zfar: camera.far <= 0 ? 0.001 : camera.far, - znear: camera.near < 0 ? 0 : camera.near - }; - - } else { - - cameraDef.perspective = { - aspectRatio: camera.aspect, - yfov: THREE.MathUtils.degToRad( camera.fov ), - zfar: camera.far <= 0 ? 0.001 : camera.far, - znear: camera.near < 0 ? 0 : camera.near - }; - - } // 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. - * - * Status: - * - Only properties listed in PATH_PROPERTIES may be animated. - * - * @param {THREE.AnimationClip} clip - * @param {THREE.Object3D} root - * @return {number|null} - */ - - - processAnimation( clip, root ) { - - const json = this.json; - const nodeMap = this.nodeMap; - if ( ! json.animations ) json.animations = []; - clip = GLTFExporter.Utils.mergeMorphTargetTracks( clip.clone(), root ); - 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 ) { - - trackNode = trackNode.skeleton.getBoneByName( trackBinding.objectIndex ); - - } else { - - trackNode = undefined; - - } - - } - - if ( ! trackNode || ! trackProperty ) { - - console.warn( 'THREE.GLTFExporter: Could not export animation track "%s".', track.name ); - return null; - - } - - 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 - // 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 - // (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 ) { - - interpolation = 'STEP'; - - } else { - - interpolation = 'LINEAR'; - - } - - samplers.push( { - input: this.processAccessor( new THREE.BufferAttribute( track.times, inputItemSize ) ), - output: this.processAccessor( new THREE.BufferAttribute( track.values, outputItemSize ) ), - interpolation: interpolation - } ); - channels.push( { - sampler: samplers.length - 1, - target: { - node: nodeMap.get( trackNode ), - path: trackProperty - } - } ); - - } - - json.animations.push( { - name: clip.name || 'clip_' + json.animations.length, - samplers: samplers, - channels: channels - } ); - return json.animations.length - 1; - - } - /** - * @param {THREE.Object3D} object - * @return {number|null} - */ - - - processSkin( object ) { - - const json = this.json; - const nodeMap = this.nodeMap; - const node = json.nodes[ nodeMap.get( object ) ]; - const skeleton = object.skeleton; - if ( skeleton === undefined ) return null; - const rootJoint = object.skeleton.bones[ 0 ]; - if ( rootJoint === undefined ) return null; - 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 ] ) ); - temporaryBoneInverse.copy( skeleton.boneInverses[ i ] ); - temporaryBoneInverse.multiply( object.bindMatrix ).toArray( inverseBindMatrices, i * 16 ); - - } - - if ( json.skins === undefined ) json.skins = []; - json.skins.push( { - inverseBindMatrices: this.processAccessor( new THREE.BufferAttribute( inverseBindMatrices, 16 ) ), - joints: joints, - skeleton: nodeMap.get( rootJoint ) - } ); - const skinIndex = node.skin = json.skins.length - 1; - 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; - const options = this.options; - 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; - - } - - if ( ! equalArray( position, [ 0, 0, 0 ] ) ) { - - nodeDef.translation = position; - - } - - if ( ! equalArray( scale, [ 1, 1, 1 ] ) ) { - - nodeDef.scale = scale; - - } - - } else { - - if ( object.matrixAutoUpdate ) { - - object.updateMatrix(); - - } - - if ( isIdentityMatrix( object.matrix ) === false ) { - - nodeDef.matrix = object.matrix.elements; - - } - - } // 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 ); - if ( meshIndex !== null ) nodeDef.mesh = meshIndex; - - } else if ( object.isCamera ) { - - nodeDef.camera = this.processCamera( object ); - - } - - 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 ); - if ( nodeIndex !== null ) children.push( nodeIndex ); - - } - - } - - if ( children.length > 0 ) nodeDef.children = children; - - } - - this._invokeAll( function ( ext ) { - - 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 = []; - json.scene = 0; - - } - - const sceneDef = {}; - 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 ); - if ( nodeIndex !== null ) nodes.push( nodeIndex ); - - } - - } - - if ( nodes.length > 0 ) sceneDef.nodes = nodes; - 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 - // modify the .parent and break its original scene and hierarchy - scene.children.push( objects[ i ] ); - - } - - 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 ) { - - this.processScene( input[ i ] ); - - } else { - - objectsWithoutScene.push( input[ i ] ); - - } - - } - - if ( objectsWithoutScene.length > 0 ) this.processObjects( objectsWithoutScene ); - - for ( let i = 0; i < this.skins.length; ++ i ) { - - this.processSkin( this.skins[ i ] ); - - } - - for ( let i = 0; i < options.animations.length; ++ i ) { - - this.processAnimation( options.animations[ i ], input[ 0 ] ); - - } - - this._invokeAll( function ( ext ) { - - ext.afterParse && ext.afterParse( input ); - - } ); - - } - - _invokeAll( func ) { - - for ( let i = 0, il = this.plugins.length; i < il; i ++ ) { - - func( this.plugins[ i ] ); - - } - - } - - } - /** - * Punctual Lights Extension - * - * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual - */ - - - class GLTFLightExtension { - - constructor( writer ) { - - this.writer = writer; - 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 ); - return; - - } - - const writer = this.writer; - const json = writer.json; - const extensionsUsed = writer.extensionsUsed; - const lightDef = {}; - if ( light.name ) lightDef.name = light.name; - lightDef.color = light.color.toArray(); - lightDef.intensity = light.intensity; - - if ( light.isDirectionalLight ) { - - lightDef.type = 'directional'; - - } else if ( light.isPointLight ) { - - lightDef.type = 'point'; - if ( light.distance > 0 ) lightDef.range = light.distance; - - } else if ( light.isSpotLight ) { - - lightDef.type = 'spot'; - if ( light.distance > 0 ) lightDef.range = light.distance; - lightDef.spot = {}; - lightDef.spot.innerConeAngle = ( light.penumbra - 1.0 ) * light.angle * - 1.0; - lightDef.spot.outerConeAngle = light.angle; - - } - - if ( light.decay !== undefined && light.decay !== 2 ) { - - console.warn( 'THREE.GLTFExporter: Light decay may be lost. glTF is physically-based, ' + 'and expects light.decay=2.' ); - - } - - if ( light.target && ( light.target.parent !== light || light.target.position.x !== 0 || light.target.position.y !== 0 || light.target.position.z !== - 1 ) ) { - - console.warn( 'THREE.GLTFExporter: Light direction may be lost. For best results, ' + 'make light.target a child of the light with position 0,0,-1.' ); - - } - - if ( ! extensionsUsed[ this.name ] ) { - - json.extensions = json.extensions || {}; - json.extensions[ this.name ] = { - lights: [] - }; - extensionsUsed[ this.name ] = true; - - } - - const lights = json.extensions[ this.name ].lights; - lights.push( lightDef ); - nodeDef.extensions = nodeDef.extensions || {}; - nodeDef.extensions[ this.name ] = { - light: lights.length - 1 - }; - - } - - } - /** - * Unlit Materials Extension - * - * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit - */ - - - class GLTFMaterialsUnlitExtension { - - constructor( writer ) { - - this.writer = writer; - this.name = 'KHR_materials_unlit'; - - } - - writeMaterial( material, materialDef ) { - - if ( ! material.isMeshBasicMaterial ) return; - const writer = this.writer; - const extensionsUsed = writer.extensionsUsed; - materialDef.extensions = materialDef.extensions || {}; - materialDef.extensions[ this.name ] = {}; - extensionsUsed[ this.name ] = true; - materialDef.pbrMetallicRoughness.metallicFactor = 0.0; - materialDef.pbrMetallicRoughness.roughnessFactor = 0.9; - - } - - } - /** - * 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 ) { - - this.writer = writer; - this.name = 'KHR_materials_clearcoat'; - - } - - writeMaterial( material, materialDef ) { - - if ( ! material.isMeshPhysicalMaterial ) return; - const writer = this.writer; - const extensionsUsed = writer.extensionsUsed; - const extensionDef = {}; - extensionDef.clearcoatFactor = material.clearcoat; - - if ( material.clearcoatMap ) { - - const clearcoatMapDef = { - index: writer.processTexture( material.clearcoatMap ) - }; - writer.applyTextureTransform( clearcoatMapDef, material.clearcoatMap ); - extensionDef.clearcoatTexture = clearcoatMapDef; - - } - - extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness; - - if ( material.clearcoatRoughnessMap ) { - - const clearcoatRoughnessMapDef = { - index: writer.processTexture( material.clearcoatRoughnessMap ) - }; - writer.applyTextureTransform( clearcoatRoughnessMapDef, material.clearcoatRoughnessMap ); - extensionDef.clearcoatRoughnessTexture = clearcoatRoughnessMapDef; - - } - - if ( material.clearcoatNormalMap ) { - - const clearcoatNormalMapDef = { - index: writer.processTexture( material.clearcoatNormalMap ) - }; - writer.applyTextureTransform( clearcoatNormalMapDef, material.clearcoatNormalMap ); - extensionDef.clearcoatNormalTexture = clearcoatNormalMapDef; - - } - - materialDef.extensions = materialDef.extensions || {}; - materialDef.extensions[ this.name ] = extensionDef; - extensionsUsed[ this.name ] = true; - - } - - } - /** - * Iridescence Materials Extension - * - * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence - */ - - - class GLTFMaterialsIridescenceExtension { - - constructor( writer ) { - - this.writer = writer; - this.name = 'KHR_materials_iridescence'; - - } - - writeMaterial( material, materialDef ) { - - if ( ! material.isMeshPhysicalMaterial ) return; - const writer = this.writer; - const extensionsUsed = writer.extensionsUsed; - const extensionDef = {}; - extensionDef.iridescenceFactor = material.iridescence; - - if ( material.iridescenceMap ) { - - const iridescenceMapDef = { - index: writer.processTexture( material.iridescenceMap ) - }; - writer.applyTextureTransform( iridescenceMapDef, material.iridescenceMap ); - extensionDef.iridescenceTexture = iridescenceMapDef; - - } - - extensionDef.iridescenceIor = material.iridescenceIOR; - extensionDef.iridescenceThicknessMinimum = material.iridescenceThicknessRange[ 0 ]; - extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[ 1 ]; - - if ( material.iridescenceThicknessMap ) { - - const iridescenceThicknessMapDef = { - index: writer.processTexture( material.iridescenceThicknessMap ) - }; - writer.applyTextureTransform( iridescenceThicknessMapDef, material.iridescenceThicknessMap ); - extensionDef.iridescenceThicknessTexture = iridescenceThicknessMapDef; - - } - - materialDef.extensions = materialDef.extensions || {}; - materialDef.extensions[ this.name ] = extensionDef; - extensionsUsed[ this.name ] = true; - - } - - } - /** - * Transmission Materials Extension - * - * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission - */ - - - class GLTFMaterialsTransmissionExtension { - - constructor( writer ) { - - this.writer = writer; - this.name = 'KHR_materials_transmission'; - - } - - writeMaterial( material, materialDef ) { - - if ( ! material.isMeshPhysicalMaterial || material.transmission === 0 ) return; - const writer = this.writer; - const extensionsUsed = writer.extensionsUsed; - const extensionDef = {}; - extensionDef.transmissionFactor = material.transmission; - - if ( material.transmissionMap ) { - - const transmissionMapDef = { - index: writer.processTexture( material.transmissionMap ) - }; - writer.applyTextureTransform( transmissionMapDef, material.transmissionMap ); - extensionDef.transmissionTexture = transmissionMapDef; - - } - - materialDef.extensions = materialDef.extensions || {}; - materialDef.extensions[ this.name ] = extensionDef; - extensionsUsed[ this.name ] = true; - - } - - } - /** - * Materials Volume Extension - * - * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume - */ - - - class GLTFMaterialsVolumeExtension { - - constructor( writer ) { - - this.writer = writer; - this.name = 'KHR_materials_volume'; - - } - - writeMaterial( material, materialDef ) { - - if ( ! material.isMeshPhysicalMaterial || material.transmission === 0 ) return; - const writer = this.writer; - const extensionsUsed = writer.extensionsUsed; - const extensionDef = {}; - extensionDef.thicknessFactor = material.thickness; - - if ( material.thicknessMap ) { - - const thicknessMapDef = { - index: writer.processTexture( material.thicknessMap ) - }; - writer.applyTextureTransform( thicknessMapDef, material.thicknessMap ); - extensionDef.thicknessTexture = thicknessMapDef; - - } - - extensionDef.attenuationDistance = material.attenuationDistance; - extensionDef.attenuationColor = material.attenuationColor.toArray(); - materialDef.extensions = materialDef.extensions || {}; - materialDef.extensions[ this.name ] = extensionDef; - extensionsUsed[ this.name ] = true; - - } - - } - /** - * 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; - - } - - index = 0; - - } else if ( time < track.times[ 0 ] ) { - - if ( Math.abs( track.times[ 0 ] - time ) < tolerance ) return 0; - times[ 0 ] = time; - times.set( track.times, 1 ); - values.set( interpolant.evaluate( time ), 0 ); - values.set( track.values, valueSize ); - index = 0; - - } else if ( time > track.times[ track.times.length - 1 ] ) { - - if ( Math.abs( track.times[ track.times.length - 1 ] - time ) < tolerance ) { - - return track.times.length - 1; - - } - - times[ times.length - 1 ] = time; - times.set( track.times, 0 ); - values.set( track.values, 0 ); - values.set( interpolant.evaluate( time ), track.values.length ); - index = times.length - 1; - - } else { - - 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 ); - times[ i + 1 ] = time; - times.set( track.times.slice( i + 1 ), i + 2 ); - values.set( track.values.slice( 0, ( i + 1 ) * valueSize ), 0 ); - values.set( interpolant.evaluate( time ), ( i + 1 ) * valueSize ); - values.set( track.values.slice( ( i + 1 ) * valueSize ), ( i + 2 ) * valueSize ); - index = i + 1; - break; - - } - - } - - } - - track.times = times; - track.values = values; - return index; - - }, - mergeMorphTargetTracks: function ( clip, root ) { - - 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. - tracks.push( sourceTrack ); - continue; - - } - - if ( sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodDiscrete && sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodLinear ) { - - if ( sourceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) { - - // This should never happen, because glTF morph target animations - // affect all targets already. - throw new Error( 'THREE.GLTFExporter: Cannot merge tracks with glTF CUBICSPLINE interpolation.' ); - - } - - console.warn( 'THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.' ); - sourceTrack = sourceTrack.clone(); - sourceTrack.setInterpolation( THREE.InterpolateLinear ); - - } - - 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. - - 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. - - - mergedTrack.name = ( sourceTrackBinding.nodeName || '' ) + '.morphTargetInfluences'; - mergedTrack.values = values; - mergedTracks[ sourceTrackNode.uuid ] = mergedTrack; - tracks.push( mergedTrack ); - continue; - - } - - 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. - - 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 - // 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 ] ); - mergedTrack.values[ keyframeIndex * targetCount + targetIndex ] = sourceTrack.values[ j ]; - - } - - } - - clip.tracks = tracks; - return clip; - - } - }; - - THREE.GLTFExporter = GLTFExporter; - -} )(); diff --git a/examples/js/exporters/MMDExporter.js b/examples/js/exporters/MMDExporter.js deleted file mode 100644 index 90fd2326d6991e..00000000000000 --- a/examples/js/exporters/MMDExporter.js +++ /dev/null @@ -1,194 +0,0 @@ -( function () { - - /** - * Dependencies - * - mmd-parser https://github.com/takahirox/mmd-parser - */ - - class MMDExporter { - - /* TODO: implement - // mesh -> pmd - this.parsePmd = function ( object ) { - }; - */ - - /* TODO: implement - // mesh -> pmx - this.parsePmx = function ( object ) { - }; - */ - - /* TODO: implement - // animation + skeleton -> vmd - this.parseVmd = function ( object ) { - }; - */ - - /* - * skeleton -> vpd - * Returns Shift_JIS encoded Uint8Array. Otherwise return strings. - */ - parseVpd( skin, outputShiftJis, useOriginalBones ) { - - if ( skin.isSkinnedMesh !== true ) { - - console.warn( 'THREE.MMDExporter: parseVpd() requires SkinnedMesh instance.' ); - return null; - - } - - function toStringsFromNumber( num ) { - - if ( Math.abs( num ) < 1e-6 ) num = 0; - let a = num.toString(); - - if ( a.indexOf( '.' ) === - 1 ) { - - a += '.'; - - } - - a += '000000'; - const index = a.indexOf( '.' ); - const d = a.slice( 0, index ); - const p = a.slice( index + 1, index + 7 ); - return d + '.' + p; - - } - - function toStringsFromArray( array ) { - - const a = []; - - for ( let i = 0, il = array.length; i < il; i ++ ) { - - a.push( toStringsFromNumber( array[ i ] ) ); - - } - - return a.join( ',' ); - - } - - skin.updateMatrixWorld( true ); - const bones = skin.skeleton.bones; - const bones2 = getBindBones( skin ); - const position = new THREE.Vector3(); - const quaternion = new THREE.Quaternion(); - const quaternion2 = new THREE.Quaternion(); - const matrix = new THREE.Matrix4(); - const array = []; - array.push( 'Vocaloid Pose Data file' ); - array.push( '' ); - 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 ); - - } else { - - matrix.copy( bone.matrix ); - - } - - 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 - - pArray[ 2 ] = - pArray[ 2 ]; - qArray[ 0 ] = - qArray[ 0 ]; - qArray[ 1 ] = - qArray[ 1 ]; - array.push( 'Bone' + i + '{' + bone.name ); - array.push( ' ' + toStringsFromArray( pArray ) + ';' ); - array.push( ' ' + toStringsFromArray( qArray ) + ';' ); - array.push( '}' ); - array.push( '' ); - - } - - array.push( '' ); - const lines = array.join( '\n' ); - return outputShiftJis === true ? unicodeToShiftjis( lines ) : lines; - - } - - } // 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 ]; - const value = table[ key ]; - key = parseInt( key ); - u2sTable[ value ] = key; - - } - - } - - 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 ) ); - - } else if ( value > 0xff ) { - - array.push( value >> 8 & 0xff ); - array.push( value & 0xff ); - - } else { - - array.push( value & 0xff ); - - } - - } - - return new Uint8Array( array ); - - } - - function getBindBones( skin ) { - - // any more efficient ways? - const poseSkin = skin.clone(); - poseSkin.pose(); - return poseSkin.skeleton.bones; - - } - - THREE.MMDExporter = MMDExporter; - -} )(); diff --git a/examples/js/exporters/OBJExporter.js b/examples/js/exporters/OBJExporter.js deleted file mode 100644 index 2f015139d52099..00000000000000 --- a/examples/js/exporters/OBJExporter.js +++ /dev/null @@ -1,272 +0,0 @@ -( function () { - - class OBJExporter { - - parse( object ) { - - let output = ''; - let indexVertex = 0; - let indexVertexUvs = 0; - let indexNormals = 0; - const vertex = new THREE.Vector3(); - const color = new THREE.Color(); - const normal = new THREE.Vector3(); - const uv = new THREE.Vector2(); - const face = []; - - function parseMesh( mesh ) { - - let nbVertex = 0; - let nbNormals = 0; - let nbVertexUvs = 0; - 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 - - - const vertices = geometry.getAttribute( 'position' ); - const normals = geometry.getAttribute( 'normal' ); - const uvs = geometry.getAttribute( 'uv' ); - const indices = geometry.getIndex(); // 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 - - - 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.applyMatrix4( mesh.matrixWorld ); // transform the vertex to export format - - output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n'; - - } - - } // 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 - - output += 'vt ' + uv.x + ' ' + uv.y + '\n'; - - } - - } // 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.applyMatrix3( normalMatrixWorld ).normalize(); // transform the normal to export format - - output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n'; - - } - - } // faces - - - if ( indices !== null ) { - - for ( let i = 0, l = indices.count; i < l; i += 3 ) { - - for ( let m = 0; m < 3; m ++ ) { - - 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 - - - output += 'f ' + face.join( ' ' ) + '\n'; - - } - - } else { - - for ( let i = 0, l = vertices.count; i < l; i += 3 ) { - - for ( let m = 0; m < 3; m ++ ) { - - const j = i + m + 1; - face[ m ] = indexVertex + j + ( normals || uvs ? '/' + ( uvs ? indexVertexUvs + j : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' ); - - } // transform the face to export format - - - output += 'f ' + face.join( ' ' ) + '\n'; - - } - - } // update index - - - indexVertex += nbVertex; - indexVertexUvs += nbVertexUvs; - indexNormals += nbNormals; - - } - - function parseLine( line ) { - - let nbVertex = 0; - 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 - - 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.applyMatrix4( line.matrixWorld ); // transform the vertex to export format - - output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n'; - - } - - } - - if ( type === 'Line' ) { - - output += 'l '; - - for ( let j = 1, l = vertices.count; j <= l; j ++ ) { - - output += indexVertex + j + ' '; - - } - - output += '\n'; - - } - - if ( type === 'LineSegments' ) { - - for ( let j = 1, k = j + 1, l = vertices.count; j < l; j += 2, k = j + 1 ) { - - output += 'l ' + ( indexVertex + j ) + ' ' + ( indexVertex + k ) + '\n'; - - } - - } // update index - - - indexVertex += nbVertex; - - } - - function parsePoints( points ) { - - 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 ++ ) { - - vertex.fromBufferAttribute( vertices, i ); - vertex.applyMatrix4( points.matrixWorld ); - output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z; - - if ( colors !== undefined ) { - - color.fromBufferAttribute( colors, i ).convertLinearToSRGB(); - output += ' ' + color.r + ' ' + color.g + ' ' + color.b; - - } - - output += '\n'; - - } - - output += 'p '; - - for ( let j = 1, l = vertices.count; j <= l; j ++ ) { - - output += indexVertex + j + ' '; - - } - - output += '\n'; - - } // update index - - - indexVertex += nbVertex; - - } - - object.traverse( function ( child ) { - - if ( child.isMesh === true ) { - - parseMesh( child ); - - } - - if ( child.isLine === true ) { - - parseLine( child ); - - } - - if ( child.isPoints === true ) { - - parsePoints( child ); - - } - - } ); - return output; - - } - - } - - THREE.OBJExporter = OBJExporter; - -} )(); diff --git a/examples/js/exporters/PLYExporter.js b/examples/js/exporters/PLYExporter.js deleted file mode 100644 index d9145f6ae26530..00000000000000 --- a/examples/js/exporters/PLYExporter.js +++ /dev/null @@ -1,434 +0,0 @@ -( function () { - - /** - * https://github.com/gkjohnson/ply-exporter-js - * - * Usage: - * const exporter = new PLYExporter(); - * - * // second argument is a list of options - * exporter.parse(mesh, data => console.log(data), { binary: true, excludeAttributes: [ 'color' ], littleEndian: true }); - * - * Format Definition: - * http://paulbourke.net/dataformats/ply/ - */ - - 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 ) { - - 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 ); - - } - - } - - } ); - - } // Default options - - - const defaultOptions = { - binary: false, - excludeAttributes: [], - // normal, uv, color, index - littleEndian: false - }; - options = Object.assign( defaultOptions, options ); - const excludeAttributes = options.excludeAttributes; - let includeNormals = false; - let includeColors = false; - 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 ) { - - if ( child.isMesh === true ) { - - 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; - - } - - vertexCount += vertices.count; - faceCount += indices ? indices.count / 3 : vertices.count / 3; - if ( normals !== undefined ) includeNormals = true; - if ( uvs !== undefined ) includeUVs = true; - if ( colors !== undefined ) includeColors = true; - - } - - } ); - const tempColor = new THREE.Color(); - const 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 - // number of vertices that is divisble by 3 (and therefore representable - // as triangles) - console.error( 'PLYExporter: Failed to generate a valid PLY file with triangle indices because the ' + 'number of indices is not divisible by 3.' ); - return null; - - } - - 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 - 'property float x\n' + 'property float y\n' + 'property float z\n'; - - if ( includeNormals === true ) { - - // normal - header += 'property float nx\n' + 'property float ny\n' + 'property float nz\n'; - - } - - if ( includeUVs === true ) { - - // uvs - header += 'property float s\n' + 'property float t\n'; - - } - - if ( includeColors === true ) { - - // colors - header += 'property uchar red\n' + 'property uchar green\n' + 'property uchar blue\n'; - - } - - if ( includeIndices === true ) { - - // faces - header += `element face ${faceCount}\n` + 'property list uchar int vertex_index\n'; - - } - - 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 - // 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 ) ); // 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 ); - let vOffset = headerBin.length; - let fOffset = headerBin.length + vertexListLength; - let writtenVertices = 0; - traverseMeshes( function ( mesh, geometry ) { - - const vertices = geometry.getAttribute( 'position' ); - const normals = geometry.getAttribute( 'normal' ); - const uvs = geometry.getAttribute( 'uv' ); - 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 - - 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 - - if ( includeNormals === true ) { - - if ( normals != null ) { - - vertex.fromBufferAttribute( normals, i ); - vertex.applyMatrix3( normalMatrixWorld ).normalize(); - 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; - - } else { - - output.setFloat32( vOffset, 0, options.littleEndian ); - vOffset += 4; - output.setFloat32( vOffset, 0, options.littleEndian ); - vOffset += 4; - output.setFloat32( vOffset, 0, options.littleEndian ); - vOffset += 4; - - } - - } // UV information - - - if ( includeUVs === true ) { - - if ( uvs != null ) { - - output.setFloat32( vOffset, uvs.getX( i ), options.littleEndian ); - vOffset += 4; - output.setFloat32( vOffset, uvs.getY( i ), options.littleEndian ); - vOffset += 4; - - } else { - - output.setFloat32( vOffset, 0, options.littleEndian ); - vOffset += 4; - output.setFloat32( vOffset, 0, options.littleEndian ); - vOffset += 4; - - } - - } // THREE.Color information - - - if ( includeColors === true ) { - - if ( colors != null ) { - - tempColor.fromBufferAttribute( colors, i ).convertLinearToSRGB(); - output.setUint8( vOffset, Math.floor( tempColor.r * 255 ) ); - vOffset += 1; - output.setUint8( vOffset, Math.floor( tempColor.g * 255 ) ); - vOffset += 1; - output.setUint8( vOffset, Math.floor( tempColor.b * 255 ) ); - vOffset += 1; - - } else { - - output.setUint8( vOffset, 255 ); - vOffset += 1; - output.setUint8( vOffset, 255 ); - vOffset += 1; - output.setUint8( vOffset, 255 ); - vOffset += 1; - - } - - } - - } - - if ( includeIndices === true ) { - - // Create the face list - if ( indices !== null ) { - - for ( let i = 0, l = indices.count; i < l; i += 3 ) { - - output.setUint8( fOffset, 3 ); - fOffset += 1; - output.setUint32( fOffset, indices.getX( i + 0 ) + writtenVertices, options.littleEndian ); - fOffset += indexByteCount; - output.setUint32( fOffset, indices.getX( i + 1 ) + writtenVertices, options.littleEndian ); - fOffset += indexByteCount; - output.setUint32( fOffset, indices.getX( i + 2 ) + writtenVertices, options.littleEndian ); - fOffset += indexByteCount; - - } - - } else { - - for ( let i = 0, l = vertices.count; i < l; i += 3 ) { - - output.setUint8( fOffset, 3 ); - fOffset += 1; - output.setUint32( fOffset, writtenVertices + i, options.littleEndian ); - fOffset += indexByteCount; - output.setUint32( fOffset, writtenVertices + i + 1, options.littleEndian ); - fOffset += indexByteCount; - output.setUint32( fOffset, writtenVertices + i + 2, options.littleEndian ); - fOffset += indexByteCount; - - } - - } - - } // Save the amount of verts we've already written so we can offset - // the face index on the next mesh - - - writtenVertices += vertices.count; - - } ); - result = output.buffer; - - } else { - - // Ascii File Generation - // count the number of vertices - let writtenVertices = 0; - let vertexList = ''; - let faceList = ''; - traverseMeshes( function ( mesh, geometry ) { - - const vertices = geometry.getAttribute( 'position' ); - const normals = geometry.getAttribute( 'normal' ); - const uvs = geometry.getAttribute( 'uv' ); - const colors = geometry.getAttribute( 'color' ); - const indices = geometry.getIndex(); - 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 - - let line = vertex.x + ' ' + vertex.y + ' ' + vertex.z; // Normal information - - if ( includeNormals === true ) { - - if ( normals != null ) { - - vertex.fromBufferAttribute( normals, i ); - vertex.applyMatrix3( normalMatrixWorld ).normalize(); - line += ' ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z; - - } else { - - line += ' 0 0 0'; - - } - - } // UV information - - - if ( includeUVs === true ) { - - if ( uvs != null ) { - - line += ' ' + uvs.getX( i ) + ' ' + uvs.getY( i ); - - } else { - - line += ' 0 0'; - - } - - } // THREE.Color information - - - if ( includeColors === true ) { - - if ( colors != null ) { - - tempColor.fromBufferAttribute( colors, i ).convertLinearToSRGB(); - line += ' ' + Math.floor( tempColor.r * 255 ) + ' ' + Math.floor( tempColor.g * 255 ) + ' ' + Math.floor( tempColor.b * 255 ); - - } else { - - line += ' 255 255 255'; - - } - - } - - vertexList += line + '\n'; - - } // Create the face list - - - if ( includeIndices === true ) { - - if ( indices !== null ) { - - for ( let i = 0, l = indices.count; i < l; i += 3 ) { - - faceList += `3 ${indices.getX( i + 0 ) + writtenVertices}`; - faceList += ` ${indices.getX( i + 1 ) + writtenVertices}`; - faceList += ` ${indices.getX( i + 2 ) + writtenVertices}\n`; - - } - - } else { - - for ( let i = 0, l = vertices.count; i < l; i += 3 ) { - - faceList += `3 ${writtenVertices + i} ${writtenVertices + i + 1} ${writtenVertices + i + 2}\n`; - - } - - } - - faceCount += indices ? indices.count / 3 : vertices.count / 3; - - } - - writtenVertices += vertices.count; - - } ); - result = `${header}${vertexList}${includeIndices ? `${faceList}\n` : '\n'}`; - - } - - if ( typeof onDone === 'function' ) requestAnimationFrame( () => onDone( result ) ); - return result; - - } - - } - - THREE.PLYExporter = PLYExporter; - -} )(); diff --git a/examples/js/exporters/STLExporter.js b/examples/js/exporters/STLExporter.js deleted file mode 100644 index a85e18d907937b..00000000000000 --- a/examples/js/exporters/STLExporter.js +++ /dev/null @@ -1,197 +0,0 @@ -( function () { - - /** - * Usage: - * const exporter = new STLExporter(); - * - * // second argument is a list of options - * const data = exporter.parse( mesh, { binary: true } ); - * - */ - - class STLExporter { - - parse( scene, options = {} ) { - - const binary = options.binary !== undefined ? options.binary : false; // - - const objects = []; - let triangles = 0; - scene.traverse( function ( object ) { - - 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; - objects.push( { - object3d: object, - geometry: geometry - } ); - - } - - } ); - let output; - let offset = 80; // skip header - - if ( binary === true ) { - - const bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4; - const arrayBuffer = new ArrayBuffer( bufferLength ); - output = new DataView( arrayBuffer ); - output.setUint32( offset, triangles, true ); - offset += 4; - - } else { - - output = ''; - output += 'solid exported\n'; - - } - - const vA = new THREE.Vector3(); - const vB = new THREE.Vector3(); - const vC = new THREE.Vector3(); - 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 ); - const b = index.getX( j + 1 ); - const c = index.getX( j + 2 ); - writeFace( a, b, c, positionAttribute, object ); - - } - - } else { - - // non-indexed geometry - for ( let j = 0; j < positionAttribute.count; j += 3 ) { - - const a = j + 0; - const b = j + 1; - const c = j + 2; - writeFace( a, b, c, positionAttribute, object ); - - } - - } - - } - - if ( binary === false ) { - - output += 'endsolid exported\n'; - - } - - 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 ); - object.boneTransform( b, vB ); - object.boneTransform( c, vC ); - - } - - vA.applyMatrix4( object.matrixWorld ); - vB.applyMatrix4( object.matrixWorld ); - vC.applyMatrix4( object.matrixWorld ); - writeNormal( vA, vB, vC ); - writeVertex( vA ); - writeVertex( vB ); - writeVertex( vC ); - - if ( binary === true ) { - - output.setUint16( offset, 0, true ); - offset += 2; - - } else { - - output += '\t\tendloop\n'; - output += '\tendfacet\n'; - - } - - } - - function writeNormal( vA, vB, vC ) { - - cb.subVectors( vC, vB ); - ab.subVectors( vA, vB ); - cb.cross( ab ).normalize(); - normal.copy( cb ).normalize(); - - if ( binary === true ) { - - output.setFloat32( offset, normal.x, true ); - offset += 4; - output.setFloat32( offset, normal.y, true ); - offset += 4; - output.setFloat32( offset, normal.z, true ); - offset += 4; - - } else { - - output += '\tfacet normal ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n'; - output += '\t\touter loop\n'; - - } - - } - - function writeVertex( vertex ) { - - if ( binary === true ) { - - output.setFloat32( offset, vertex.x, true ); - offset += 4; - output.setFloat32( offset, vertex.y, true ); - offset += 4; - output.setFloat32( offset, vertex.z, true ); - offset += 4; - - } else { - - output += '\t\t\tvertex ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n'; - - } - - } - - } - - } - - THREE.STLExporter = STLExporter; - -} )(); diff --git a/examples/js/exporters/USDZExporter.js b/examples/js/exporters/USDZExporter.js deleted file mode 100644 index 1c801098c2d7e2..00000000000000 --- a/examples/js/exporters/USDZExporter.js +++ /dev/null @@ -1,516 +0,0 @@ -( function () { - - class USDZExporter { - - async parse( scene ) { - - const files = {}; - const modelFileName = 'model.usda'; // model file should be first in USDZ archive so we init it here - - files[ modelFileName ] = null; - let output = buildHeader(); - const materials = {}; - const textures = {}; - scene.traverseVisible( object => { - - if ( object.isMesh ) { - - if ( object.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 ); - files[ geometryFileName ] = buildUSDFileAsString( meshObject ); - - } - - if ( ! ( material.uuid in materials ) ) { - - materials[ material.uuid ] = material; - - } - - output += buildXform( object, geometry, material ); - - } else { - - console.warn( 'THREE.USDZExporter: Unsupported material type (USDZ only supports MeshStandardMaterial)', object ); - - } - - } - - } ); - output += buildMaterials( materials, textures ); - files[ modelFileName ] = fflate.strToU8( output ); - output = null; - - for ( const id in textures ) { - - const texture = textures[ id ]; - const color = id.split( '_' )[ 1 ]; - const isRGBA = texture.format === 1023; - const canvas = imageToCanvas( texture.image, color ); - 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 - - - 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; - const padding = new Uint8Array( padLength ); - files[ filename ] = [ file, { - extra: { - 12345: padding - } - } ]; - - } - - offset = file.length; - - } - - return fflate.zipSync( files, { - level: 0 - } ); - - } - - } - - 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 ) { - - const scale = 1024 / Math.max( image.width, image.height ); - const canvas = document.createElement( 'canvas' ); - canvas.width = image.width * Math.min( 1, scale ); - 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 ); - const r = ( hex >> 16 & 255 ) / 255; - const g = ( hex >> 8 & 255 ) / 255; - 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; - data[ i + 1 ] = data[ i + 1 ] * g; - data[ i + 2 ] = data[ i + 2 ] * b; - - } - - context.putImageData( imagedata, 0, 0 ); - - } - - return canvas; - - } - - } // - - - const PRECISION = 7; - - function buildHeader() { - - return `#usda 1.0 -( - customLayerData = { - string creator = "Three.js USDZExporter" - } - metersPerUnit = 1 - upAxis = "Y" -) - -`; - - } - - function buildUSDFileAsString( dataToInsert ) { - - let output = buildHeader(); - output += dataToInsert; - return fflate.strToU8( output ); - - } // 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 ); - - } - - return `def Xform "${name}" ( - prepend references = @./geometries/Geometry_${geometry.id}.usd@ -) -{ - matrix4d xformOp:transform = ${transform} - uniform token[] xformOpOrder = ["xformOp:transform"] - - rel material:binding = -} - -`; - - } - - function buildMatrix( matrix ) { - - const array = matrix.elements; - return `( ${buildMatrixRow( array, 0 )}, ${buildMatrixRow( array, 4 )}, ${buildMatrixRow( array, 8 )}, ${buildMatrixRow( array, 12 )} )`; - - } - - function buildMatrixRow( array, offset ) { - - return `(${array[ offset + 0 ]}, ${array[ offset + 1 ]}, ${array[ offset + 2 ]}, ${array[ offset + 3 ]})`; - - } // Mesh - - - function buildMeshObject( geometry ) { - - const mesh = buildMesh( geometry ); - return ` -def "Geometry" -{ - ${mesh} -} -`; - - } - - function buildMesh( geometry ) { - - const name = 'Geometry'; - const attributes = geometry.attributes; - const count = attributes.position.count; - return ` - def Mesh "${name}" - { - int[] faceVertexCounts = [${buildMeshVertexCount( geometry )}] - int[] faceVertexIndices = [${buildMeshVertexIndices( geometry )}] - normal3f[] normals = [${buildVector3Array( attributes.normal, count )}] ( - interpolation = "vertex" - ) - point3f[] points = [${buildVector3Array( attributes.position, count )}] - float2[] primvars:st = [${buildVector2Array( attributes.uv, count )}] ( - interpolation = "vertex" - ) - uniform token subdivisionScheme = "none" - } -`; - - } - - function buildMeshVertexCount( geometry ) { - - const count = geometry.index !== null ? geometry.index.count : geometry.attributes.position.count; - return Array( count / 3 ).fill( 3 ).join( ', ' ); - - } - - function buildMeshVertexIndices( geometry ) { - - const index = geometry.index; - const array = []; - - if ( index !== null ) { - - for ( let i = 0; i < index.count; i ++ ) { - - array.push( index.getX( i ) ); - - } - - } else { - - const length = geometry.attributes.position.count; - - for ( let i = 0; i < length; i ++ ) { - - array.push( i ); - - } - - } - - return array.join( ', ' ); - - } - - function buildVector3Array( attribute, count ) { - - if ( attribute === undefined ) { - - console.warn( 'USDZExporter: Normals missing.' ); - return Array( count ).fill( '(0, 0, 0)' ).join( ', ' ); - - } - - const array = []; - - for ( let i = 0; i < attribute.count; i ++ ) { - - const x = attribute.getX( i ); - const y = attribute.getY( i ); - const z = attribute.getZ( i ); - array.push( `(${x.toPrecision( PRECISION )}, ${y.toPrecision( PRECISION )}, ${z.toPrecision( PRECISION )})` ); - - } - - return array.join( ', ' ); - - } - - function buildVector2Array( attribute, count ) { - - if ( attribute === undefined ) { - - console.warn( 'USDZExporter: UVs missing.' ); - return Array( count ).fill( '(0, 0)' ).join( ', ' ); - - } - - const array = []; - - for ( let i = 0; i < attribute.count; i ++ ) { - - const x = attribute.getX( i ); - const y = attribute.getY( i ); - array.push( `(${x.toPrecision( PRECISION )}, ${1 - y.toPrecision( PRECISION )})` ); - - } - - return array.join( ', ' ); - - } // Materials - - - function buildMaterials( materials, textures ) { - - const array = []; - - for ( const uuid in materials ) { - - const material = materials[ uuid ]; - array.push( buildMaterial( material, textures ) ); - - } - - return `def "Materials" -{ -${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() : '' ); - const isRGBA = texture.format === 1023; - textures[ id ] = texture; - return ` - def Shader "Transform2d_${mapType}" ( - sdrMetadata = { - string role = "math" - } - ) - { - uniform token info:id = "UsdTransform2d" - float2 inputs:in.connect = - float2 inputs:scale = ${buildVector2( texture.repeat )} - float2 inputs:translation = ${buildVector2( texture.offset )} - float2 outputs:result - } - - def Shader "Texture_${texture.id}_${mapType}" - { - uniform token info:id = "UsdUVTexture" - asset inputs:file = @textures/Texture_${id}.${isRGBA ? 'png' : 'jpg'}@ - float2 inputs:st.connect = - token inputs:wrapS = "repeat" - token inputs:wrapT = "repeat" - float outputs:r - float outputs:g - float outputs:b - float3 outputs:rgb - ${material.transparent || material.alphaTest > 0.0 ? 'float outputs:a' : ''} - }`; - - } - - if ( material.map !== null ) { - - inputs.push( `${pad}color3f inputs:diffuseColor.connect = ` ); - - if ( material.transparent ) { - - inputs.push( `${pad}float inputs:opacity.connect = ` ); - - } else if ( material.alphaTest > 0.0 ) { - - inputs.push( `${pad}float inputs:opacity.connect = ` ); - inputs.push( `${pad}float inputs:opacityThreshold = ${material.alphaTest}` ); - - } - - samplers.push( buildTexture( material.map, 'diffuse', material.color ) ); - - } else { - - inputs.push( `${pad}color3f inputs:diffuseColor = ${buildColor( material.color )}` ); - - } - - if ( material.emissiveMap !== null ) { - - inputs.push( `${pad}color3f inputs:emissiveColor.connect = ` ); - samplers.push( buildTexture( material.emissiveMap, 'emissive' ) ); - - } else if ( material.emissive.getHex() > 0 ) { - - inputs.push( `${pad}color3f inputs:emissiveColor = ${buildColor( material.emissive )}` ); - - } - - if ( material.normalMap !== null ) { - - inputs.push( `${pad}normal3f inputs:normal.connect = ` ); - samplers.push( buildTexture( material.normalMap, 'normal' ) ); - - } - - if ( material.aoMap !== null ) { - - inputs.push( `${pad}float inputs:occlusion.connect = ` ); - samplers.push( buildTexture( material.aoMap, 'occlusion' ) ); - - } - - if ( material.roughnessMap !== null && material.roughness === 1 ) { - - inputs.push( `${pad}float inputs:roughness.connect = ` ); - samplers.push( buildTexture( material.roughnessMap, 'roughness' ) ); - - } else { - - inputs.push( `${pad}float inputs:roughness = ${material.roughness}` ); - - } - - if ( material.metalnessMap !== null && material.metalness === 1 ) { - - inputs.push( `${pad}float inputs:metallic.connect = ` ); - samplers.push( buildTexture( material.metalnessMap, 'metallic' ) ); - - } else { - - inputs.push( `${pad}float inputs:metallic = ${material.metalness}` ); - - } - - if ( material.alphaMap !== null ) { - - inputs.push( `${pad}float inputs:opacity.connect = ` ); - inputs.push( `${pad}float inputs:opacityThreshold = 0.0001` ); - samplers.push( buildTexture( material.alphaMap, 'opacity' ) ); - - } else { - - inputs.push( `${pad}float inputs:opacity = ${material.opacity}` ); - - } - - if ( material.isMeshPhysicalMaterial ) { - - inputs.push( `${pad}float inputs:clearcoat = ${material.clearcoat}` ); - inputs.push( `${pad}float inputs:clearcoatRoughness = ${material.clearcoatRoughness}` ); - inputs.push( `${pad}float inputs:ior = ${material.ior}` ); - - } - - return ` - def Material "Material_${material.id}" - { - def Shader "PreviewSurface" - { - uniform token info:id = "UsdPreviewSurface" -${inputs.join( '\n' )} - int inputs:useSpecularWorkflow = 0 - token outputs:surface - } - - token outputs:surface.connect = - token inputs:frame:stPrimvarName = "st" - - def Shader "uvReader_st" - { - uniform token info:id = "UsdPrimvarReader_float2" - token inputs:varname.connect = - float2 inputs:fallback = (0.0, 0.0) - float2 outputs:result - } - -${samplers.join( '\n' )} - - } -`; - - } - - function buildColor( color ) { - - return `(${color.r}, ${color.g}, ${color.b})`; - - } - - function buildVector2( vector ) { - - return `(${vector.x}, ${vector.y})`; - - } - - THREE.USDZExporter = USDZExporter; - -} )(); diff --git a/examples/js/geometries/BoxLineGeometry.js b/examples/js/geometries/BoxLineGeometry.js deleted file mode 100644 index 97a1ec33407568..00000000000000 --- a/examples/js/geometries/BoxLineGeometry.js +++ /dev/null @@ -1,60 +0,0 @@ -( function () { - - class BoxLineGeometry extends THREE.BufferGeometry { - - constructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) { - - super(); - widthSegments = Math.floor( widthSegments ); - heightSegments = Math.floor( heightSegments ); - depthSegments = Math.floor( depthSegments ); - const widthHalf = width / 2; - const heightHalf = height / 2; - const depthHalf = depth / 2; - const segmentWidth = width / widthSegments; - const segmentHeight = height / heightSegments; - const segmentDepth = depth / depthSegments; - const vertices = []; - let x = - widthHalf; - let y = - heightHalf; - let z = - depthHalf; - - for ( let i = 0; i <= widthSegments; i ++ ) { - - vertices.push( x, - heightHalf, - depthHalf, x, heightHalf, - depthHalf ); - vertices.push( x, heightHalf, - depthHalf, x, heightHalf, depthHalf ); - vertices.push( x, heightHalf, depthHalf, x, - heightHalf, depthHalf ); - vertices.push( x, - heightHalf, depthHalf, x, - heightHalf, - depthHalf ); - x += segmentWidth; - - } - - for ( let i = 0; i <= heightSegments; i ++ ) { - - vertices.push( - widthHalf, y, - depthHalf, widthHalf, y, - depthHalf ); - vertices.push( widthHalf, y, - depthHalf, widthHalf, y, depthHalf ); - vertices.push( widthHalf, y, depthHalf, - widthHalf, y, depthHalf ); - vertices.push( - widthHalf, y, depthHalf, - widthHalf, y, - depthHalf ); - y += segmentHeight; - - } - - for ( let i = 0; i <= depthSegments; i ++ ) { - - vertices.push( - widthHalf, - heightHalf, z, - widthHalf, heightHalf, z ); - vertices.push( - widthHalf, heightHalf, z, widthHalf, heightHalf, z ); - vertices.push( widthHalf, heightHalf, z, widthHalf, - heightHalf, z ); - vertices.push( widthHalf, - heightHalf, z, - widthHalf, - heightHalf, z ); - z += segmentDepth; - - } - - this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - - } - - } - - THREE.BoxLineGeometry = BoxLineGeometry; - -} )(); diff --git a/examples/js/geometries/ConvexGeometry.js b/examples/js/geometries/ConvexGeometry.js deleted file mode 100644 index 42d5be8876ae19..00000000000000 --- a/examples/js/geometries/ConvexGeometry.js +++ /dev/null @@ -1,48 +0,0 @@ -( function () { - - class ConvexGeometry extends THREE.BufferGeometry { - - constructor( points = [] ) { - - super(); // buffers - - const vertices = []; - const normals = []; - - if ( THREE.ConvexHull === undefined ) { - - console.error( 'THREE.ConvexBufferGeometry: ConvexBufferGeometry relies on THREE.ConvexHull' ); - - } - - const convexHull = new THREE.ConvexHull().setFromPoints( points ); // 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) - - do { - - const point = edge.head().point; - vertices.push( point.x, point.y, point.z ); - normals.push( face.normal.x, face.normal.y, face.normal.z ); - edge = edge.next; - - } while ( edge !== face.edge ); - - } // build geometry - - - this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - this.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); - - } - - } - - THREE.ConvexGeometry = ConvexGeometry; - -} )(); diff --git a/examples/js/geometries/DecalGeometry.js b/examples/js/geometries/DecalGeometry.js deleted file mode 100644 index 156f4d638bd25c..00000000000000 --- a/examples/js/geometries/DecalGeometry.js +++ /dev/null @@ -1,291 +0,0 @@ -( function () { - - /** - * You can use this geometry to create a decal mesh, that serves different kinds of purposes. - * e.g. adding unique details to models, performing dynamic visual environmental changes or covering seams. - * - * Constructor parameter: - * - * mesh — Any mesh object - * position — Position of the decal projector - * orientation — Orientation of the decal projector - * size — Size of the decal projector - * - * reference: http://blog.wolfire.com/2009/06/how-to-project-decals/ - * - */ - - class DecalGeometry extends THREE.BufferGeometry { - - constructor( mesh, position, orientation, size ) { - - super(); // buffers - - const vertices = []; - const normals = []; - const uvs = []; // helpers - - 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 - - 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 geometry = mesh.geometry; - const positionAttribute = geometry.attributes.position; - 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 - - if ( geometry.index !== null ) { - - // indexed THREE.BufferGeometry - const index = geometry.index; - - for ( let i = 0; i < index.count; i ++ ) { - - vertex.fromBufferAttribute( positionAttribute, index.getX( i ) ); - normal.fromBufferAttribute( normalAttribute, index.getX( i ) ); - pushDecalVertex( decalVertices, vertex, normal ); - - } - - } else { - - // non-indexed THREE.BufferGeometry - for ( let i = 0; i < positionAttribute.count; i ++ ) { - - vertex.fromBufferAttribute( positionAttribute, i ); - normal.fromBufferAttribute( normalAttribute, i ); - pushDecalVertex( decalVertices, vertex, normal ); - - } - - } // 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 - - for ( let i = 0; i < decalVertices.length; i ++ ) { - - 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 - - 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 ); - - } - - } - - 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 ); - decalVertices.push( new DecalVertex( vertex.clone(), normal.clone() ) ); - - } - - function clipGeometry( inVertices, plane ) { - - const outVertices = []; - 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 ) { - - let total = 0; - let nV1; - let nV2; - let nV3; - let nV4; - const d1 = inVertices[ i + 0 ].position.dot( plane ) - s; - const d2 = inVertices[ i + 1 ].position.dot( plane ) - s; - 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 - - 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 ] ); - break; - - } - - case 1: - { - - // one vertex lies outside of the plane, perform clipping - if ( v1Out ) { - - nV1 = inVertices[ i + 1 ]; - nV2 = inVertices[ i + 2 ]; - nV3 = clip( inVertices[ i ], nV1, plane, s ); - nV4 = clip( inVertices[ i ], nV2, plane, s ); - - } - - if ( v2Out ) { - - nV1 = inVertices[ i ]; - nV2 = inVertices[ i + 2 ]; - nV3 = clip( inVertices[ i + 1 ], nV1, plane, s ); - nV4 = clip( inVertices[ i + 1 ], nV2, plane, s ); - outVertices.push( nV3 ); - outVertices.push( nV2.clone() ); - outVertices.push( nV1.clone() ); - outVertices.push( nV2.clone() ); - outVertices.push( nV3.clone() ); - outVertices.push( nV4 ); - break; - - } - - if ( v3Out ) { - - nV1 = inVertices[ i ]; - nV2 = inVertices[ i + 1 ]; - nV3 = clip( inVertices[ i + 2 ], nV1, plane, s ); - nV4 = clip( inVertices[ i + 2 ], nV2, plane, s ); - - } - - outVertices.push( nV1.clone() ); - outVertices.push( nV2.clone() ); - outVertices.push( nV3 ); - outVertices.push( nV4 ); - outVertices.push( nV3.clone() ); - outVertices.push( nV2.clone() ); - break; - - } - - case 2: - { - - // two vertices lies outside of the plane, perform clipping - if ( ! v1Out ) { - - nV1 = inVertices[ i ].clone(); - nV2 = clip( nV1, inVertices[ i + 1 ], plane, s ); - nV3 = clip( nV1, inVertices[ i + 2 ], plane, s ); - outVertices.push( nV1 ); - outVertices.push( nV2 ); - outVertices.push( nV3 ); - - } - - if ( ! v2Out ) { - - nV1 = inVertices[ i + 1 ].clone(); - nV2 = clip( nV1, inVertices[ i + 2 ], plane, s ); - nV3 = clip( nV1, inVertices[ i ], plane, s ); - outVertices.push( nV1 ); - outVertices.push( nV2 ); - outVertices.push( nV3 ); - - } - - if ( ! v3Out ) { - - nV1 = inVertices[ i + 2 ].clone(); - nV2 = clip( nV1, inVertices[ i ], plane, s ); - nV3 = clip( nV1, inVertices[ i + 1 ], plane, s ); - outVertices.push( nV1 ); - outVertices.push( nV2 ); - outVertices.push( nV3 ); - - } - - break; - - } - - case 3: - { - - // the entire face lies outside of the plane, so let's discard the corresponding vertices - break; - - } - - } - - } - - return outVertices; - - } - - function clip( v0, v1, p, s ) { - - 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: - // intersectpoint.value = a.value + s * ( b.value - a.value ); - - return v; - - } - - } - - } // helper - - - class DecalVertex { - - constructor( position, normal ) { - - this.position = position; - this.normal = normal; - - } - - clone() { - - return new this.constructor( this.position.clone(), this.normal.clone() ); - - } - - } - - THREE.DecalGeometry = DecalGeometry; - THREE.DecalVertex = DecalVertex; - -} )(); diff --git a/examples/js/geometries/LightningStrike.js b/examples/js/geometries/LightningStrike.js deleted file mode 100644 index 0a3f2c347f90d4..00000000000000 --- a/examples/js/geometries/LightningStrike.js +++ /dev/null @@ -1,874 +0,0 @@ -( function () { - - /** - * @fileoverview LightningStrike object for creating lightning strikes and voltaic arcs. - * - * - * Usage - * - * var myRay = new LightningStrike( paramsObject ); - * var myRayMesh = new THREE.Mesh( myRay, myMaterial ); - * scene.add( myRayMesh ); - * ... - * myRay.update( currentTime ); - * - * The "currentTime" can vary its rate, go forwards, backwards or even jump, but it cannot be negative. - * - * You should normally leave the ray position to (0, 0, 0). You should control it by changing the sourceOffset and destOffset parameters. - * - * - * LightningStrike parameters - * - * The paramsObject can contain any of the following parameters. - * - * Legend: - * 'LightningStrike' (also called 'ray'): An independent voltaic arc with its ramifications and defined with a set of parameters. - * 'Subray': A ramification of the ray. It is not a LightningStrike object. - * 'Segment': A linear segment piece of a subray. - * 'Leaf segment': A ray segment which cannot be smaller. - * - * - * The following parameters can be changed any time and if they vary smoothly, the ray form will also change smoothly: - * - * @param {Vector3} sourceOffset The point where the ray starts. - * - * @param {Vector3} destOffset The point where the ray ends. - * - * @param {double} timeScale The rate at wich the ray form changes in time. Default: 1 - * - * @param {double} roughness From 0 to 1. The higher the value, the more wrinkled is the ray. Default: 0.9 - * - * @param {double} straightness From 0 to 1. The higher the value, the more straight will be a subray path. Default: 0.7 - * - * @param {Vector3} up0 Ray 'up' direction at the ray starting point. Must be normalized. It should be perpendicular to the ray forward direction but it doesn't matter much. - * - * @param {Vector3} up1 Like the up0 parameter but at the end of the ray. Must be normalized. - * - * @param {double} radius0 Radius of the main ray trunk at the start point. Default: 1 - * - * @param {double} radius1 Radius of the main ray trunk at the end point. Default: 1 - * - * @param {double} radius0Factor The radius0 of a subray is this factor times the radius0 of its parent subray. Default: 0.5 - * - * @param {double} radius1Factor The radius1 of a subray is this factor times the radius1 of its parent subray. Default: 0.2 - * - * @param {minRadius} Minimum value a subray radius0 or radius1 can get. Default: 0.1 - * - * - * The following parameters should not be changed after lightning creation. They can be changed but the ray will change its form abruptly: - * - * @param {boolean} isEternal If true the ray never extinguishes. Otherwise its life is controlled by the 'birthTime' and 'deathTime' parameters. Default: true if any of those two parameters is undefined. - * - * @param {double} birthTime The time at which the ray starts its life and begins propagating. Only if isEternal is false. Default: None. - * - * @param {double} deathTime The time at which the ray ends vanishing and its life. Only if isEternal is false. Default: None. - * - * @param {double} propagationTimeFactor From 0 to 1. Lifetime factor at which the ray ends propagating and enters the steady phase. For example, 0.1 means it is propagating 1/10 of its lifetime. Default: 0.1 - * - * @param {double} vanishingTimeFactor From 0 to 1. Lifetime factor at which the ray ends the steady phase and begins vanishing. For example, 0.9 means it is vanishing 1/10 of its lifetime. Default: 0.9 - * - * @param {double} subrayPeriod Subrays cycle periodically. This is their time period. Default: 4 - * - * @param {double} subrayDutyCycle From 0 to 1. This is the fraction of time a subray is active. Default: 0.6 - * - * - * These parameters cannot change after lightning creation: - * - * @param {integer} maxIterations: Greater than 0. The number of ray's leaf segments is 2**maxIterations. Default: 9 - * - * @param {boolean} isStatic Set to true only for rays which won't change over time and are not attached to moving objects (Rare case). It is used to set the vertex buffers non-dynamic. You can omit calling update() for these rays. - * - * @param {integer} ramification Greater than 0. Maximum number of child subrays a subray can have. Default: 5 - * - * @param {integer} maxSubrayRecursion Greater than 0. Maximum level of recursion (subray descendant generations). Default: 3 - * - * @param {double} recursionProbability From 0 to 1. The lower the value, the less chance each new generation of subrays has to generate new subrays. Default: 0.6 - * - * @param {boolean} generateUVs If true, the ray geometry will have uv coordinates generated. u runs along the ray, and v across its perimeter. Default: false. - * - * @param {Object} randomGenerator Set here your random number generator which will seed the THREE.SimplexNoise and other decisions during ray tree creation. - * It can be used to generate repeatable rays. For that, set also the noiseSeed parameter, and each ray created with that generator and seed pair will be identical in time. - * The randomGenerator parameter should be an object with a random() function similar to Math.random, but seedable. - * It must have also a getSeed() method, which returns the current seed, and a setSeed( seed ) method, which accepts as seed a fractional number from 0 to 1, as well as any other number. - * The default value is an internal generator for some uses and Math.random for others (It is non-repeatable even if noiseSeed is supplied) - * - * @param {double} noiseSeed Seed used to make repeatable rays (see the randomGenerator) - * - * @param {function} onDecideSubrayCreation Set this to change the callback which decides subray creation. You can look at the default callback in the code (createDefaultSubrayCreationCallbacks)for more info. - * - * @param {function} onSubrayCreation This is another callback, more simple than the previous one. It can be used to adapt the form of subrays or other parameters once a subray has been created and initialized. It is used in the examples to adapt subrays to a sphere or to a plane. - * - * -*/ - - class LightningStrike extends THREE.BufferGeometry { - - constructor( rayParameters = {} ) { - - super(); - this.isLightningStrike = true; - this.type = 'LightningStrike'; // 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() ); - - } - - const generator = { - currentSeed: 0, - random: function () { - - const value = seeds[ generator.currentSeed ]; - generator.currentSeed = ( generator.currentSeed + 1 ) % numSeeds; - return value; - - }, - getSeed: function () { - - return generator.currentSeed / numSeeds; - - }, - setSeed: function ( seed ) { - - generator.currentSeed = Math.floor( seed * numSeeds ) % numSeeds; - - } - }; - return generator; - - } - - static copyParameters( dest = {}, source = {} ) { - - const vecCopy = function ( v ) { - - if ( source === dest ) { - - return v; - - } else { - - return v.clone(); - - } - - }; - - 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.maxIterations = source.maxIterations !== undefined ? source.maxIterations : 9; - dest.isStatic = source.isStatic !== undefined ? source.isStatic : false; - dest.ramification = source.ramification !== undefined ? source.ramification : 5; - dest.maxSubrayRecursion = source.maxSubrayRecursion !== undefined ? source.maxSubrayRecursion : 3; - dest.recursionProbability = source.recursionProbability !== undefined ? source.recursionProbability : 0.6; - dest.generateUVs = source.generateUVs !== undefined ? source.generateUVs : false; - dest.randomGenerator = source.randomGenerator, dest.noiseSeed = source.noiseSeed, dest.onDecideSubrayCreation = source.onDecideSubrayCreation, dest.onSubrayCreation = source.onSubrayCreation; - 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; - - } else if ( time > this.subrays[ 0 ].beginVanishingTime ) { - - this.state = LightningStrike.RAY_VANISHING; - - } else { - - this.state = LightningStrike.RAY_STEADY; - - } - - this.visible = true; - - } else { - - this.visible = false; - - if ( time < this.rayParameters.birthTime ) { - - this.state = LightningStrike.RAY_UNBORN; - - } else { - - this.state = LightningStrike.RAY_EXTINGUISHED; - - } - - } - - } - - init( rayParameters ) { - - // Init all the state from the parameters - this.rayParameters = rayParameters; // These parameters cannot change after lightning creation: - - this.maxIterations = rayParameters.maxIterations !== undefined ? Math.floor( rayParameters.maxIterations ) : 9; - rayParameters.maxIterations = this.maxIterations; - this.isStatic = rayParameters.isStatic !== undefined ? rayParameters.isStatic : false; - rayParameters.isStatic = this.isStatic; - this.ramification = rayParameters.ramification !== undefined ? Math.floor( rayParameters.ramification ) : 5; - rayParameters.ramification = this.ramification; - this.maxSubrayRecursion = rayParameters.maxSubrayRecursion !== undefined ? Math.floor( rayParameters.maxSubrayRecursion ) : 3; - rayParameters.maxSubrayRecursion = this.maxSubrayRecursion; - 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 - - if ( rayParameters.randomGenerator !== undefined ) { - - this.randomGenerator = rayParameters.randomGenerator; - this.seedGenerator = rayParameters.randomGenerator; - - if ( rayParameters.noiseSeed !== undefined ) { - - this.seedGenerator.setSeed( rayParameters.noiseSeed ); - - } - - } else { - - this.randomGenerator = LightningStrike.createRandomGenerator(); - this.seedGenerator = Math; - - } // Ray creation callbacks - - - if ( rayParameters.onDecideSubrayCreation !== undefined ) { - - this.onDecideSubrayCreation = rayParameters.onDecideSubrayCreation; - - } else { - - this.createDefaultSubrayCreationCallbacks(); - - if ( rayParameters.onSubrayCreation !== undefined ) { - - this.onSubrayCreation = rayParameters.onSubrayCreation; - - } - - } // 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() ); - - } - - this.raySegments = []; - - for ( let i = 0; i < this.maxRaySegments; i ++ ) { - - this.raySegments.push( this.createSegment() ); - - } - - this.time = 0; - this.timeFraction = 0; - this.currentSegmentCallback = null; - this.currentCreateTriangleVertices = this.generateUVs ? this.createTriangleVerticesWithUVs : this.createTriangleVerticesWithoutUVs; - this.numSubrays = 0; - this.currentSubray = null; - this.currentSegmentIndex = 0; - this.isInitialSegment = false; - this.subrayProbability = 0; - this.currentVertex = 0; - this.currentIndex = 0; - this.currentCoordinate = 0; - this.currentUVCoordinate = 0; - this.vertices = null; - this.uvs = null; - this.indices = null; - this.positionAttribute = null; - 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.forwards = new THREE.Vector3(); - this.forwardsFill = new THREE.Vector3(); - this.side = new THREE.Vector3(); - this.down = new THREE.Vector3(); - this.middlePos = new THREE.Vector3(); - this.middleLinPos = new THREE.Vector3(); - this.newPos = new THREE.Vector3(); - this.vPos = new THREE.Vector3(); - this.cross1 = new THREE.Vector3(); - - } - - createMesh() { - - const maxDrawableSegmentsPerSubRay = 1 << this.maxIterations; - const maxVerts = 3 * ( maxDrawableSegmentsPerSubRay + 1 ) * this.maxSubrays; - 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 - - - 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 ); - this.setAttribute( 'uv', this.uvsAttribute ); - - } - - if ( ! this.isStatic ) { - - this.index.usage = THREE.DynamicDrawUsage; - this.positionAttribute.usage = THREE.DynamicDrawUsage; - - if ( this.generateUVs ) { - - this.uvsAttribute.usage = THREE.DynamicDrawUsage; - - } - - } // Store buffers for later modification - - - this.vertices = this.positionAttribute.array; - this.indices = this.index.array; - - if ( this.generateUVs ) { - - this.uvs = this.uvsAttribute.array; - - } - - } - - 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; - - } - - } - - fillMesh( time ) { - - const scope = this; - this.currentVertex = 0; - this.currentIndex = 0; - this.currentCoordinate = 0; - this.currentUVCoordinate = 0; - 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 ); - - } else if ( time < subray.endPropagationTime ) { - - if ( scope.timeFraction >= segment.fraction0 * subray.propagationTimeFactor ) { - - // Ray propagation has arrived to this segment - scope.createPrism( segment ); - scope.onDecideSubrayCreation( segment, scope ); - - } - - } else if ( time < subray.beginVanishingTime ) { - - // Ray is steady (nor propagating nor vanishing) - scope.createPrism( segment ); - scope.onDecideSubrayCreation( segment, scope ); - - } else { - - if ( scope.timeFraction <= subray.vanishingTimeFactor + segment.fraction1 * ( 1 - subray.vanishingTimeFactor ) ) { - - // Segment has not yet vanished - scope.createPrism( segment ); - - } - - scope.onDecideSubrayCreation( segment, scope ); - - } - - } ); - - } - - addNewSubray() { - - return this.subrays[ this.numSubrays ++ ]; - - } - - initSubray( subray, rayParameters ) { - - subray.pos0.copy( rayParameters.sourceOffset ); - subray.pos1.copy( rayParameters.destOffset ); - subray.up0.copy( rayParameters.up0 ); - subray.up1.copy( rayParameters.up1 ); - subray.radius0 = rayParameters.radius0; - subray.radius1 = rayParameters.radius1; - subray.birthTime = rayParameters.birthTime; - subray.deathTime = rayParameters.deathTime; - subray.timeScale = rayParameters.timeScale; - subray.roughness = rayParameters.roughness; - subray.straightness = rayParameters.straightness; - subray.propagationTimeFactor = rayParameters.propagationTimeFactor; - subray.vanishingTimeFactor = rayParameters.vanishingTimeFactor; - subray.maxIterations = this.maxIterations; - subray.seed = rayParameters.noiseSeed !== undefined ? rayParameters.noiseSeed : 0; - subray.recursion = 0; - - } - - fractalRay( time, segmentCallback ) { - - this.time = time; - this.currentSegmentCallback = segmentCallback; - this.numSubrays = 0; // 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 ]; - this.currentSubray = subray; - this.randomGenerator.setSeed( subray.seed ); - subray.endPropagationTime = THREE.MathUtils.lerp( subray.birthTime, subray.deathTime, subray.propagationTimeFactor ); - subray.beginVanishingTime = THREE.MathUtils.lerp( subray.deathTime, subray.birthTime, 1 - subray.vanishingTimeFactor ); - const random1 = this.randomGenerator.random; - subray.linPos0.set( random1(), random1(), random1() ).multiplyScalar( 1000 ); - subray.linPos1.set( random1(), random1(), random1() ).multiplyScalar( 1000 ); - this.timeFraction = ( time - subray.birthTime ) / ( subray.deathTime - subray.birthTime ); - this.currentSegmentIndex = 0; - this.isInitialSegment = true; - const segment = this.getNewSegment(); - segment.iteration = 0; - segment.pos0.copy( subray.pos0 ); - segment.pos1.copy( subray.pos1 ); - segment.linPos0.copy( subray.linPos0 ); - segment.linPos1.copy( subray.linPos1 ); - segment.up0.copy( subray.up0 ); - segment.up1.copy( subray.up1 ); - segment.radius0 = subray.radius0; - segment.radius1 = subray.radius1; - segment.fraction0 = 0; - segment.fraction1 = 1; - segment.positionVariationFactor = 1 - subray.straightness; - this.subrayProbability = this.ramification * Math.pow( this.recursionProbability, subray.recursion ) / ( 1 << subray.maxIterations ); - this.fractalRayRecursive( segment ); - - } - - this.currentSegmentCallback = null; - this.currentSubray = null; - - } - - fractalRayRecursive( segment ) { - - // Leave recursion condition - if ( segment.iteration >= this.currentSubray.maxIterations ) { - - this.currentSegmentCallback( segment ); - return; - - } // Interpolation - - - this.forwards.subVectors( segment.pos1, segment.pos0 ); - let lForwards = this.forwards.length(); - - if ( lForwards < 0.000001 ) { - - this.forwards.set( 0, 0, 0.01 ); - lForwards = this.forwards.length(); - - } - - const middleRadius = ( segment.radius0 + segment.radius1 ) * 0.5; - const middleFraction = ( segment.fraction0 + segment.fraction1 ) * 0.5; - 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 - - 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 - - const newSegment1 = this.getNewSegment(); - newSegment1.pos0.copy( segment.pos0 ); - newSegment1.pos1.copy( this.newPos ); - newSegment1.linPos0.copy( segment.linPos0 ); - newSegment1.linPos1.copy( this.middleLinPos ); - newSegment1.up0.copy( segment.up0 ); - newSegment1.up1.copy( segment.up1 ); - newSegment1.radius0 = segment.radius0; - newSegment1.radius1 = middleRadius; - newSegment1.fraction0 = segment.fraction0; - newSegment1.fraction1 = middleFraction; - newSegment1.positionVariationFactor = segment.positionVariationFactor * this.currentSubray.roughness; - newSegment1.iteration = segment.iteration + 1; - const newSegment2 = this.getNewSegment(); - newSegment2.pos0.copy( this.newPos ); - newSegment2.pos1.copy( segment.pos1 ); - newSegment2.linPos0.copy( this.middleLinPos ); - newSegment2.linPos1.copy( segment.linPos1 ); - this.cross1.crossVectors( segment.up0, this.forwards.normalize() ); - newSegment2.up0.crossVectors( this.forwards, this.cross1 ).normalize(); - newSegment2.up1.copy( segment.up1 ); - newSegment2.radius0 = middleRadius; - newSegment2.radius1 = segment.radius1; - newSegment2.fraction0 = middleFraction; - newSegment2.fraction1 = segment.fraction1; - newSegment2.positionVariationFactor = segment.positionVariationFactor * this.currentSubray.roughness; - newSegment2.iteration = segment.iteration + 1; - this.fractalRayRecursive( newSegment1 ); - this.fractalRayRecursive( newSegment2 ); - - } - - createPrism( segment ) { - - // Creates one triangular prism and its vertices at the segment - this.forwardsFill.subVectors( segment.pos1, segment.pos0 ).normalize(); - - if ( this.isInitialSegment ) { - - this.currentCreateTriangleVertices( segment.pos0, segment.up0, this.forwardsFill, segment.radius0, 0 ); - this.isInitialSegment = false; - - } - - this.currentCreateTriangleVertices( segment.pos1, segment.up0, this.forwardsFill, segment.radius1, segment.fraction1 ); - 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; - const v = this.vertices; - p.copy( pos ).sub( this.side ).add( this.down ); - v[ this.currentCoordinate ++ ] = p.x; - v[ this.currentCoordinate ++ ] = p.y; - v[ this.currentCoordinate ++ ] = p.z; - p.copy( pos ).add( this.side ).add( this.down ); - v[ this.currentCoordinate ++ ] = p.x; - v[ this.currentCoordinate ++ ] = p.y; - v[ this.currentCoordinate ++ ] = p.z; - p.copy( up ).multiplyScalar( radius ).add( pos ); - v[ this.currentCoordinate ++ ] = p.x; - v[ this.currentCoordinate ++ ] = p.y; - v[ this.currentCoordinate ++ ] = p.z; - 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; - const v = this.vertices; - const uv = this.uvs; - p.copy( pos ).sub( this.side ).add( this.down ); - v[ this.currentCoordinate ++ ] = p.x; - v[ this.currentCoordinate ++ ] = p.y; - v[ this.currentCoordinate ++ ] = p.z; - uv[ this.currentUVCoordinate ++ ] = u; - uv[ this.currentUVCoordinate ++ ] = 0; - p.copy( pos ).add( this.side ).add( this.down ); - v[ this.currentCoordinate ++ ] = p.x; - v[ this.currentCoordinate ++ ] = p.y; - v[ this.currentCoordinate ++ ] = p.z; - uv[ this.currentUVCoordinate ++ ] = u; - uv[ this.currentUVCoordinate ++ ] = 0.5; - p.copy( up ).multiplyScalar( radius ).add( pos ); - v[ this.currentCoordinate ++ ] = p.x; - v[ this.currentCoordinate ++ ] = p.y; - v[ this.currentCoordinate ++ ] = p.z; - uv[ this.currentUVCoordinate ++ ] = u; - uv[ this.currentUVCoordinate ++ ] = 1; - this.currentVertex += 3; - - } - - createPrismFaces( vertex - /*, index*/ - ) { - - const indices = this.indices; - vertex = this.currentVertex - 6; - indices[ this.currentIndex ++ ] = vertex + 1; - indices[ this.currentIndex ++ ] = vertex + 2; - indices[ this.currentIndex ++ ] = vertex + 5; - indices[ this.currentIndex ++ ] = vertex + 1; - indices[ this.currentIndex ++ ] = vertex + 5; - indices[ this.currentIndex ++ ] = vertex + 4; - indices[ this.currentIndex ++ ] = vertex + 0; - indices[ this.currentIndex ++ ] = vertex + 1; - indices[ this.currentIndex ++ ] = vertex + 4; - indices[ this.currentIndex ++ ] = vertex + 0; - indices[ this.currentIndex ++ ] = vertex + 4; - indices[ this.currentIndex ++ ] = vertex + 3; - indices[ this.currentIndex ++ ] = vertex + 2; - indices[ this.currentIndex ++ ] = vertex + 0; - indices[ this.currentIndex ++ ] = vertex + 3; - indices[ this.currentIndex ++ ] = vertex + 2; - indices[ this.currentIndex ++ ] = vertex + 3; - 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; - const phase0 = lightningStrike.rayParameters.isEternal && subray.recursion == 0 ? - random1() * period : THREE.MathUtils.lerp( subray.birthTime, subray.endPropagationTime, segment.fraction0 ) - random1() * period; - const phase = lightningStrike.time - phase0; - const currentCycle = Math.floor( phase / period ); - 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; - - } - - if ( subray.recursion < lightningStrike.maxSubrayRecursion && lightningStrike.numSubrays < lightningStrike.maxSubrays && random1() < probability ) { - - const childSubray = lightningStrike.addNewSubray(); - const parentSeed = lightningStrike.randomGenerator.getSeed(); - childSubray.seed = childSubraySeed; - lightningStrike.randomGenerator.setSeed( childSubraySeed ); - childSubray.recursion = subray.recursion + 1; - childSubray.maxIterations = Math.max( 1, subray.maxIterations - 1 ); - childSubray.linPos0.set( random1(), random1(), random1() ).multiplyScalar( 1000 ); - childSubray.linPos1.set( random1(), random1(), random1() ).multiplyScalar( 1000 ); - childSubray.up0.copy( subray.up0 ); - childSubray.up1.copy( subray.up1 ); - childSubray.radius0 = segment.radius0 * lightningStrike.rayParameters.radius0Factor; - 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 ); - childSubray.deathTime = Math.min( childSubray.deathTime, subray.deathTime ); - - } - - childSubray.timeScale = subray.timeScale * 2; - childSubray.roughness = subray.roughness; - childSubray.straightness = subray.straightness; - childSubray.propagationTimeFactor = subray.propagationTimeFactor; - childSubray.vanishingTimeFactor = subray.vanishingTimeFactor; - lightningStrike.onSubrayCreation( segment, subray, childSubray, lightningStrike ); - lightningStrike.randomGenerator.setSeed( parentSeed ); - - } - - }; - - const vec1Pos = new THREE.Vector3(); - 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 ); - - }; - - 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(); - vec1Pos.multiplyScalar( segment.fraction0 + ( 1 - segment.fraction0 ) * ( random1() * heightFactor ) ); - const length = vec1Pos.length(); - vec3Side.crossVectors( parentSubray.up0, vec2Forward ); - const angle = 2 * Math.PI * random1(); - vec3Side.multiplyScalar( Math.cos( angle ) ); - vec4Up.copy( parentSubray.up0 ).multiplyScalar( Math.sin( angle ) ); - childSubray.pos1.copy( vec3Side ).add( vec4Up ).multiplyScalar( length * sideWidthFactor * ( minSideWidthFactor + random1() * ( 1 - minSideWidthFactor ) ) ).add( vec1Pos ).add( parentSubray.pos0 ); - - }; - - 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(); - vec1Pos.multiplyScalar( segment.fraction0 + ( 1 - segment.fraction0 ) * ( ( 2 * random1() - 1 ) * heightFactor ) ); - const length = vec1Pos.length(); - vec3Side.crossVectors( parentSubray.up0, vec2Forward ); - const angle = 2 * Math.PI * random1(); - vec3Side.multiplyScalar( Math.cos( angle ) ); - vec4Up.copy( parentSubray.up0 ).multiplyScalar( Math.sin( angle ) ); - childSubray.pos1.copy( vec3Side ).add( vec4Up ).multiplyScalar( length * sideWidthFactor * ( minSideWidthFactor + random1() * ( 1 - minSideWidthFactor ) ) ).add( vec1Pos ).add( parentSubray.pos0 ); - - }; - - } - - createSubray() { - - return { - seed: 0, - maxIterations: 0, - recursion: 0, - pos0: new THREE.Vector3(), - pos1: new THREE.Vector3(), - linPos0: new THREE.Vector3(), - linPos1: new THREE.Vector3(), - up0: new THREE.Vector3(), - up1: new THREE.Vector3(), - radius0: 0, - radius1: 0, - birthTime: 0, - deathTime: 0, - timeScale: 0, - roughness: 0, - straightness: 0, - propagationTimeFactor: 0, - vanishingTimeFactor: 0, - endPropagationTime: 0, - beginVanishingTime: 0 - }; - - } - - createSegment() { - - return { - iteration: 0, - pos0: new THREE.Vector3(), - pos1: new THREE.Vector3(), - linPos0: new THREE.Vector3(), - linPos1: new THREE.Vector3(), - up0: new THREE.Vector3(), - up1: new THREE.Vector3(), - radius0: 0, - radius1: 0, - fraction0: 0, - fraction1: 0, - positionVariationFactor: 0 - }; - - } - - getNewSegment() { - - return this.raySegments[ this.currentSegmentIndex ++ ]; - - } - - copy( source ) { - - super.copy( source ); - this.init( LightningStrike.copyParameters( {}, source.rayParameters ) ); - return this; - - } - - clone() { - - return new this.constructor( LightningStrike.copyParameters( {}, this.rayParameters ) ); - - } - - } // Ray states - - - LightningStrike.RAY_INITIALIZED = 0; - LightningStrike.RAY_UNBORN = 1; - LightningStrike.RAY_PROPAGATING = 2; - LightningStrike.RAY_STEADY = 3; - LightningStrike.RAY_VANISHING = 4; - LightningStrike.RAY_EXTINGUISHED = 5; - LightningStrike.COS30DEG = Math.cos( 30 * Math.PI / 180 ); - LightningStrike.SIN30DEG = Math.sin( 30 * Math.PI / 180 ); - - THREE.LightningStrike = LightningStrike; - -} )(); diff --git a/examples/js/geometries/ParametricGeometries.js b/examples/js/geometries/ParametricGeometries.js deleted file mode 100644 index 5791c3cdab6ac5..00000000000000 --- a/examples/js/geometries/ParametricGeometries.js +++ /dev/null @@ -1,215 +0,0 @@ -( function () { - - /** - * Experimenting of primitive geometry creation using Surface Parametric equations - */ - - const ParametricGeometries = { - klein: function ( v, u, target ) { - - u *= Math.PI; - 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 ); - z = - 8 * Math.sin( u ) - 2 * ( 1 - Math.cos( u ) / 2 ) * Math.sin( u ) * Math.cos( v ); - - } else { - - x = 3 * Math.cos( u ) * ( 1 + Math.sin( u ) ) + 2 * ( 1 - Math.cos( u ) / 2 ) * Math.cos( v + Math.PI ); - z = - 8 * Math.sin( u ); - - } - - const y = - 2 * ( 1 - Math.cos( u ) / 2 ) * Math.sin( v ); - target.set( x, y, z ); - - }, - plane: function ( width, height ) { - - return function ( u, v, target ) { - - const x = u * width; - const y = 0; - const z = v * height; - target.set( x, y, z ); - - }; - - }, - mobius: function ( u, t, target ) { - - // flat mobius strip - // http://www.wolframalpha.com/input/?i=M%C3%B6bius+strip+parametric+equations&lk=1&a=ClashPrefs_*Surface.MoebiusStrip.SurfaceProperty.ParametricEquations- - u = u - 0.5; - const v = 2 * Math.PI * t; - const a = 2; - const x = Math.cos( v ) * ( a + u * Math.cos( v / 2 ) ); - const y = Math.sin( v ) * ( a + u * Math.cos( v / 2 ) ); - const z = u * Math.sin( v / 2 ); - target.set( x, y, z ); - - }, - mobius3d: function ( u, t, target ) { - - // volumetric mobius strip - u *= Math.PI; - t *= 2 * Math.PI; - u = u * 2; - const phi = u / 2; - const major = 2.25, - a = 0.125, - b = 0.65; - let x = a * Math.cos( t ) * Math.cos( phi ) - b * Math.sin( t ) * Math.sin( phi ); - const z = a * Math.cos( t ) * Math.sin( phi ) + b * Math.sin( t ) * Math.cos( phi ); - const y = ( major + x ) * Math.sin( u ); - x = ( major + x ) * Math.cos( u ); - target.set( x, y, z ); - - } - }; - /********************************************* - * - * Parametric Replacement for TubeGeometry - * - *********************************************/ - - ParametricGeometries.TubeGeometry = class TubeGeometry extends THREE.ParametricGeometry { - - constructor( path, segments = 64, radius = 1, segmentsRadius = 8, closed = false ) { - - const numpoints = segments + 1; - const frames = path.computeFrenetFrames( segments, closed ), - tangents = frames.tangents, - normals = frames.normals, - binormals = frames.binormals; - const position = new THREE.Vector3(); - - function ParametricTube( u, v, target ) { - - v *= 2 * Math.PI; - const i = Math.floor( u * ( numpoints - 1 ) ); - path.getPointAt( u, position ); - 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; - position.z += cx * normal.z + cy * binormal.z; - target.copy( position ); - - } - - super( ParametricTube, segments, segmentsRadius ); // proxy internals - - this.tangents = tangents; - this.normals = normals; - this.binormals = binormals; - this.path = path; - this.segments = segments; - this.radius = radius; - this.segmentsRadius = segmentsRadius; - this.closed = closed; - - } - - }; - /********************************************* - * - * Parametric Replacement for TorusKnotGeometry - * - *********************************************/ - - ParametricGeometries.TorusKnotGeometry = class TorusKnotGeometry extends ParametricGeometries.TubeGeometry { - - constructor( radius = 200, tube = 40, segmentsT = 64, segmentsR = 8, p = 2, q = 3 ) { - - class TorusKnotCurve extends THREE.Curve { - - getPoint( t, optionalTarget = new THREE.Vector3() ) { - - const point = optionalTarget; - t *= Math.PI * 2; - const r = 0.5; - const x = ( 1 + r * Math.cos( q * t ) ) * Math.cos( p * t ); - const y = ( 1 + r * Math.cos( q * t ) ) * Math.sin( p * t ); - const z = r * Math.sin( q * t ); - return point.set( x, y, z ).multiplyScalar( radius ); - - } - - } - - const segments = segmentsT; - const radiusSegments = segmentsR; - const extrudePath = new TorusKnotCurve(); - super( extrudePath, segments, tube, radiusSegments, true, false ); - this.radius = radius; - this.tube = tube; - this.segmentsT = segmentsT; - this.segmentsR = segmentsR; - this.p = p; - this.q = q; - - } - - }; - /********************************************* - * - * Parametric Replacement for SphereGeometry - * - *********************************************/ - - ParametricGeometries.SphereGeometry = class SphereGeometry extends THREE.ParametricGeometry { - - constructor( size, u, v ) { - - function sphere( u, v, target ) { - - u *= Math.PI; - v *= 2 * Math.PI; - const x = size * Math.sin( u ) * Math.cos( v ); - const y = size * Math.sin( u ) * Math.sin( v ); - const z = size * Math.cos( u ); - target.set( x, y, z ); - - } - - super( sphere, u, v ); - - } - - }; - /********************************************* - * - * Parametric Replacement for PlaneGeometry - * - *********************************************/ - - ParametricGeometries.PlaneGeometry = class PlaneGeometry extends THREE.ParametricGeometry { - - constructor( width, depth, segmentsWidth, segmentsDepth ) { - - function plane( u, v, target ) { - - const x = u * width; - const y = 0; - const z = v * depth; - target.set( x, y, z ); - - } - - super( plane, segmentsWidth, segmentsDepth ); - - } - - }; - - THREE.ParametricGeometries = ParametricGeometries; - -} )(); diff --git a/examples/js/geometries/ParametricGeometry.js b/examples/js/geometries/ParametricGeometry.js deleted file mode 100644 index d7ccc4a1b603c3..00000000000000 --- a/examples/js/geometries/ParametricGeometry.js +++ /dev/null @@ -1,115 +0,0 @@ -( function () { - - /** - * 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 ) { - - super(); - this.type = 'ParametricGeometry'; - this.parameters = { - func: func, - slices: slices, - stacks: stacks - }; // buffers - - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; - const EPS = 0.00001; - const normal = new THREE.Vector3(); - const p0 = new THREE.Vector3(), - p1 = new THREE.Vector3(); - 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 - - - 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 - - func( u, v, p0 ); - vertices.push( p0.x, p0.y, p0.z ); // normal - // approximate tangent vectors via finite differences - - if ( u - EPS >= 0 ) { - - func( u - EPS, v, p1 ); - pu.subVectors( p0, p1 ); - - } else { - - func( u + EPS, v, p1 ); - pu.subVectors( p1, p0 ); - - } - - if ( v - EPS >= 0 ) { - - func( u, v - EPS, p1 ); - pv.subVectors( p0, p1 ); - - } else { - - func( u, v + EPS, p1 ); - pv.subVectors( p1, p0 ); - - } // cross product of tangent vectors returns surface normal - - - normal.crossVectors( pu, pv ).normalize(); - normals.push( normal.x, normal.y, normal.z ); // uv - - uvs.push( u, v ); - - } - - } // generate indices - - - for ( let i = 0; i < stacks; i ++ ) { - - for ( let j = 0; j < slices; j ++ ) { - - 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 - - indices.push( a, b, d ); - indices.push( b, c, d ); - - } - - } // build geometry - - - this.setIndex( indices ); - this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - this.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); - this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); - - } - - } - - THREE.ParametricGeometry = ParametricGeometry; - -} )(); diff --git a/examples/js/geometries/RoundedBoxGeometry.js b/examples/js/geometries/RoundedBoxGeometry.js deleted file mode 100644 index 883cea47bc0041..00000000000000 --- a/examples/js/geometries/RoundedBoxGeometry.js +++ /dev/null @@ -1,140 +0,0 @@ -( 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 centerLength = Math.max( sideLength - 2 * radius, 0 ); - const halfArc = Math.PI / 4; // Get the vector projected onto the Y plane - - _tempNormal.copy( normal ); - - _tempNormal[ projectionAxis ] = 0; - - _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 - - const arcAngleRatio = 1.0 - _tempNormal.angleTo( faceDirVector ) / halfArc; - - if ( Math.sign( _tempNormal[ uvAxis ] ) === 1 ) { - - return arcAngleRatio * arcUvRatio; - - } else { - - // total amount of UV space alloted to the plane between the arcs - const lenUv = centerLength / ( totArcLength + centerLength ); - return lenUv + arcUvRatio + arcUvRatio * ( 1.0 - arcAngleRatio ); - - } - - } - - class RoundedBoxGeometry extends THREE.BoxGeometry { - - 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 - - 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 - - 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; // - - const position = new THREE.Vector3(); - const normal = new THREE.Vector3(); - const box = new THREE.Vector3( width, height, depth ).divideScalar( 2 ).subScalar( radius ); - const positions = this.attributes.position.array; - const normals = this.attributes.normal.array; - const uvs = this.attributes.uv.array; - 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 ); - normal.copy( position ); - normal.x -= Math.sign( normal.x ) * halfSegmentSize; - normal.y -= Math.sign( normal.y ) * halfSegmentSize; - normal.z -= Math.sign( normal.z ) * halfSegmentSize; - normal.normalize(); - positions[ i + 0 ] = box.x * Math.sign( position.x ) + normal.x * radius; - positions[ i + 1 ] = box.y * Math.sign( position.y ) + normal.y * radius; - positions[ i + 2 ] = box.z * Math.sign( position.z ) + normal.z * radius; - normals[ i + 0 ] = normal.x; - 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 ); - uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'x', radius, height ); - break; - - } - - } - - } - - } - - THREE.RoundedBoxGeometry = RoundedBoxGeometry; - -} )(); diff --git a/examples/js/geometries/TeapotGeometry.js b/examples/js/geometries/TeapotGeometry.js deleted file mode 100644 index e5395a23f9df63..00000000000000 --- a/examples/js/geometries/TeapotGeometry.js +++ /dev/null @@ -1,331 +0,0 @@ -( function () { - - /** - * Tessellates the famous Utah teapot database by Martin Newell into triangles. - * - * Parameters: size = 50, segments = 10, bottom = true, lid = true, body = true, - * fitLid = false, blinn = true - * - * size is a relative scale: I've scaled the teapot to fit vertically between -1 and 1. - * Think of it as a "radius". - * segments - number of line segments to subdivide each patch edge; - * 1 is possible but gives degenerates, so two is the real minimum. - * bottom - boolean, if true (default) then the bottom patches are added. Some consider - * adding the bottom heresy, so set this to "false" to adhere to the One True Way. - * lid - to remove the lid and look inside, set to true. - * body - to remove the body and leave the lid, set this and "bottom" to false. - * fitLid - the lid is a tad small in the original. This stretches it a bit so you can't - * see the teapot's insides through the gap. - * blinn - Jim Blinn scaled the original data vertically by dividing by about 1.3 to look - * nicer. If you want to see the original teapot, similar to the real-world model, set - * this to false. True by default. - * See http://en.wikipedia.org/wiki/File:Original_Utah_Teapot.jpg for the original - * real-world teapot (from http://en.wikipedia.org/wiki/Utah_teapot). - * - * Note that the bottom (the last four patches) is not flat - blame Frank Crow, not me. - * - * The teapot should normally be rendered as a double sided object, since for some - * patches both sides can be seen, e.g., the gap around the lid and inside the spout. - * - * Segments 'n' determines the number of triangles output. - * Total triangles = 32*2*n*n - 8*n [degenerates at the top and bottom cusps are deleted] - * - * size_factor # triangles - * 1 56 - * 2 240 - * 3 552 - * 4 992 - * - * 10 6320 - * 20 25440 - * 30 57360 - * - * Code converted from my ancient SPD software, http://tog.acm.org/resources/SPD/ - * Created for the Udacity course "Interactive Rendering", http://bit.ly/ericity - * YouTube video on teapot history: https://www.youtube.com/watch?v=DxMfblPzFNc - * - * See https://en.wikipedia.org/wiki/Utah_teapot for the history of the teapot - * - */ - - class TeapotGeometry extends THREE.BufferGeometry { - - 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*/ - 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 - - 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; // 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. - - let numTriangles = bottom ? ( 8 * segments - 4 ) * segments : 0; - numTriangles += lid ? ( 16 * segments - 4 ) * segments : 0; - numTriangles += body ? 40 * segments * segments : 0; - const indices = new Uint32Array( numTriangles * 3 ); - let numVertices = bottom ? 4 : 0; - numVertices += lid ? 8 : 0; - numVertices += body ? 20 : 0; - 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 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 mgm = []; - const vert = []; - const sdir = []; - const tdir = []; - const norm = new THREE.Vector3(); - let tcoord; - let sval; - let tval; - let p; - let dsval = 0; - let dtval = 0; - const normOut = new THREE.Vector3(); - const gmx = new THREE.Matrix4(); - const tmtx = new THREE.Matrix4(); - const vsp = new THREE.Vector4(); - const vtp = new THREE.Vector4(); - const vdsp = new THREE.Vector4(); - const vdtp = new THREE.Vector4(); - 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. - - 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(); - - } - - const minPatches = body ? 0 : 20; - const maxPatches = bottom ? 32 : 28; - const vertPerRow = segments + 1; - let surfCount = 0; - let vertCount = 0; - 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, - // so ignore it for this part of the loop if the lid is not desired - if ( lid || surf < 20 || surf >= 28 ) { - - // get M * G * M matrix for x,y,z - for ( let i = 0; i < 3; i ++ ) { - - // get control patches - for ( let r = 0; r < 4; r ++ ) { - - 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? - - if ( fitLid && surf >= 20 && surf < 28 && i !== 2 ) { - - // increase XY size by 7.7%, found empirically. I don't - // increase Z so that the teapot will continue to fit in the - // 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: - - - if ( ! blinn && i === 2 ) { - - g[ c * 4 + r ] *= blinnScale; - - } - - } - - } - - gmx.set( g[ 0 ], g[ 1 ], g[ 2 ], g[ 3 ], g[ 4 ], g[ 5 ], g[ 6 ], g[ 7 ], g[ 8 ], g[ 9 ], g[ 10 ], g[ 11 ], g[ 12 ], g[ 13 ], g[ 14 ], g[ 15 ] ); - tmtx.multiplyMatrices( gmx, ms ); - mgm[ i ].multiplyMatrices( mst, tmtx ); - - } // 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 - - 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; - dsval = dtval = 1.0; - - } else { - - dsp[ p ] = dsval * ( 3 - p ); - dtp[ p ] = dtval * ( 3 - p ); - dsval *= s; - dtval *= t; - - } - - } - - vsp.fromArray( sp ); - vtp.fromArray( tp ); - vdsp.fromArray( dsp ); - 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 - - tcoord = vdsp.clone(); - tcoord.applyMatrix4( mgm[ i ] ); - sdir[ i ] = tcoord.dot( vtp ); - tcoord = vsp.clone(); - tcoord.applyMatrix4( mgm[ i ] ); - tdir[ i ] = tcoord.dot( vdtp ); - - } // 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 - - if ( vert[ 0 ] === 0 && vert[ 1 ] === 0 ) { - - // if above the middle of the teapot, normal points up, else down - normOut.set( 0, vert[ 2 ] > maxHeight2 ? 1 : - 1, 0 ); - - } else { - - // standard output: rotate on X axis - normOut.set( norm.x, norm.z, - norm.y ); - - } // store it all - - - vertices[ vertCount ++ ] = trueSize * vert[ 0 ]; - vertices[ vertCount ++ ] = trueSize * ( vert[ 2 ] - maxHeight2 ); - vertices[ vertCount ++ ] = - trueSize * vert[ 1 ]; - normals[ normCount ++ ] = normOut.x; - normals[ normCount ++ ] = normOut.y; - normals[ normCount ++ ] = normOut.z; - uvs[ uvCount ++ ] = 1 - t; - uvs[ uvCount ++ ] = 1 - s; - - } - - } // save the faces - - - for ( let sstep = 0; sstep < segments; sstep ++ ) { - - for ( let tstep = 0; tstep < segments; tstep ++ ) { - - 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 ). - - if ( notDegenerate( v1, v2, v3 ) ) { - - indices[ indexCount ++ ] = v1; - indices[ indexCount ++ ] = v2; - indices[ indexCount ++ ] = v3; - - } - - if ( notDegenerate( v1, v3, v4 ) ) { - - indices[ indexCount ++ ] = v1; - indices[ indexCount ++ ] = v3; - indices[ indexCount ++ ] = v4; - - } - - } - - } // increment only if a surface was used - - - surfCount ++; - - } - - } - - this.setIndex( new THREE.BufferAttribute( indices, 1 ) ); - this.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - this.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); - this.setAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) ); - this.computeBoundingSphere(); - - } - - } - - THREE.TeapotGeometry = TeapotGeometry; - -} )(); diff --git a/examples/js/geometries/TextGeometry.js b/examples/js/geometries/TextGeometry.js deleted file mode 100644 index 7cbdaa35cea515..00000000000000 --- a/examples/js/geometries/TextGeometry.js +++ /dev/null @@ -1,51 +0,0 @@ -( function () { - - /** - * Text = 3D Text - * - * parameters = { - * font: , // font - * - * size: , // size of the text - * height: , // thickness to extrude text - * curveSegments: , // number of points on the curves - * - * bevelEnabled: , // turn on bevel - * bevelThickness: , // how deep into text bevel goes - * bevelSize: , // how far from text outline (including bevelOffset) is bevel - * 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 - - parameters.depth = parameters.height !== undefined ? parameters.height : 50; // defaults - - if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10; - if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8; - if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false; - super( shapes, parameters ); - - } - - this.type = 'TextGeometry'; - - } - - } - - THREE.TextGeometry = TextGeometry; - -} )(); diff --git a/examples/js/helpers/LightProbeHelper.js b/examples/js/helpers/LightProbeHelper.js deleted file mode 100644 index e3e9cbeef10155..00000000000000 --- a/examples/js/helpers/LightProbeHelper.js +++ /dev/null @@ -1,49 +0,0 @@ -( function () { - - class LightProbeHelper extends THREE.Mesh { - - constructor( lightProbe, size ) { - - const material = new THREE.ShaderMaterial( { - type: 'LightProbeHelperMaterial', - uniforms: { - sh: { - value: lightProbe.sh.coefficients - }, - // by reference - intensity: { - value: lightProbe.intensity - } - }, - vertexShader: [ 'varying vec3 vNormal;', 'void main() {', ' vNormal = normalize( normalMatrix * normal );', ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ), - fragmentShader: [ '#define RECIPROCAL_PI 0.318309886', 'vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {', ' // matrix is assumed to be orthogonal', ' return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );', '}', '// source: https://graphics.stanford.edu/papers/envmap/envmap.pdf', 'vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {', ' // normal is assumed to have unit length', ' float x = normal.x, y = normal.y, z = normal.z;', ' // band 0', ' vec3 result = shCoefficients[ 0 ] * 0.886227;', ' // band 1', ' result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;', ' result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;', ' result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;', ' // band 2', ' result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;', ' result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;', ' result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );', ' result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;', ' result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );', ' return result;', '}', 'uniform vec3 sh[ 9 ]; // sh coefficients', 'uniform float intensity; // light probe intensity', 'varying vec3 vNormal;', 'void main() {', ' vec3 normal = normalize( vNormal );', ' vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );', ' vec3 irradiance = shGetIrradianceAt( worldNormal, sh );', ' vec3 outgoingLight = RECIPROCAL_PI * irradiance * intensity;', ' gl_FragColor = linearToOutputTexel( vec4( outgoingLight, 1.0 ) );', '}' ].join( '\n' ) - } ); - const geometry = new THREE.SphereGeometry( 1, 32, 16 ); - super( geometry, material ); - this.lightProbe = lightProbe; - this.size = size; - this.type = 'LightProbeHelper'; - this.onBeforeRender(); - - } - - dispose() { - - this.geometry.dispose(); - this.material.dispose(); - - } - - onBeforeRender() { - - this.position.copy( this.lightProbe.position ); - this.scale.set( 1, 1, 1 ).multiplyScalar( this.size ); - this.material.uniforms.intensity.value = this.lightProbe.intensity; - - } - - } - - THREE.LightProbeHelper = LightProbeHelper; - -} )(); diff --git a/examples/js/helpers/OctreeHelper.js b/examples/js/helpers/OctreeHelper.js deleted file mode 100644 index 86c0d3c162112c..00000000000000 --- a/examples/js/helpers/OctreeHelper.js +++ /dev/null @@ -1,74 +0,0 @@ -( function () { - - class OctreeHelper extends THREE.LineSegments { - - constructor( octree, color = 0xffff00 ) { - - const vertices = []; - - function traverse( tree ) { - - for ( let i = 0; i < tree.length; i ++ ) { - - const min = tree[ i ].box.min; - 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 - - traverse( tree[ i ].subTrees ); - - } - - } - - 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'; - - } - - } - - THREE.OctreeHelper = OctreeHelper; - -} )(); diff --git a/examples/js/helpers/PositionalAudioHelper.js b/examples/js/helpers/PositionalAudioHelper.js deleted file mode 100644 index a89d61561b5356..00000000000000 --- a/examples/js/helpers/PositionalAudioHelper.js +++ /dev/null @@ -1,89 +0,0 @@ -( function () { - - class PositionalAudioHelper extends THREE.Line { - - constructor( audio, range = 1, divisionsInnerAngle = 16, divisionsOuterAngle = 2 ) { - - const geometry = new THREE.BufferGeometry(); - const divisions = divisionsInnerAngle + divisionsOuterAngle * 2; - const positions = new Float32Array( ( divisions * 3 + 3 ) * 3 ); - geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); - const materialInnerAngle = new THREE.LineBasicMaterial( { - color: 0x00ff00 - } ); - const materialOuterAngle = new THREE.LineBasicMaterial( { - color: 0xffff00 - } ); - super( geometry, [ materialOuterAngle, materialInnerAngle ] ); - this.audio = audio; - this.range = range; - this.divisionsInnerAngle = divisionsInnerAngle; - this.divisionsOuterAngle = divisionsOuterAngle; - this.type = 'PositionalAudioHelper'; - this.update(); - - } - - update() { - - const audio = this.audio; - const range = this.range; - const divisionsInnerAngle = this.divisionsInnerAngle; - const divisionsOuterAngle = this.divisionsOuterAngle; - const coneInnerAngle = THREE.MathUtils.degToRad( audio.panner.coneInnerAngle ); - const coneOuterAngle = THREE.MathUtils.degToRad( audio.panner.coneOuterAngle ); - const halfConeInnerAngle = coneInnerAngle / 2; - const halfConeOuterAngle = coneOuterAngle / 2; - let start = 0; - let count = 0; - let i; - let stride; - const geometry = this.geometry; - const positionAttribute = geometry.attributes.position; - 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; - positionAttribute.setXYZ( stride, Math.sin( i ) * range, 0, Math.cos( i ) * range ); - positionAttribute.setXYZ( stride + 1, Math.sin( Math.min( i + step, to ) ) * range, 0, Math.cos( Math.min( i + step, to ) ) * range ); - positionAttribute.setXYZ( stride + 2, 0, 0, 0 ); - count += 3; - - } - - geometry.addGroup( start, count, materialIndex ); - start += count; - count = 0; - - } // - - - generateSegment( - halfConeOuterAngle, - halfConeInnerAngle, divisionsOuterAngle, 0 ); - generateSegment( - halfConeInnerAngle, halfConeInnerAngle, divisionsInnerAngle, 1 ); - generateSegment( halfConeInnerAngle, halfConeOuterAngle, divisionsOuterAngle, 0 ); // - - positionAttribute.needsUpdate = true; - if ( coneInnerAngle === coneOuterAngle ) this.material[ 0 ].visible = false; - - } - - dispose() { - - this.geometry.dispose(); - this.material[ 0 ].dispose(); - this.material[ 1 ].dispose(); - - } - - } - - THREE.PositionalAudioHelper = PositionalAudioHelper; - -} )(); diff --git a/examples/js/helpers/RectAreaLightHelper.js b/examples/js/helpers/RectAreaLightHelper.js deleted file mode 100644 index faeb7508d33be9..00000000000000 --- a/examples/js/helpers/RectAreaLightHelper.js +++ /dev/null @@ -1,74 +0,0 @@ -( function () { - - /** - * This helper must be added as a child of the light - */ - - class RectAreaLightHelper extends THREE.Line { - - constructor( light, color ) { - - const positions = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, - 1, 0, 1, 1, 0 ]; - const geometry = new THREE.BufferGeometry(); - geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); - geometry.computeBoundingSphere(); - const material = new THREE.LineBasicMaterial( { - fog: false - } ); - super( geometry, material ); - this.light = light; - this.color = color; // optional hardwired color for the helper - - 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(); - geometry2.setAttribute( 'position', new THREE.Float32BufferAttribute( positions2, 3 ) ); - geometry2.computeBoundingSphere(); - this.add( new THREE.Mesh( geometry2, new THREE.MeshBasicMaterial( { - side: THREE.BackSide, - fog: false - } ) ) ); - - } - - 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 ); - this.children[ 0 ].material.color.set( this.color ); - - } else { - - 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 - - - this.matrixWorld.extractRotation( this.light.matrixWorld ).scale( this.scale ).copyPosition( this.light.matrixWorld ); - this.children[ 0 ].matrixWorld.copy( this.matrixWorld ); - - } - - dispose() { - - this.geometry.dispose(); - this.material.dispose(); - this.children[ 0 ].geometry.dispose(); - this.children[ 0 ].material.dispose(); - - } - - } - - THREE.RectAreaLightHelper = RectAreaLightHelper; - -} )(); diff --git a/examples/js/helpers/VertexNormalsHelper.js b/examples/js/helpers/VertexNormalsHelper.js deleted file mode 100644 index ad1d709433aac0..00000000000000 --- a/examples/js/helpers/VertexNormalsHelper.js +++ /dev/null @@ -1,72 +0,0 @@ -( 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 ) { - - const geometry = new THREE.BufferGeometry(); - const nNormals = object.geometry.attributes.normal.count; - const positions = new THREE.Float32BufferAttribute( nNormals * 2 * 3, 3 ); - geometry.setAttribute( 'position', positions ); - super( geometry, new THREE.LineBasicMaterial( { - color, - toneMapped: false - } ) ); - this.object = object; - this.size = size; - 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 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 - - 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 ); - idx = idx + 1; - - } - - } - - position.needsUpdate = true; - - } - - } - - THREE.VertexNormalsHelper = VertexNormalsHelper; - -} )(); diff --git a/examples/js/helpers/VertexTangentsHelper.js b/examples/js/helpers/VertexTangentsHelper.js deleted file mode 100644 index 299e84815faa8f..00000000000000 --- a/examples/js/helpers/VertexTangentsHelper.js +++ /dev/null @@ -1,62 +0,0 @@ -( function () { - - const _v1 = new THREE.Vector3(); - - const _v2 = new THREE.Vector3(); - - class VertexTangentsHelper extends THREE.LineSegments { - - constructor( object, size = 1, color = 0x00ffff ) { - - const geometry = new THREE.BufferGeometry(); - const nTangents = object.geometry.attributes.tangent.count; - const positions = new THREE.Float32BufferAttribute( nTangents * 2 * 3, 3 ); - geometry.setAttribute( 'position', positions ); - super( geometry, new THREE.LineBasicMaterial( { - color, - toneMapped: false - } ) ); - this.object = object; - this.size = size; - 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 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 - - 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 ); - idx = idx + 1; - - } - - position.needsUpdate = true; - - } - - } - - THREE.VertexTangentsHelper = VertexTangentsHelper; - -} )(); diff --git a/examples/js/helpers/ViewHelper.js b/examples/js/helpers/ViewHelper.js deleted file mode 100644 index aa5cf9bb7aab0a..00000000000000 --- a/examples/js/helpers/ViewHelper.js +++ /dev/null @@ -1,266 +0,0 @@ -( function () { - - const vpTemp = new THREE.Vector4(); - - class ViewHelper extends THREE.Object3D { - - constructor( editorCamera, dom ) { - - super(); - this.isViewHelper = true; - this.animating = false; - this.controls = null; - const color1 = new THREE.Color( '#ff3653' ); - const color2 = new THREE.Color( '#8adb00' ); - const color3 = new THREE.Color( '#2c8fff' ); - const interactiveObjects = []; - const raycaster = new THREE.Raycaster(); - const mouse = new THREE.Vector2(); - const dummy = new THREE.Object3D(); - const camera = new THREE.OrthographicCamera( - 2, 2, 2, - 2, 0, 4 ); - camera.position.set( 0, 0, 2 ); - const geometry = new THREE.BoxGeometry( 0.8, 0.05, 0.05 ).translate( 0.4, 0, 0 ); - const xAxis = new THREE.Mesh( geometry, getAxisMaterial( color1 ) ); - const yAxis = new THREE.Mesh( geometry, getAxisMaterial( color2 ) ); - const zAxis = new THREE.Mesh( geometry, getAxisMaterial( color3 ) ); - yAxis.rotation.z = Math.PI / 2; - zAxis.rotation.y = - Math.PI / 2; - this.add( xAxis ); - this.add( zAxis ); - this.add( yAxis ); - const posXAxisHelper = new THREE.Sprite( getSpriteMaterial( color1, 'X' ) ); - posXAxisHelper.userData.type = 'posX'; - const posYAxisHelper = new THREE.Sprite( getSpriteMaterial( color2, 'Y' ) ); - posYAxisHelper.userData.type = 'posY'; - const posZAxisHelper = new THREE.Sprite( getSpriteMaterial( color3, 'Z' ) ); - posZAxisHelper.userData.type = 'posZ'; - const negXAxisHelper = new THREE.Sprite( getSpriteMaterial( color1 ) ); - negXAxisHelper.userData.type = 'negX'; - const negYAxisHelper = new THREE.Sprite( getSpriteMaterial( color2 ) ); - negYAxisHelper.userData.type = 'negY'; - const negZAxisHelper = new THREE.Sprite( getSpriteMaterial( color3 ) ); - negZAxisHelper.userData.type = 'negZ'; - posXAxisHelper.position.x = 1; - posYAxisHelper.position.y = 1; - posZAxisHelper.position.z = 1; - negXAxisHelper.position.x = - 1; - negXAxisHelper.scale.setScalar( 0.8 ); - negYAxisHelper.position.y = - 1; - negYAxisHelper.scale.setScalar( 0.8 ); - negZAxisHelper.position.z = - 1; - negZAxisHelper.scale.setScalar( 0.8 ); - this.add( posXAxisHelper ); - this.add( posYAxisHelper ); - this.add( posZAxisHelper ); - this.add( negXAxisHelper ); - this.add( negYAxisHelper ); - this.add( negZAxisHelper ); - interactiveObjects.push( posXAxisHelper ); - interactiveObjects.push( posYAxisHelper ); - interactiveObjects.push( posZAxisHelper ); - interactiveObjects.push( negXAxisHelper ); - interactiveObjects.push( negYAxisHelper ); - interactiveObjects.push( negZAxisHelper ); - const point = new THREE.Vector3(); - const dim = 128; - const turnRate = 2 * Math.PI; // turn rate in angles per second - - this.render = function ( renderer ) { - - this.quaternion.copy( editorCamera.quaternion ).invert(); - this.updateMatrixWorld(); - point.set( 0, 0, 1 ); - point.applyQuaternion( editorCamera.quaternion ); - - if ( point.x >= 0 ) { - - posXAxisHelper.material.opacity = 1; - negXAxisHelper.material.opacity = 0.5; - - } else { - - posXAxisHelper.material.opacity = 0.5; - negXAxisHelper.material.opacity = 1; - - } - - if ( point.y >= 0 ) { - - posYAxisHelper.material.opacity = 1; - negYAxisHelper.material.opacity = 0.5; - - } else { - - posYAxisHelper.material.opacity = 0.5; - negYAxisHelper.material.opacity = 1; - - } - - if ( point.z >= 0 ) { - - posZAxisHelper.material.opacity = 1; - negZAxisHelper.material.opacity = 0.5; - - } else { - - posZAxisHelper.material.opacity = 0.5; - negZAxisHelper.material.opacity = 1; - - } // - - - const x = dom.offsetWidth - dim; - renderer.clearDepth(); - renderer.getViewport( vpTemp ); - renderer.setViewport( x, 0, dim, dim ); - renderer.render( this, camera ); - renderer.setViewport( vpTemp.x, vpTemp.y, vpTemp.z, vpTemp.w ); - - }; - - const targetPosition = new THREE.Vector3(); - const targetQuaternion = new THREE.Quaternion(); - const q1 = new THREE.Quaternion(); - const q2 = new THREE.Quaternion(); - let radius = 0; - - this.handleClick = function ( event ) { - - if ( this.animating === true ) return false; - const rect = dom.getBoundingClientRect(); - const offsetX = rect.left + ( dom.offsetWidth - dim ); - const offsetY = rect.top + ( dom.offsetHeight - dim ); - mouse.x = ( event.clientX - offsetX ) / ( rect.width - offsetX ) * 2 - 1; - 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 ]; - const object = intersection.object; - prepareAnimationData( object, this.controls.center ); - this.animating = true; - return true; - - } else { - - return false; - - } - - }; - - 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 - - q1.rotateTowards( q2, step ); - editorCamera.position.set( 0, 0, 1 ).applyQuaternion( q1 ).multiplyScalar( radius ).add( focusPoint ); // animate orientation - - editorCamera.quaternion.rotateTowards( targetQuaternion, step ); - - if ( q1.angleTo( q2 ) === 0 ) { - - this.animating = false; - - } - - }; - - function prepareAnimationData( object, focusPoint ) { - - switch ( object.userData.type ) { - - case 'posX': - 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 ); - dummy.position.copy( focusPoint ); - dummy.lookAt( editorCamera.position ); - q1.copy( dummy.quaternion ); - dummy.lookAt( targetPosition ); - q2.copy( dummy.quaternion ); - - } - - function getAxisMaterial( color ) { - - return new THREE.MeshBasicMaterial( { - color: color, - toneMapped: false - } ); - - } - - function getSpriteMaterial( color, text = null ) { - - const canvas = document.createElement( 'canvas' ); - canvas.width = 64; - canvas.height = 64; - const context = canvas.getContext( '2d' ); - context.beginPath(); - context.arc( 32, 32, 16, 0, 2 * Math.PI ); - context.closePath(); - context.fillStyle = color.getStyle(); - context.fill(); - - if ( text !== null ) { - - context.font = '24px Arial'; - context.textAlign = 'center'; - context.fillStyle = '#000000'; - context.fillText( text, 32, 41 ); - - } - - const texture = new THREE.CanvasTexture( canvas ); - return new THREE.SpriteMaterial( { - map: texture, - toneMapped: false - } ); - - } - - } - - } - - THREE.ViewHelper = ViewHelper; - -} )(); diff --git a/examples/js/interactive/HTMLMesh.js b/examples/js/interactive/HTMLMesh.js deleted file mode 100644 index e71e90d687890d..00000000000000 --- a/examples/js/interactive/HTMLMesh.js +++ /dev/null @@ -1,511 +0,0 @@ -( function () { - - class HTMLMesh extends THREE.Mesh { - - constructor( dom ) { - - const texture = new HTMLTexture( dom ); - const geometry = new THREE.PlaneGeometry( texture.image.width * 0.001, texture.image.height * 0.001 ); - const material = new THREE.MeshBasicMaterial( { - map: texture, - toneMapped: false, - transparent: true - } ); - super( geometry, material ); - - function onEvent( event ) { - - material.map.dispatchDOMEvent( event ); - - } - - this.addEventListener( 'mousedown', onEvent ); - this.addEventListener( 'mousemove', onEvent ); - this.addEventListener( 'mouseup', onEvent ); - this.addEventListener( 'click', onEvent ); - - this.dispose = function () { - - geometry.dispose(); - material.dispose(); - material.map.dispose(); - this.removeEventListener( 'mousedown', onEvent ); - this.removeEventListener( 'mousemove', onEvent ); - this.removeEventListener( 'mouseup', onEvent ); - this.removeEventListener( 'click', onEvent ); - - }; - - } - - } - - class HTMLTexture extends THREE.CanvasTexture { - - constructor( dom ) { - - super( html2canvas( dom ) ); - this.dom = dom; - 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 - - const observer = new MutationObserver( () => { - - if ( ! this.scheduleUpdate ) { - - // ideally should use xr.requestAnimationFrame, here setTimeout to avoid passing the renderer - this.scheduleUpdate = setTimeout( () => this.update(), 16 ); - - } - - } ); - const config = { - attributes: true, - childList: true, - subtree: true, - characterData: true - }; - observer.observe( dom, config ); - this.observer = observer; - - } - - dispatchDOMEvent( event ) { - - if ( event.data ) { - - htmlevent( this.dom, event.type, event.data.x, event.data.y ); - - } - - } - - update() { - - this.image = html2canvas( this.dom ); - this.needsUpdate = true; - this.scheduleUpdate = null; - - } - - dispose() { - - if ( this.observer ) { - - this.observer.disconnect(); - - } - - this.scheduleUpdate = clearTimeout( this.scheduleUpdate ); - super.dispose(); - - } - - } // - - - 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 ) { - - isClipping = false; - context.restore(); - - } - - if ( clips.length === 0 ) return; - let minX = - Infinity, - minY = - Infinity; - let maxX = Infinity, - maxY = Infinity; - - for ( let i = 0; i < clips.length; i ++ ) { - - const clip = clips[ i ]; - minX = Math.max( minX, clip.x ); - minY = Math.max( minY, clip.y ); - maxX = Math.min( maxX, clip.x + clip.width ); - maxY = Math.min( maxY, clip.y + clip.height ); - - } - - context.save(); - context.beginPath(); - context.rect( minX, minY, maxX - minX, maxY - minY ); - context.clip(); - isClipping = true; - - } - - return { - add: function ( clip ) { - - clips.push( clip ); - doClip(); - - }, - remove: function () { - - clips.pop(); - doClip(); - - } - }; - - } - - function drawText( style, x, y, string ) { - - if ( string !== '' ) { - - if ( style.textTransform === 'uppercase' ) { - - string = string.toUpperCase(); - - } - - context.font = style.fontWeight + ' ' + style.fontSize + ' ' + style.fontFamily; - context.textBaseline = 'top'; - context.fillStyle = style.color; - context.fillText( string, x, y + parseFloat( style.fontSize ) * 0.1 ); - - } - - } - - function buildRectPath( x, y, w, h, r ) { - - if ( w < 2 * r ) r = w / 2; - if ( h < 2 * r ) r = h / 2; - context.beginPath(); - context.moveTo( x + r, y ); - context.arcTo( x + w, y, x + w, y + h, r ); - context.arcTo( x + w, y + h, x, y + h, r ); - context.arcTo( x, y + h, x, y, r ); - context.arcTo( x, y, x + w, y, r ); - context.closePath(); - - } - - function drawBorder( style, which, x, y, width, height ) { - - 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; - context.lineWidth = parseFloat( borderWidth ); - context.beginPath(); - context.moveTo( x, y ); - context.lineTo( x + width, y + height ); - context.stroke(); - - } - - } - - function drawElement( element, style ) { - - let x = 0, - 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; - y = rect.top - offset.top - 0.5; - width = rect.width; - height = rect.height; - drawText( style, x, y, element.nodeValue.trim() ); - - } else if ( element.nodeType === Node.COMMENT_NODE ) { - - return; - - } else if ( element instanceof HTMLCanvasElement ) { - - // Canvas element - if ( element.style.display === 'none' ) return; - context.save(); - const dpr = window.devicePixelRatio; - context.scale( 1 / dpr, 1 / dpr ); - context.drawImage( element, 0, 0 ); - context.restore(); - - } else { - - if ( element.style.display === 'none' ) return; - const rect = element.getBoundingClientRect(); - x = rect.left - offset.left - 0.5; - 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 - - 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 - - - const borders = [ 'borderTop', 'borderLeft', 'borderBottom', 'borderRight' ]; - let match = true; - let prevBorder = null; - - for ( const border of borders ) { - - if ( prevBorder !== null ) { - - match = style[ border + 'Width' ] === style[ prevBorder + 'Width' ] && style[ border + 'Color' ] === style[ prevBorder + 'Color' ] && style[ border + 'Style' ] === style[ prevBorder + 'Style' ]; - - } - - if ( match === false ) break; - prevBorder = border; - - } - - if ( match === true ) { - - // They all match so stroke the rectangle from before allows for border-radius - 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; - context.lineWidth = width; - context.stroke(); - - } - - } 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 ); - drawBorder( style, 'borderRight', x + width, y, 0, height ); - - } - - if ( element instanceof HTMLInputElement ) { - - let accentColor = style.accentColor; - if ( accentColor === undefined || accentColor === 'auto' ) accentColor = style.color; - 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 ); - context.fillStyle = 'white'; - context.strokeStyle = accentColor; - context.lineWidth = 1; - context.fill(); - context.stroke(); - - if ( element.checked ) { - - buildRectPath( x + 2, y + 2, width - 4, height - 4, height ); - context.fillStyle = accentColor; - context.strokeStyle = accentTextColor; - context.lineWidth = 2; - context.fill(); - context.stroke(); - - } - - } - - if ( element.type === 'checkbox' ) { - - buildRectPath( x, y, width, height, 2 ); - context.fillStyle = element.checked ? accentColor : 'white'; - context.strokeStyle = element.checked ? accentTextColor : accentColor; - context.lineWidth = 1; - context.stroke(); - context.fill(); - - if ( element.checked ) { - - const currentTextAlign = context.textAlign; - context.textAlign = 'center'; - const properties = { - color: accentTextColor, - fontFamily: style.fontFamily, - fontSize: height + 'px', - fontWeight: 'bold' - }; - drawText( properties, x + width / 2, y, '✔' ); - context.textAlign = currentTextAlign; - - } - - } - - if ( element.type === 'range' ) { - - const [ min, max, value ] = [ 'min', 'max', 'value' ].map( property => parseFloat( element[ property ] ) ); - const position = ( value - min ) / ( max - min ) * ( width - height ); - buildRectPath( x, y + height / 4, width, height / 2, height / 4 ); - context.fillStyle = accentTextColor; - context.strokeStyle = accentColor; - context.lineWidth = 1; - context.fill(); - context.stroke(); - buildRectPath( x, y + height / 4, position + height / 2, height / 2, height / 4 ); - context.fillStyle = accentColor; - context.fill(); - buildRectPath( x + position, y, height, height, height / 2 ); - context.fillStyle = accentColor; - context.fill(); - - } - - if ( element.type === 'color' || element.type === 'text' || element.type === 'number' ) { - - clipper.add( { - x: x, - y: y, - width: width, - height: height - } ); - drawText( style, x + parseInt( style.paddingLeft ), y + parseInt( style.paddingTop ), element.value ); - clipper.remove(); - - } - - } - - } - /* - // 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, - y: y, - width: width, - height: height - } ); - - for ( let i = 0; i < element.childNodes.length; i ++ ) { - - drawElement( element.childNodes[ i ], style ); - - } - - if ( isClipping ) clipper.remove(); - - } - - const offset = element.getBoundingClientRect(); - let canvas; - - if ( canvases.has( element ) ) { - - canvas = canvases.get( element ); - - } else { - - canvas = document.createElement( 'canvas' ); - canvas.width = offset.width; - canvas.height = offset.height; - - } - - const context = canvas.getContext( '2d' - /*, { alpha: false }*/ - ); - const clipper = new Clipper( context ); // console.time( 'drawElement' ); - - drawElement( element ); // console.timeEnd( 'drawElement' ); - - return canvas; - - } - - function htmlevent( element, event, x, y ) { - - const mouseEventInit = { - clientX: x * element.offsetWidth + element.offsetLeft, - clientY: y * element.offsetHeight + element.offsetTop, - view: element.ownerDocument.defaultView - }; - window.dispatchEvent( new MouseEvent( event, mouseEventInit ) ); - 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 ] ) ); - const width = rect.width; - const offsetX = x - rect.x; - const proportion = offsetX / width; - element.value = min + ( max - min ) * proportion; - element.dispatchEvent( new InputEvent( 'input', { - bubbles: true - } ) ); - - } - - } - - for ( let i = 0; i < element.childNodes.length; i ++ ) { - - traverse( element.childNodes[ i ] ); - - } - - } - - } - - traverse( element ); - - } - - THREE.HTMLMesh = HTMLMesh; - -} )(); diff --git a/examples/js/interactive/InteractiveGroup.js b/examples/js/interactive/InteractiveGroup.js deleted file mode 100644 index 14682dfd2ac2ef..00000000000000 --- a/examples/js/interactive/InteractiveGroup.js +++ /dev/null @@ -1,100 +0,0 @@ -( function () { - - const _pointer = new THREE.Vector2(); - - const _event = { - type: '', - data: _pointer - }; - - class InteractiveGroup extends THREE.Group { - - constructor( renderer, camera ) { - - super(); - const scope = this; - const raycaster = new THREE.Raycaster(); - const tempMatrix = new THREE.Matrix4(); // 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; - 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 ); - - } - - } - - element.addEventListener( 'pointerdown', onPointerEvent ); - element.addEventListener( 'pointerup', onPointerEvent ); - element.addEventListener( 'pointermove', onPointerEvent ); - element.addEventListener( 'mousedown', onPointerEvent ); - element.addEventListener( 'mouseup', onPointerEvent ); - element.addEventListener( 'mousemove', onPointerEvent ); - element.addEventListener( 'click', onPointerEvent ); // WebXR Controller Events - // TODO: Dispatch pointerevents too - - const events = { - 'move': 'mousemove', - 'select': 'click', - 'selectstart': 'mousedown', - 'selectend': 'mouseup' - }; - - function onXRControllerEvent( event ) { - - const controller = event.target; - tempMatrix.identity().extractRotation( controller.matrixWorld ); - 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 ); - - } - - } - - const controller1 = renderer.xr.getController( 0 ); - controller1.addEventListener( 'move', onXRControllerEvent ); - controller1.addEventListener( 'select', onXRControllerEvent ); - controller1.addEventListener( 'selectstart', onXRControllerEvent ); - controller1.addEventListener( 'selectend', onXRControllerEvent ); - const controller2 = renderer.xr.getController( 1 ); - controller2.addEventListener( 'move', onXRControllerEvent ); - controller2.addEventListener( 'select', onXRControllerEvent ); - controller2.addEventListener( 'selectstart', onXRControllerEvent ); - controller2.addEventListener( 'selectend', onXRControllerEvent ); - - } - - } - - THREE.InteractiveGroup = InteractiveGroup; - -} )(); diff --git a/examples/js/interactive/SelectionBox.js b/examples/js/interactive/SelectionBox.js deleted file mode 100644 index adc9d4857ae78d..00000000000000 --- a/examples/js/interactive/SelectionBox.js +++ /dev/null @@ -1,262 +0,0 @@ -( function () { - - /** - * This is a class to check whether objects are in a selection area in 3D space - */ - - 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 ) { - - this.camera = camera; - this.scene = scene; - this.startPoint = new THREE.Vector3(); - this.endPoint = new THREE.Vector3(); - this.collection = []; - this.instances = {}; - this.deep = deep; - - } - - select( startPoint, endPoint ) { - - this.startPoint = startPoint || this.startPoint; - this.endPoint = endPoint || this.endPoint; - this.collection = []; - this.updateFrustum( this.startPoint, this.endPoint ); - this.searchChildInFrustum( _frustum, this.scene ); - return this.collection; - - } - - updateFrustum( startPoint, endPoint ) { - - startPoint = startPoint || this.startPoint; - endPoint = endPoint || this.endPoint; // Avoid invalid frustum - - if ( startPoint.x === endPoint.x ) { - - endPoint.x += Number.EPSILON; - - } - - if ( startPoint.y === endPoint.y ) { - - endPoint.y += Number.EPSILON; - - } - - 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 ); - planes[ 2 ].setFromCoplanarPoints( _vecDownRight, _vecDownLeft, _vecNear ); - planes[ 3 ].setFromCoplanarPoints( _vecDownLeft, _vecTopLeft, _vecNear ); - planes[ 4 ].setFromCoplanarPoints( _vecTopRight, _vecDownRight, _vecDownLeft ); - planes[ 5 ].setFromCoplanarPoints( _vectemp3, _vectemp2, _vectemp1 ); - planes[ 5 ].normal.multiplyScalar( - 1 ); - - } else if ( this.camera.isOrthographicCamera ) { - - const left = Math.min( startPoint.x, endPoint.x ); - 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 ); - planes[ 2 ].setFromCoplanarPoints( _vecFarDownRight, _vecFarDownLeft, _vecDownLeft ); - planes[ 3 ].setFromCoplanarPoints( _vecFarDownLeft, _vecFarTopLeft, _vecTopLeft ); - planes[ 4 ].setFromCoplanarPoints( _vecTopRight, _vecDownRight, _vecDownLeft ); - planes[ 5 ].setFromCoplanarPoints( _vecFarDownRight, _vecFarTopRight, _vecFarTopLeft ); - planes[ 5 ].normal.multiplyScalar( - 1 ); - - } else { - - console.error( 'THREE.SelectionBox: Unsupported camera type.' ); - - } - - } - - searchChildInFrustum( frustum, object ) { - - if ( object.isMesh || object.isLine || object.isPoints ) { - - 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 ); - - } - - } - - } 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 ); - - } - - } - - } - - if ( object.children.length > 0 ) { - - for ( let x = 0; x < object.children.length; x ++ ) { - - this.searchChildInFrustum( frustum, object.children[ x ] ); - - } - - } - - } - - } - - THREE.SelectionBox = SelectionBox; - -} )(); diff --git a/examples/js/interactive/SelectionHelper.js b/examples/js/interactive/SelectionHelper.js deleted file mode 100644 index 36a171b201a159..00000000000000 --- a/examples/js/interactive/SelectionHelper.js +++ /dev/null @@ -1,89 +0,0 @@ -( function () { - - class SelectionHelper { - - constructor( renderer, cssClassName ) { - - this.element = document.createElement( 'div' ); - this.element.classList.add( cssClassName ); - this.element.style.pointerEvents = 'none'; - this.renderer = renderer; - this.startPoint = new THREE.Vector2(); - 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 ) { - - this.onSelectMove( event ); - - } - - }.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 ); - this.renderer.domElement.removeEventListener( 'pointermove', this.onPointerMove ); - this.renderer.domElement.removeEventListener( 'pointerup', this.onPointerUp ); - - } - - onSelectStart( event ) { - - this.renderer.domElement.parentElement.appendChild( this.element ); - this.element.style.left = event.clientX + 'px'; - this.element.style.top = event.clientY + 'px'; - this.element.style.width = '0px'; - this.element.style.height = '0px'; - this.startPoint.x = event.clientX; - this.startPoint.y = event.clientY; - - } - - onSelectMove( event ) { - - 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 ); - this.pointTopLeft.y = Math.min( this.startPoint.y, event.clientY ); - this.element.style.left = this.pointTopLeft.x + 'px'; - this.element.style.top = this.pointTopLeft.y + 'px'; - this.element.style.width = this.pointBottomRight.x - this.pointTopLeft.x + 'px'; - this.element.style.height = this.pointBottomRight.y - this.pointTopLeft.y + 'px'; - - } - - onSelectOver() { - - this.element.parentElement.removeChild( this.element ); - - } - - } - - THREE.SelectionHelper = SelectionHelper; - -} )(); diff --git a/examples/js/libs/basis/README.md b/examples/js/libs/basis/README.md deleted file mode 100644 index 150a27b081aaa2..00000000000000 --- a/examples/js/libs/basis/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Basis Universal GPU Texture Compression - -Basis Universal is a "[supercompressed](http://gamma.cs.unc.edu/GST/gst.pdf)" -GPU texture and texture video compression system that outputs a highly -compressed intermediate file format (.basis) that can be quickly transcoded to -a wide variety of GPU texture compression formats. - -[GitHub](https://github.com/BinomialLLC/basis_universal) - -## Transcoders - -Basis Universal texture data may be used in two different file formats: -`.basis` and `.ktx2`, where `ktx2` is a standardized wrapper around basis texture data. - -For further documentation about the Basis compressor and transcoder, refer to -the [Basis GitHub repository](https://github.com/BinomialLLC/basis_universal). - -The folder contains two files required for transcoding `.basis` or `.ktx2` textures: - -* `basis_transcoder.js` — JavaScript wrapper for the WebAssembly transcoder. -* `basis_transcoder.wasm` — WebAssembly transcoder. - -Both are dependencies of `THREE.KTX2Loader` and `THREE.BasisTextureLoader`: - -```js -var ktx2Loader = new THREE.KTX2Loader(); -ktx2Loader.setTranscoderPath( 'examples/js/libs/basis/' ); -ktx2Loader.detectSupport( renderer ); -ktx2Loader.load( 'diffuse.ktx2', function ( texture ) { - - var material = new THREE.MeshStandardMaterial( { map: texture } ); - -}, function () { - - console.log( 'onProgress' ); - -}, function ( e ) { - - console.error( e ); - -} ); -``` - -## License - -[Apache License 2.0](https://github.com/BinomialLLC/basis_universal/blob/master/LICENSE) diff --git a/examples/js/libs/chevrotain.min.js b/examples/js/libs/chevrotain.min.js deleted file mode 100644 index ea22f5989a8e9f..00000000000000 --- a/examples/js/libs/chevrotain.min.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! chevrotain - v9.0.1 */ -/*! For license information please see chevrotain.min.js.LICENSE.txt */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("chevrotain",[],e):"object"==typeof exports?exports.chevrotain=e():t.chevrotain=e()}("undefined"!=typeof self?self:this,(function(){return(()=>{var t={844:function(t,e){var n,r;"undefined"!=typeof self&&self,void 0===(r="function"==typeof(n=function(){function t(){}t.prototype.saveState=function(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}},t.prototype.restoreState=function(t){this.idx=t.idx,this.input=t.input,this.groupIdx=t.groupIdx},t.prototype.pattern=function(t){this.idx=0,this.input=t,this.groupIdx=0,this.consumeChar("/");var e=this.disjunction();this.consumeChar("/");for(var n={type:"Flags",loc:{begin:this.idx,end:t.length},global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};this.isRegExpFlag();)switch(this.popChar()){case"g":s(n,"global");break;case"i":s(n,"ignoreCase");break;case"m":s(n,"multiLine");break;case"u":s(n,"unicode");break;case"y":s(n,"sticky")}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:n,value:e,loc:this.loc(0)}},t.prototype.disjunction=function(){var t=[],e=this.idx;for(t.push(this.alternative());"|"===this.peekChar();)this.consumeChar("|"),t.push(this.alternative());return{type:"Disjunction",value:t,loc:this.loc(e)}},t.prototype.alternative=function(){for(var t=[],e=this.idx;this.isTerm();)t.push(this.term());return{type:"Alternative",value:t,loc:this.loc(e)}},t.prototype.term=function(){return this.isAssertion()?this.assertion():this.atom()},t.prototype.assertion=function(){var t=this.idx;switch(this.popChar()){case"^":return{type:"StartAnchor",loc:this.loc(t)};case"$":return{type:"EndAnchor",loc:this.loc(t)};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary",loc:this.loc(t)};case"B":return{type:"NonWordBoundary",loc:this.loc(t)}}throw Error("Invalid Assertion Escape");case"(":var e;switch(this.consumeChar("?"),this.popChar()){case"=":e="Lookahead";break;case"!":e="NegativeLookahead"}c(e);var n=this.disjunction();return this.consumeChar(")"),{type:e,value:n,loc:this.loc(t)}}!function(){throw Error("Internal Error - Should never get here!")}()},t.prototype.quantifier=function(t){var e,n=this.idx;switch(this.popChar()){case"*":e={atLeast:0,atMost:1/0};break;case"+":e={atLeast:1,atMost:1/0};break;case"?":e={atLeast:0,atMost:1};break;case"{":var r=this.integerIncludingZero();switch(this.popChar()){case"}":e={atLeast:r,atMost:r};break;case",":e=this.isDigit()?{atLeast:r,atMost:this.integerIncludingZero()}:{atLeast:r,atMost:1/0},this.consumeChar("}")}if(!0===t&&void 0===e)return;c(e)}if(!0!==t||void 0!==e)return c(e),"?"===this.peekChar(0)?(this.consumeChar("?"),e.greedy=!1):e.greedy=!0,e.type="Quantifier",e.loc=this.loc(n),e},t.prototype.atom=function(){var t,e=this.idx;switch(this.peekChar()){case".":t=this.dotAll();break;case"\\":t=this.atomEscape();break;case"[":t=this.characterClass();break;case"(":t=this.group()}return void 0===t&&this.isPatternCharacter()&&(t=this.patternCharacter()),c(t),t.loc=this.loc(e),this.isQuantifier()&&(t.quantifier=this.quantifier()),t},t.prototype.dotAll=function(){return this.consumeChar("."),{type:"Set",complement:!0,value:[o("\n"),o("\r"),o("\u2028"),o("\u2029")]}},t.prototype.atomEscape=function(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}},t.prototype.decimalEscapeAtom=function(){return{type:"GroupBackReference",value:this.positiveInteger()}},t.prototype.characterClassEscape=function(){var t,e=!1;switch(this.popChar()){case"d":t=u;break;case"D":t=u,e=!0;break;case"s":t=p;break;case"S":t=p,e=!0;break;case"w":t=l;break;case"W":t=l,e=!0}return c(t),{type:"Set",value:t,complement:e}},t.prototype.controlEscapeAtom=function(){var t;switch(this.popChar()){case"f":t=o("\f");break;case"n":t=o("\n");break;case"r":t=o("\r");break;case"t":t=o("\t");break;case"v":t=o("\v")}return c(t),{type:"Character",value:t}},t.prototype.controlLetterEscapeAtom=function(){this.consumeChar("c");var t=this.popChar();if(!1===/[a-zA-Z]/.test(t))throw Error("Invalid ");return{type:"Character",value:t.toUpperCase().charCodeAt(0)-64}},t.prototype.nulCharacterAtom=function(){return this.consumeChar("0"),{type:"Character",value:o("\0")}},t.prototype.hexEscapeSequenceAtom=function(){return this.consumeChar("x"),this.parseHexDigits(2)},t.prototype.regExpUnicodeEscapeSequenceAtom=function(){return this.consumeChar("u"),this.parseHexDigits(4)},t.prototype.identityEscapeAtom=function(){return{type:"Character",value:o(this.popChar())}},t.prototype.classPatternCharacterAtom=function(){switch(this.peekChar()){case"\n":case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:return{type:"Character",value:o(this.popChar())}}},t.prototype.characterClass=function(){var t=[],e=!1;for(this.consumeChar("["),"^"===this.peekChar(0)&&(this.consumeChar("^"),e=!0);this.isClassAtom();){var n=this.classAtom();if("Character"===n.type&&this.isRangeDash()){this.consumeChar("-");var r=this.classAtom();if("Character"===r.type){if(r.value=this.input.length)throw Error("Unexpected end of input");this.idx++},t.prototype.loc=function(t){return{begin:t,end:this.idx}};var e,n=/[0-9a-fA-F]/,r=/[0-9]/,i=/[1-9]/;function o(t){return t.charCodeAt(0)}function a(t,e){void 0!==t.length?t.forEach((function(t){e.push(t)})):e.push(t)}function s(t,e){if(!0===t[e])throw"duplicate flag "+e;t[e]=!0}function c(t){if(void 0===t)throw Error("Internal Error - Should never get here!")}var u=[];for(e=o("0");e<=o("9");e++)u.push(e);var l=[o("_")].concat(u);for(e=o("a");e<=o("z");e++)l.push(e);for(e=o("A");e<=o("Z");e++)l.push(e);var p=[o(" "),o("\f"),o("\n"),o("\r"),o("\t"),o("\v"),o("\t"),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o("\u2028"),o("\u2029"),o(" "),o(" "),o(" "),o("\ufeff")];function f(){}return f.prototype.visitChildren=function(t){for(var e in t){var n=t[e];t.hasOwnProperty(e)&&(void 0!==n.type?this.visit(n):Array.isArray(n)&&n.forEach((function(t){this.visit(t)}),this))}},f.prototype.visit=function(t){switch(t.type){case"Pattern":this.visitPattern(t);break;case"Flags":this.visitFlags(t);break;case"Disjunction":this.visitDisjunction(t);break;case"Alternative":this.visitAlternative(t);break;case"StartAnchor":this.visitStartAnchor(t);break;case"EndAnchor":this.visitEndAnchor(t);break;case"WordBoundary":this.visitWordBoundary(t);break;case"NonWordBoundary":this.visitNonWordBoundary(t);break;case"Lookahead":this.visitLookahead(t);break;case"NegativeLookahead":this.visitNegativeLookahead(t);break;case"Character":this.visitCharacter(t);break;case"Set":this.visitSet(t);break;case"Group":this.visitGroup(t);break;case"GroupBackReference":this.visitGroupBackReference(t);break;case"Quantifier":this.visitQuantifier(t)}this.visitChildren(t)},f.prototype.visitPattern=function(t){},f.prototype.visitFlags=function(t){},f.prototype.visitDisjunction=function(t){},f.prototype.visitAlternative=function(t){},f.prototype.visitStartAnchor=function(t){},f.prototype.visitEndAnchor=function(t){},f.prototype.visitWordBoundary=function(t){},f.prototype.visitNonWordBoundary=function(t){},f.prototype.visitLookahead=function(t){},f.prototype.visitNegativeLookahead=function(t){},f.prototype.visitCharacter=function(t){},f.prototype.visitSet=function(t){},f.prototype.visitGroup=function(t){},f.prototype.visitGroupBackReference=function(t){},f.prototype.visitQuantifier=function(t){},{RegExpParser:t,BaseRegExpVisitor:f,VERSION:"0.5.0"}})?n.apply(e,[]):n)||(t.exports=r)},781:(t,e,n)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.createSyntaxDiagramsCode=void 0;var r=n(979);e.createSyntaxDiagramsCode=function(t,e){var n=void 0===e?{}:e,i=n.resourceBase,o=void 0===i?"https://unpkg.com/chevrotain@"+r.VERSION+"/diagrams/":i,a=n.css;return"\n\x3c!-- This is a generated file --\x3e\n\n\n\n\n\n\n\n @@ -28,7 +29,7 @@ import * as THREE from 'bmap-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 157d4daafd2614..3ce5c168b7cb6b 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 'bmap-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 6242d6c86e3079..9c5618e8dee49f 100644 --- a/examples/misc_boxselection.html +++ b/examples/misc_boxselection.html @@ -36,7 +36,8 @@ @@ -45,10 +46,10 @@ import * as THREE from 'bmap-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 8080293ce983a5..13c3a3e0acaa5a 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 'bmap-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 147983e1613c96..1d26bbe0505ddb 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 'bmap-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 0ef5771f3b9150..0399c4e286b227 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 'bmap-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 8720a6fdf6d4c8..15b3b1f7c24aad 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 'bmap-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 6883a70fb00def..8a024a35afea61 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 'bmap-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 e3645e9f38015f..17bf1f69b9e378 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 'bmap-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 0fbf97959c4d7c..6ad2a091803fdd 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 'bmap-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 294d785204c07e..915132e8b9bd48 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 'bmap-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 9ecb08048b6009..fd5c8682e73ed8 100644 --- a/examples/misc_exporter_draco.html +++ b/examples/misc_exporter_draco.html @@ -11,7 +11,7 @@ three.js webgl - exporter - draco - + @@ -20,7 +20,8 @@ @@ -29,9 +30,9 @@ import * as THREE from 'bmap-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 a8af830a27810a..b080891a0a7274 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 'bmap-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 { GLTFExporter } from 'three/addons/exporters/GLTFExporter.js'; + import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.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 }; @@ -99,18 +99,17 @@ let container; let camera, object, object2, material, geometry, scene1, scene2, renderer; - let gridHelper, sphere, waltHead; + let gridHelper, sphere, model; const params = { trs: false, onlyVisible: true, - truncateDrawRange: true, binary: false, maxTextureSize: 4096, exportScene1: exportScene1, exportScenes: exportScenes, exportSphere: exportSphere, - exportHead: exportHead, + exportModel: exportModel, exportObjects: exportObjects, exportSceneObject: exportSceneObject }; @@ -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 // --------------------------------------------------------------------- @@ -454,19 +415,18 @@ scene1.add( object ); // --------------------------------------------------------------------- - // - // - const loader = new OBJLoader(); - loader.load( 'models/obj/walt/WaltHead.obj', function ( obj ) { + // Model requiring KHR_mesh_quantization + // --------------------------------------------------------------------- + const loader = new GLTFLoader(); + loader.load( 'models/gltf/ShaderBall.glb', function ( gltf ) { - waltHead = obj; - waltHead.scale.multiplyScalar( 1.5 ); - waltHead.position.set( 400, 0, 0 ); - scene1.add( waltHead ); + model = gltf.scene; + model.scale.setScalar( 50 ); + model.position.set( 200, - 40, - 200 ); + scene1.add( model ); } ); - // --------------------------------------------------------------------- // 2nd THREE.Scene // --------------------------------------------------------------------- @@ -482,6 +442,9 @@ renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); + renderer.outputEncoding = THREE.sRGBEncoding; + renderer.toneMapping = THREE.ACESFilmicToneMapping; + renderer.toneMappingExposure = 1; container.appendChild( renderer.domElement ); @@ -494,7 +457,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 ); @@ -502,7 +464,7 @@ h.add( params, 'exportScene1' ).name( 'Export Scene 1' ); h.add( params, 'exportScenes' ).name( 'Export Scene 1 and 2' ); h.add( params, 'exportSphere' ).name( 'Export Sphere' ); - h.add( params, 'exportHead' ).name( 'Export Head' ); + h.add( params, 'exportModel' ).name( 'Export Model' ); h.add( params, 'exportObjects' ).name( 'Export Sphere With Grid' ); h.add( params, 'exportSceneObject' ).name( 'Export Scene 1 and Object' ); @@ -528,9 +490,9 @@ } - function exportHead() { + function exportModel() { - exportGLTF( waltHead ); + exportGLTF( model ); } diff --git a/examples/misc_exporter_obj.html b/examples/misc_exporter_obj.html index 6f18c6a6a449ae..e57a6392cdd618 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 'bmap-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 05414a1b6eef45..a3dd5f121df601 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 'bmap-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 161f3927e570cf..755a4450320b52 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 'bmap-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 767c40ffcc2077..41cd9ed80cb9e3 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 'bmap-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 839f873ba6beed..105bb37821cea9 100644 --- a/examples/misc_lookat.html +++ b/examples/misc_lookat.html @@ -26,7 +26,8 @@ @@ -35,7 +36,7 @@ import * as THREE from 'bmap-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 38ebb8a815dc33..48725895d0ae63 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 'bmap-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/AVIFTest/DamagedHelmetAVIF.glb b/examples/models/gltf/AVIFTest/DamagedHelmetAVIF.glb new file mode 100644 index 00000000000000..948c6031d45412 Binary files /dev/null and b/examples/models/gltf/AVIFTest/DamagedHelmetAVIF.glb differ diff --git a/examples/models/gltf/AVIFTest/avif-test.avif b/examples/models/gltf/AVIFTest/avif-test.avif new file mode 100644 index 00000000000000..2e0906dba04168 Binary files /dev/null and b/examples/models/gltf/AVIFTest/avif-test.avif differ diff --git a/examples/models/gltf/AVIFTest/avif-test.bin b/examples/models/gltf/AVIFTest/avif-test.bin new file mode 100644 index 00000000000000..3fb577fea5213c Binary files /dev/null and b/examples/models/gltf/AVIFTest/avif-test.bin differ diff --git a/examples/models/gltf/AVIFTest/avif-test.gltf b/examples/models/gltf/AVIFTest/avif-test.gltf new file mode 100644 index 00000000000000..26c407f4cc42d8 --- /dev/null +++ b/examples/models/gltf/AVIFTest/avif-test.gltf @@ -0,0 +1,134 @@ +{ + "asset": { + "generator": "Khronos glTF Blender I/O v3.4.50", + "version": "2.0" + }, + "extensionsUsed": ["EXT_texture_avif"], + "extensionsRequired": ["EXT_texture_avif"], + "scene": 0, + "scenes": [ + { + "name": "Scene", + "nodes": [0] + } + ], + "nodes": [ + { + "mesh": 0, + "name": "Cube" + } + ], + "materials": [ + { + "doubleSided": true, + "name": "Material", + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 0 + }, + "metallicFactor": 0, + "roughnessFactor": 0 + } + } + ], + "meshes": [ + { + "name": "Cube", + "primitives": [ + { + "attributes": { + "POSITION": 0, + "TEXCOORD_0": 1, + "NORMAL": 2 + }, + "indices": 3, + "material": 0 + } + ] + } + ], + "textures": [ + { + "extensions": { + "EXT_texture_avif": { + "source": 0 + } + }, + "sampler": 0, + "source": 0 + } + ], + "images": [ + { + "mimeType": "image/avif", + "name": "avif-test", + "uri": "avif-test.avif" + } + ], + "accessors": [ + { + "bufferView": 0, + "componentType": 5126, + "count": 864, + "max": [1, 1, 1], + "min": [-1, -1, -1], + "type": "VEC3" + }, + { + "bufferView": 1, + "componentType": 5126, + "count": 864, + "type": "VEC2" + }, + { + "bufferView": 2, + "componentType": 5126, + "count": 864, + "type": "VEC3" + }, + { + "bufferView": 3, + "componentType": 5123, + "count": 1284, + "type": "SCALAR" + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteLength": 10368, + "byteOffset": 0, + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 6912, + "byteOffset": 10368, + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 10368, + "byteOffset": 17280, + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 2568, + "byteOffset": 27648, + "target": 34963 + } + ], + "samplers": [ + { + "magFilter": 9729, + "minFilter": 9987 + } + ], + "buffers": [ + { + "byteLength": 30216, + "uri": "avif-test.bin" + } + ] +} 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/IridescenceLamp.glb b/examples/models/gltf/IridescenceLamp.glb new file mode 100644 index 00000000000000..66db017183807d Binary files /dev/null and b/examples/models/gltf/IridescenceLamp.glb differ diff --git a/examples/models/gltf/ShaderBall.glb b/examples/models/gltf/ShaderBall.glb new file mode 100644 index 00000000000000..adfc9189baf83b Binary files /dev/null and b/examples/models/gltf/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/singlePointTest.svg b/examples/models/svg/singlePointTest.svg new file mode 100644 index 00000000000000..a0f997aa08086e --- /dev/null +++ b/examples/models/svg/singlePointTest.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/examples/models/svg/singlePointTest2.svg b/examples/models/svg/singlePointTest2.svg new file mode 100644 index 00000000000000..394d0df1a0a564 --- /dev/null +++ b/examples/models/svg/singlePointTest2.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/examples/models/svg/singlePointTest3.svg b/examples/models/svg/singlePointTest3.svg new file mode 100644 index 00000000000000..90b644fd638077 --- /dev/null +++ b/examples/models/svg/singlePointTest3.svg @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file 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/svg/tests/roundJoinPrecisionIssue.svg b/examples/models/svg/tests/roundJoinPrecisionIssue.svg new file mode 100644 index 00000000000000..96f8f9b2d478b8 --- /dev/null +++ b/examples/models/svg/tests/roundJoinPrecisionIssue.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/models/svg/tests/styles.svg b/examples/models/svg/tests/styles.svg new file mode 100644 index 00000000000000..331e81922f3637 --- /dev/null +++ b/examples/models/svg/tests/styles.svg @@ -0,0 +1 @@ + Aperture \ No newline at end of file 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 f05b796d85b6d0..07d78a5e09912e 100644 --- a/examples/physics_ammo_break.html +++ b/examples/physics_ammo_break.html @@ -15,7 +15,7 @@
          Physics threejs demo with convex objects breaking in real time
          Press mouse to throw balls and move the camera.
          - + @@ -24,7 +24,8 @@ @@ -32,11 +33,11 @@ + @@ -23,7 +23,8 @@ @@ -32,9 +33,9 @@ import * as THREE from 'bmap-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 2af291d435980f..313edbc756a148 100644 --- a/examples/physics_ammo_instancing.html +++ b/examples/physics_ammo_instancing.html @@ -12,7 +12,7 @@ three.js physics - ammo.js instancing - + @@ -21,17 +21,25 @@ + @@ -23,7 +23,8 @@ @@ -31,9 +32,9 @@ + @@ -24,7 +24,8 @@ @@ -33,9 +34,9 @@ import * as THREE from 'bmap-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 c8ecac719eec61..fac7bbdaf6b46d 100644 --- a/examples/physics_ammo_volume.html +++ b/examples/physics_ammo_volume.html @@ -17,7 +17,7 @@
          - + @@ -26,7 +26,8 @@ @@ -35,10 +36,10 @@ import * as THREE from 'bmap-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 570c63b085fae8..e0fbab89724023 100644 --- a/examples/physics_oimo_instancing.html +++ b/examples/physics_oimo_instancing.html @@ -20,17 +20,25 @@ @@ -33,7 +34,7 @@ import * as THREE from 'bmap-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 760db0647530cd..754bddb8d0852b 100644 --- a/examples/svg_sandbox.html +++ b/examples/svg_sandbox.html @@ -20,7 +20,8 @@ @@ -29,9 +30,9 @@ import * as THREE from 'bmap-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 fe0c88e5489da7..3418da88f96467 100644 --- a/examples/tags.json +++ b/examples/tags.json @@ -9,6 +9,7 @@ "webgl_geometries": [ "geometry" ], "webgl_geometries_parametric": [ "geometry" ], "webgl_geometry_colors_lookuptable": [ "vertex" ], + "webgl_geometry_csg": [ "external", "csg", "bvh", "constructive", "solid", "geometry", "games", "level" ], "webgl_geometry_nurbs": [ "curve", "surface" ], "webgl_geometry_spline_editor": [ "curve" ], "webgl_geometry_terrain": [ "fog" ], @@ -33,6 +34,7 @@ "webgl_loader_ttf": [ "text", "font" ], "webgl_loader_pdb": [ "molecules", "css2d" ], "webgl_loader_ldraw": [ "lego" ], + "webgl_loader_ifc": [ "external" ], "webgl_lod": [ "level", "details" ], "webgl_materials_blending": [ "alpha" ], "webgl_materials_blending_custom": [ "alpha" ], @@ -52,6 +54,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" ], @@ -71,7 +74,6 @@ "webgl_shadowmap_viewer": [ "directional", "spot" ], "webgl_skinning_simple": [ "animation" ], "webgl_tonemapping": [ "gltf" ], - "webgl_loader_nodes": [ "caustics", "displace", "xray" ], "webgl_postprocessing_afterimage": [ "trails" ], "webgl_postprocessing_dof": [ "bokeh" ], "webgl_postprocessing_dof2": [ "bokeh" ], @@ -88,12 +90,13 @@ "webgl_postprocessing_unreal_bloom_selective": [ "glow" ], "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" ], "webgl_tiled_forward": [ "derivatives" ], "webgl2_multiple_rendertargets": [ "mrt" ], - "webgl2_multiple_rendertargets_multisampled": [ "mrt" ], "webgl2_multisampled_renderbuffers": [ "msaa" ], "physics_ammo_cloth": [ "integration" ], "misc_controls_arcball": [ "rotation" ], 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/compressed/canestra_di_frutta_caravaggio.basis b/examples/textures/compressed/canestra_di_frutta_caravaggio.basis deleted file mode 100644 index d8a9839e8d7cdd..00000000000000 Binary files a/examples/textures/compressed/canestra_di_frutta_caravaggio.basis and /dev/null differ diff --git a/examples/textures/equirectangular/blouberg_sunrise_2_1k.hdr b/examples/textures/equirectangular/blouberg_sunrise_2_1k.hdr new file mode 100644 index 00000000000000..a35949f9ebe07c Binary files /dev/null and b/examples/textures/equirectangular/blouberg_sunrise_2_1k.hdr 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/opengameart/smoke1.png b/examples/textures/opengameart/smoke1.png new file mode 100644 index 00000000000000..8fa2076998f260 Binary files /dev/null and b/examples/textures/opengameart/smoke1.png 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 8c1c42125ab908..5f9a783a8a8a2b 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 'bmap-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 21637e8a789754..61313581303506 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 f907381efeb164..248235da504356 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 'bmap-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 dd02cb9fa1397b..fdf8cf4828668e 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 'bmap-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 c991e6852cb042..5ebce59f50bb15 100644 --- a/examples/webgl2_materials_texture3d.html +++ b/examples/webgl2_materials_texture3d.html @@ -20,7 +20,8 @@ @@ -28,11 +29,11 @@ @@ -121,13 +119,24 @@ import * as THREE from 'bmap-three'; - import WebGL from './jsm/capabilities/WebGL.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.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; let postScene, postCamera; + const parameters = { + samples: 4, + wireframe: false + }; + + const gui = new GUI(); + gui.add( parameters, 'samples', 0, 4 ).step( 1 ); + gui.add( parameters, 'wireframe' ); + gui.onChange( render ); + init(); function init() { @@ -156,7 +165,6 @@ renderTarget.texture[ i ].minFilter = THREE.NearestFilter; renderTarget.texture[ i ].magFilter = THREE.NearestFilter; - renderTarget.texture[ i ].type = THREE.FloatType; } @@ -168,27 +176,19 @@ // Scene setup scene = new THREE.Scene(); + scene.background = new THREE.Color( 0x222222 ); - camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10 ); + camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 50 ); camera.position.z = 4; - const diffuse = new THREE.TextureLoader().load( - - 'textures/brick_diffuse.jpg', - - function () { - - // ready to render - render(); - - } - - ); + const loader = new THREE.TextureLoader(); - diffuse.wrapS = diffuse.wrapT = THREE.RepeatWrapping; + const diffuse = loader.load( 'textures/hardwood2_diffuse.jpg', render ); + diffuse.wrapS = THREE.RepeatWrapping; + diffuse.wrapT = THREE.RepeatWrapping; scene.add( new THREE.Mesh( - new THREE.TorusKnotGeometry( 1, 0.3, 128, 64 ), + new THREE.TorusKnotGeometry( 1, 0.3, 128, 32 ), new THREE.RawShaderMaterial( { vertexShader: document.querySelector( '#gbuffer-vert' ).textContent.trim(), fragmentShader: document.querySelector( '#gbuffer-frag' ).textContent.trim(), @@ -222,8 +222,7 @@ controls = new OrbitControls( camera, renderer.domElement ); controls.addEventListener( 'change', render ); - controls.enableZoom = false; - controls.screenSpacePanning = true; + //controls.enableZoom = false; window.addEventListener( 'resize', onWindowResize ); @@ -245,6 +244,18 @@ function render() { + renderTarget.samples = parameters.samples; + + scene.traverse( function ( child ) { + + if ( child.material !== undefined ) { + + child.material.wireframe = parameters.wireframe; + + } + + } ); + // render scene into target renderer.setRenderTarget( renderTarget ); renderer.render( scene, camera ); diff --git a/examples/webgl2_multiple_rendertargets_multisampled.html b/examples/webgl2_multiple_rendertargets_multisampled.html deleted file mode 100644 index 7f69a290f058fb..00000000000000 --- a/examples/webgl2_multiple_rendertargets_multisampled.html +++ /dev/null @@ -1,337 +0,0 @@ - - - - three.js webgl - Multiple Render Targets MultiSampled - - - - - - - - - - - - - - -
          - threejs - WebGL - Multiple Render Targets Multisampled
          - Created by @onirenaud with the help of @Cody_J_Bennett. -
          -
          -
          - - - - - - - - - - diff --git a/examples/webgl2_multisampled_renderbuffers.html b/examples/webgl2_multisampled_renderbuffers.html index 6efe5353efa2f3..0b19859ed1897a 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 'bmap-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 927bd866ef1d18..9408a286d62e60 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 'bmap-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..bdb314300ee8e5 --- /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 new file mode 100644 index 00000000000000..f8f822a3617047 --- /dev/null +++ b/examples/webgl2_ubo.html @@ -0,0 +1,348 @@ + + + + three.js WebGL 2 - Uniform Buffer Objects + + + + + + + +
          + three.js - Uniform Buffer Objects +
          +
          + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/webgl2_volume_cloud.html b/examples/webgl2_volume_cloud.html index b9b994cb4f74c8..637e45275508cc 100644 --- a/examples/webgl2_volume_cloud.html +++ b/examples/webgl2_volume_cloud.html @@ -19,18 +19,25 @@ @@ -43,13 +44,13 @@ import * as THREE from 'bmap-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; @@ -81,7 +82,7 @@ controls.enableDamping = true; const dracoLoader = new DRACOLoader(); - dracoLoader.setDecoderPath( 'js/libs/draco/gltf/' ); + dracoLoader.setDecoderPath( 'jsm/libs/draco/gltf/' ); const loader = new GLTFLoader(); loader.setDRACOLoader( dracoLoader ); diff --git a/examples/webgl_animation_multiple.html b/examples/webgl_animation_multiple.html index 29b1c7d04fa321..1e6b79242935c0 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 'bmap-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 63ad823e0eca9c..83959cec0e05d8 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 'bmap-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,7 +204,11 @@ const currentAction = currentSettings ? currentSettings.action : null; const action = settings ? settings.action : null; - prepareCrossFade( currentAction, action, 0.35 ); + 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 74dcb0712700b4..c9193361e033a6 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 'bmap-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..7a2bb2cc148fc9 --- /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 25850941ef66a8..50be86198c1224 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 'bmap-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 22527956b252be..597ae974fa6ec3 100644 --- a/examples/webgl_buffergeometry.html +++ b/examples/webgl_buffergeometry.html @@ -18,7 +18,8 @@ @@ -27,7 +28,7 @@ import * as THREE from 'bmap-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 ba0fc44e548bf3..0abc9418a0428d 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 'bmap-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,16 @@ // options const data = { - "model": "Icosahedron", - "wireframe": false, - "texture": false, - "detail": 4, - "rotationSpeed": 0.1, + 'model': 'Icosahedron', + 'wireframe': false, + 'texture': false, + 'detail': 4, - "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; @@ -64,7 +64,7 @@ // materials const lineMaterial = new THREE.LineBasicMaterial( { color: 0xaaaaaa, transparent: true, opacity: 0.8 } ); - const meshMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff, emissive: 0x111111 } ); + const meshMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff, side: THREE.DoubleSide } ); // texture const texture = new THREE.TextureLoader().load( 'textures/uv_grid_opengl.jpg' ); @@ -79,6 +79,7 @@ function init() { // + container = document.createElement( 'div' ); document.body.appendChild( container ); @@ -91,18 +92,20 @@ scene = new THREE.Scene(); - camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.01, 10000000 ); - camera.position.x = 2 * radius; - camera.position.y = 2 * radius; - camera.position.z = 2 * radius; + camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 ); + camera.position.setScalar( 2 * radius ); controls = new OrbitControls( camera, renderer.domElement ); + controls.enablePan = false; + controls.enableZoom = false; // + + scene.add( new THREE.AmbientLight( 0xffffff, 0.1 ) ); - lights[ 0 ] = new THREE.PointLight( 0xffffff, 1, 0 ); - lights[ 1 ] = new THREE.PointLight( 0xffffff, 1, 0 ); - lights[ 2 ] = new THREE.PointLight( 0xffffff, 1, 0 ); + lights[ 0 ] = new THREE.DirectionalLight( 0xffffff, 0.7 ); + lights[ 1 ] = new THREE.DirectionalLight( 0xffffff, 0.7 ); + lights[ 2 ] = new THREE.DirectionalLight( 0xffffff, 0.7 ); lights[ 0 ].position.set( 0, 2 * radius, 0 ); lights[ 1 ].position.set( 2 * radius, - 2 * radius, 2 * radius ); @@ -121,10 +124,11 @@ let geom = newGeometry( data ); const mesh = new THREE.Mesh( geom, meshMaterial ); + scene.add( mesh ); + const lineSegments = new THREE.LineSegments( new THREE.WireframeGeometry( geom ), lineMaterial ); lineSegments.visible = data.wireframe; - scene.add( mesh ); scene.add( lineSegments ); // @@ -136,16 +140,16 @@ switch ( data.model ) { - case "Icosahedron": + case 'Icosahedron': return new THREE.IcosahedronGeometry( radius, data.detail ); - case "Cylinder": - return new THREE.CylinderGeometry( radius, radius, radius * 2, data.detail * 6 ); - case "Teapot": - return new TeapotGeometry( radius, data.detail * 3, true, true, true, true, true ); - case "TorusKnot": - return new THREE.TorusKnotGeometry( radius, 10, data.detail * 20, data.detail * 6, 3, 4 ); + case 'Cylinder': + return new THREE.CylinderGeometry( radius / 1.5, radius / 1.5, radius, data.detail * 6 ); + case 'Teapot': + return new TeapotGeometry( radius / 1.5, data.detail * 3, true, true, true, true, true ); + case 'TorusKnot': + return new THREE.TorusKnotGeometry( radius / 2, 10, data.detail * 30, data.detail * 6, 3, 4 ); - } + } } @@ -153,15 +157,10 @@ geom = newGeometry( data ); - updateGroupGeometry( - mesh, - lineSegments, - geom, - data ); + updateGroupGeometry( mesh, lineSegments, geom, data ); } - // updateLineSegments function updateLineSegments() { lineSegments.visible = data.wireframe; @@ -169,11 +168,10 @@ } 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 ); - folder.add( data, 'rotationSpeed', 0, 0.5, 0.1 ); folder.open(); folder = gui.addFolder( 'Position Compression' ); @@ -181,7 +179,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 +188,7 @@ folder = gui.addFolder( 'Memory Info' ); folder.open(); - memoryDisplay = folder.add( data, 'totalGPUMemory', "0 bytes" ); + memoryDisplay = folder.add( data, 'totalGPUMemory', '0 bytes' ); computeGPUMemory( mesh ); // @@ -213,20 +211,8 @@ renderer.setSize( window.innerWidth, window.innerHeight ); camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - } - // - function updateLightsPossition() { - - lights.forEach( light => { - - const direction = light.position.clone(); - direction.applyAxisAngle( new THREE.Vector3( 1, 1, 0 ), data.rotationSpeed / 180 * Math.PI ); - light.position.add( direction.sub( light.position ) ); - - } ); + camera.updateProjectionMatrix(); } @@ -236,9 +222,6 @@ requestAnimationFrame( animate ); - controls.update(); - updateLightsPossition(); - renderer.render( scene, camera ); if ( statsEnabled ) stats.update(); @@ -250,27 +233,30 @@ function updateGroupGeometry( mesh, lineSegments, geometry, data ) { // dispose first + lineSegments.geometry.dispose(); mesh.geometry.dispose(); + mesh.material.dispose(); + if ( mesh.material.map ) mesh.material.map.dispose(); lineSegments.geometry = new THREE.WireframeGeometry( geometry ); mesh.geometry = geometry; - mesh.material = new THREE.MeshPhongMaterial( { color: 0xffffff, emissive: 0x111111 } ); + mesh.material = new THREE.MeshPhongMaterial( { color: 0xffffff, side: THREE.DoubleSide } ); 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 +270,8 @@ 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 4bb77987967a50..8527bc0b54cbdf 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 'bmap-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 0bd335ad399ceb..368cd752ce0524 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 'bmap-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 822d3110ee106a..bd5738302f23af 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 'bmap-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 e1b84f65c994c6..07b3119d90daa8 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 'bmap-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 8ffd8c2b84bf18..5f03a4f4b1eb62 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 'bmap-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 3445855dc5f541..214a289e9b22d3 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 'bmap-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 0249562ba0d942..a127ad4a05db94 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 'bmap-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 092324678eeb29..7f70caa5c7ab14 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 'bmap-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 241687e7566036..86b567bd46afed 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 'bmap-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 1c15b1130482c2..c51f51a514187e 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 'bmap-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 9089cf0d4027de..9fb153e587249f 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 'bmap-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 68c5c119424e8c..7623a82f87ad0a 100644 --- a/examples/webgl_camera.html +++ b/examples/webgl_camera.html @@ -23,7 +23,8 @@ @@ -32,7 +33,7 @@ import * as THREE from 'bmap-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 7127a6fd9663bd..6914ee04f0d706 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 6bb6dd50e5e410..7b3a12e44692cf 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 'bmap-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 bdd5c354102428..78310f2143e206 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 'bmap-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 235b792acec4cf..25a2e7361dff83 100644 --- a/examples/webgl_clipping.html +++ b/examples/webgl_clipping.html @@ -15,7 +15,8 @@ @@ -24,10 +25,10 @@ import * as THREE from 'bmap-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 99ad9057092474..b900c64c6ab6b1 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 'bmap-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 c134c949b9e8dc..d301c1f29166eb 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 'bmap-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 f9afc415861f7c..1b5b8bf2776bef 100644 --- a/examples/webgl_clipping_stencil.html +++ b/examples/webgl_clipping_stencil.html @@ -17,16 +17,24 @@ @@ -72,7 +73,7 @@ import * as THREE from 'bmap-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 5d9a8efebdc64e..8579a59f6028df 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 'bmap-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 5b4377c2db2a9b..24409f05015c9b 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 'bmap-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 26b62613f59179..396f1838ab5066 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 'bmap-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 7e43e3c93b43e0..91ae84c683b8ae 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 'bmap-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 4b4b6ed2c39886..5a38bc866e6e29 100644 --- a/examples/webgl_decals.html +++ b/examples/webgl_decals.html @@ -21,7 +21,8 @@ @@ -30,12 +31,12 @@ import * as THREE from 'bmap-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 8326aba559897e..a0a31422f38a60 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 'bmap-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 3687b500c3b900..246758da9a1644 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 'bmap-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 9ab84b0669970e..356d4b6e55e258 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 'bmap-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 aa8e439b30b000..6ffe28a8f03bfa 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 'bmap-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 59579d92f349c6..2eb3d6e7a5901f 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 'bmap-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 9d733d03d72a28..c0d3dc502352f1 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 'bmap-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 ad99dde8aebfe6..d51cb6f6891414 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 'bmap-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 73492b00d5f763..0c379e323e5d85 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 1baebfe77619a0..f53265bb17a25c 100644 --- a/examples/webgl_geometries.html +++ b/examples/webgl_geometries.html @@ -17,7 +17,8 @@ @@ -26,7 +27,7 @@ import * as THREE from 'bmap-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 b49dde18ca82b4..278843b6b17561 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 'bmap-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 3ee998dadeb1ec..be286ec8ffffab 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 'bmap-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 f0dc319bb8717f..a5e512c74c207a 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 'bmap-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 a8fdaf3763175d..49536b2dc6b2c8 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 'bmap-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; @@ -101,12 +102,10 @@ } const pointsMaterial = new THREE.PointsMaterial( { - color: 0x0080ff, map: texture, size: 1, alphaTest: 0.5 - } ); const pointsGeometry = new THREE.BufferGeometry().setFromPoints( vertices ); @@ -119,20 +118,14 @@ const meshMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, opacity: 0.5, + side: THREE.DoubleSide, transparent: true } ); const meshGeometry = new ConvexGeometry( vertices ); - const mesh1 = new THREE.Mesh( meshGeometry, meshMaterial ); - mesh1.material.side = THREE.BackSide; // back faces - mesh1.renderOrder = 0; - group.add( mesh1 ); - - const mesh2 = new THREE.Mesh( meshGeometry, meshMaterial.clone() ); - mesh2.material.side = THREE.FrontSide; // front faces - mesh2.renderOrder = 1; - group.add( mesh2 ); + const mesh = new THREE.Mesh( meshGeometry, meshMaterial ); + group.add( mesh ); // diff --git a/examples/webgl_geometry_csg.html b/examples/webgl_geometry_csg.html new file mode 100644 index 00000000000000..6cd7321fe077d4 --- /dev/null +++ b/examples/webgl_geometry_csg.html @@ -0,0 +1,234 @@ + + + + three.js geometry - csg + + + + + + + +
          + three.js bvh csg - three-bvh-csg
          + See main project repository for more information and examples on constructive solid geometry. +
          + + + + + + + + + + + diff --git a/examples/webgl_geometry_cube.html b/examples/webgl_geometry_cube.html index 4f856661d7d43c..b2197629d1dd20 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 c3832634491ab2..c33ee1d484ac19 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 'bmap-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 63ea369af9e4ec..e5facaf0e3e232 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 'bmap-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 b3cfd0f0328083..38fe75afbe36dd 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 'bmap-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 9f609dfbdf73d2..ca461f5b1390f8 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 'bmap-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 25a3548c8ae1b6..37df6eccc8bb7c 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 'bmap-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 6392174de57f33..9aa7b8d790949f 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 'bmap-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 8d5a14b98204eb..601016b8e574f3 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 'bmap-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 4d8c8550a8d18a..87ea43e69f70f5 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 'bmap-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 d731b997393637..c8898050898889 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 'bmap-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 19020ad4a206e5..d236d2832f983e 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 'bmap-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 6b54ead6e06a3a..6a44892a92c96a 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 'bmap-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 82b7341794051c..307e26088fcf35 100644 --- a/examples/webgl_geometry_text.html +++ b/examples/webgl_geometry_text.html @@ -10,12 +10,7 @@
          three.js - procedural 3D text
          - type to enter new text, drag to spin the text
          - - - -
          - + type to enter new text, drag to spin the text
          @@ -25,7 +20,8 @@ @@ -34,14 +30,14 @@ import * as THREE from 'bmap-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 { GUI } from 'three/addons/libs/lil-gui.module.min.js'; THREE.Cache.enabled = true; - let container, stats, permalink, hex; + let container; let camera, cameraTarget, scene, renderer; @@ -105,21 +101,11 @@ init(); animate(); - function decimalToHex( d ) { - - let hex = Number( d ).toString( 16 ); - hex = '000000'.substring( 0, 6 - hex.length ) + hex; - return hex.toUpperCase(); - - } - function init() { container = document.createElement( 'div' ); document.body.appendChild( container ); - permalink = document.getElementById( 'permalink' ); - // CAMERA camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 1, 1500 ); @@ -140,40 +126,10 @@ scene.add( dirLight ); const pointLight = new THREE.PointLight( 0xffffff, 1.5 ); + pointLight.color.setHSL( Math.random(), 1, 0.5 ); pointLight.position.set( 0, 100, 90 ); scene.add( pointLight ); - // Get text from hash - - const hash = document.location.hash.slice( 1 ); - - if ( hash.length !== 0 ) { - - const colorhash = hash.substring( 0, 6 ); - const fonthash = hash.substring( 6, 7 ); - const weighthash = hash.substring( 7, 8 ); - const bevelhash = hash.substring( 8, 9 ); - const texthash = hash.substring( 10 ); - - hex = colorhash; - pointLight.color.setHex( parseInt( colorhash, 16 ) ); - - fontName = reverseFontMap[ parseInt( fonthash ) ]; - fontWeight = reverseWeightMap[ parseInt( weighthash ) ]; - - bevelEnabled = parseInt( bevelhash ); - - text = decodeURI( texthash ); - - updatePermalink(); - - } else { - - pointLight.color.setHSL( Math.random(), 1, 0.5 ); - hex = decimalToHex( pointLight.color.getHex() ); - - } - materials = [ new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true } ), // front new THREE.MeshPhongMaterial( { color: 0xffffff } ) // side @@ -201,11 +157,6 @@ renderer.setSize( window.innerWidth, window.innerHeight ); container.appendChild( renderer.domElement ); - // STATS - - stats = new Stats(); - //container.appendChild( stats.dom ); - // EVENTS container.style.touchAction = 'none'; @@ -214,49 +165,56 @@ document.addEventListener( 'keypress', onDocumentKeyPress ); document.addEventListener( 'keydown', onDocumentKeyDown ); - document.getElementById( 'color' ).addEventListener( 'click', function () { + // - pointLight.color.setHSL( Math.random(), 1, 0.5 ); - hex = decimalToHex( pointLight.color.getHex() ); + const params = { + changeColor: function () { - updatePermalink(); + pointLight.color.setHSL( Math.random(), 1, 0.5 ); - } ); + }, + changeFont: function () { - document.getElementById( 'font' ).addEventListener( 'click', function () { + fontIndex ++; - fontIndex ++; + fontName = reverseFontMap[ fontIndex % reverseFontMap.length ]; - fontName = reverseFontMap[ fontIndex % reverseFontMap.length ]; + loadFont(); - loadFont(); + }, + changeWeight: function () { - } ); + if ( fontWeight === 'bold' ) { + fontWeight = 'regular'; - document.getElementById( 'weight' ).addEventListener( 'click', function () { + } else { - if ( fontWeight === 'bold' ) { + fontWeight = 'bold'; - fontWeight = 'regular'; + } - } else { + loadFont(); - fontWeight = 'bold'; - - } + }, + changeBevel: function () { - loadFont(); + bevelEnabled = ! bevelEnabled; - } ); + refreshText(); - document.getElementById( 'bevel' ).addEventListener( 'click', function () { + } + }; - bevelEnabled = ! bevelEnabled; + // - refreshText(); + const gui = new GUI(); - } ); + gui.add( params, 'changeColor' ).name( 'change color' ); + gui.add( params, 'changeFont' ).name( 'change font' ); + gui.add( params, 'changeWeight' ).name( 'change weight' ); + gui.add( params, 'changeBevel' ).name( 'change bevel' ); + gui.open(); // @@ -277,21 +235,6 @@ // - function boolToNum( b ) { - - return b ? 1 : 0; - - } - - function updatePermalink() { - - const link = hex + fontMap[ fontName ] + weightMap[ fontWeight ] + boolToNum( bevelEnabled ) + '#' + encodeURI( text ); - - permalink.href = '#' + link; - window.location.hash = link; - - } - function onDocumentKeyDown( event ) { if ( firstLetter ) { @@ -402,8 +345,6 @@ function refreshText() { - updatePermalink(); - group.remove( textMesh1 ); if ( mirror ) group.remove( textMesh2 ); @@ -451,7 +392,6 @@ requestAnimationFrame( animate ); render(); - stats.update(); } diff --git a/examples/webgl_geometry_text_shapes.html b/examples/webgl_geometry_text_shapes.html index 657e47294221e0..79ae017a246073 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 'bmap-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 416a9dfd4d234a..2cb99114aa7ecb 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 'bmap-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 c54005ab4b1251..4939ce20f57cc6 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 'bmap-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 e4f89c43e9d2c1..cbdb7adc112579 100644 --- a/examples/webgl_gpgpu_birds_gltf.html +++ b/examples/webgl_gpgpu_birds_gltf.html @@ -214,18 +214,27 @@ @@ -244,11 +245,11 @@ import * as THREE from 'bmap-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 da2c52925348d8..623c4318acb08a 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 'bmap-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 8863e7038c2ca4..a3b1fe7b6f381d 100644 --- a/examples/webgl_helpers.html +++ b/examples/webgl_helpers.html @@ -18,7 +18,8 @@ @@ -27,10 +28,10 @@ import * as THREE from 'bmap-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 5a54ad540f9321..39f9935b920f5c 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 'bmap-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 ddccec2306ba0a..4308ccba7d8506 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 'bmap-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 14cfd508cb4917..bb78182caf3b70 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 'bmap-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 dfe39378698b1d..446936cecdc3d7 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 'bmap-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 eadb11d12e3ab7..17973f52ec36ea 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 'bmap-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 57532725e4f9f3..9d1b0312126908 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 'bmap-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 b4b8d68050a008..5ed6882f47f992 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 'bmap-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 6e833bec546ece..bc4b3e0354f08b 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 'bmap-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 e05e74357bd01a..7e4371ae6916e1 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 'bmap-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 edef79a8e444a8..ad9a7edda03050 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 'bmap-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 b200269c3694f3..69395e2fb20939 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 b64819d86e8919..99049ffcbfec7b 100644 --- a/examples/webgl_layers.html +++ b/examples/webgl_layers.html @@ -28,7 +28,8 @@ @@ -37,8 +38,8 @@ import * as THREE from 'bmap-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 b940530f8117a5..2a0e97da5de9d3 100644 --- a/examples/webgl_lensflares.html +++ b/examples/webgl_lensflares.html @@ -21,7 +21,8 @@ @@ -30,10 +31,10 @@ import * as THREE from 'bmap-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 68ad9771a2a723..a08446aff8793a 100644 --- a/examples/webgl_lightningstrike.html +++ b/examples/webgl_lightningstrike.html @@ -18,7 +18,8 @@ @@ -27,15 +28,15 @@ import * as THREE from 'bmap-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 6ec91233f5fbf7..9cc623fa1a8ccf 100644 --- a/examples/webgl_lightprobe.html +++ b/examples/webgl_lightprobe.html @@ -19,7 +19,8 @@ @@ -28,10 +29,10 @@ import * as THREE from 'bmap-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 eb878e512cc64b..8df72530434833 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 'bmap-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 23dc2c040a87b5..b35f98d9f15cea 100644 --- a/examples/webgl_lights_hemisphere.html +++ b/examples/webgl_lights_hemisphere.html @@ -19,9 +19,7 @@
          three.js - webgl hemisphere light example
          - flamingo by mirada from ro.me

          - - + flamingo by mirada from ro.me
          @@ -73,10 +72,10 @@ import * as THREE from 'bmap-three'; - import Stats from './jsm/libs/stats.module.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 { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; let camera, scene, renderer; const mixers = []; @@ -212,23 +211,30 @@ // - window.addEventListener( 'resize', onWindowResize ); + const params = { + toggleHemisphereLight: function () { - const hemisphereButton = document.getElementById( 'hemisphereButton' ); - hemisphereButton.addEventListener( 'click', function () { + hemiLight.visible = ! hemiLight.visible; + hemiLightHelper.visible = ! hemiLightHelper.visible; - hemiLight.visible = ! hemiLight.visible; - hemiLightHelper.visible = ! hemiLightHelper.visible; + }, + toggleDirectionalLight: function () { - } ); + dirLight.visible = ! dirLight.visible; + dirLightHelper.visible = ! dirLightHelper.visible; - const directionalButton = document.getElementById( 'directionalButton' ); - directionalButton.addEventListener( 'click', function () { + } + }; - dirLight.visible = ! dirLight.visible; - dirLightHelper.visible = ! dirLightHelper.visible; + const gui = new GUI(); - } ); + gui.add( params, 'toggleHemisphereLight' ).name( 'toggle hemisphere light' ); + gui.add( params, 'toggleDirectionalLight' ).name( 'toggle directional light' ); + gui.open(); + + // + + window.addEventListener( 'resize', onWindowResize ); } diff --git a/examples/webgl_lights_physical.html b/examples/webgl_lights_physical.html index f22b3e19fa13d4..5c1063f1e5b940 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 'bmap-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 2a2d215033289a..7122d637667ae2 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 'bmap-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 efdfc8cdb6f168..dab6434ad26259 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 'bmap-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 9598b4929b7c48..7f1e0b5ad8c786 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 'bmap-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 248f4c07adf0d7..2e3479b8cb83db 100644 --- a/examples/webgl_lights_spotlights.html +++ b/examples/webgl_lights_spotlights.html @@ -20,21 +20,25 @@ @@ -29,7 +30,7 @@ import * as THREE from 'bmap-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 1320bc94fb2c7d..a8e1eb54effd8b 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 'bmap-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 110dd5bc43852b..bf4f060923aa3c 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 'bmap-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 ddfc4d576d3020..af54c36544e7d1 100644 --- a/examples/webgl_lines_fat_raycasting.html +++ b/examples/webgl_lines_fat_raycasting.html @@ -20,7 +20,8 @@ @@ -29,35 +30,79 @@ import * as THREE from 'bmap-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 renderer, scene, camera, controls; + let sphereInter, sphereOnLine; let stats, gpuPanel; let gui; + let clock; - // viewport - let insetWidth; - let insetHeight; + const color = new THREE.Color(); 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 ); @@ -69,18 +114,11 @@ camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.set( - 40, 0, 60 ); - camera2 = new THREE.PerspectiveCamera( 40, 1, 1, 1000 ); - camera2.position.copy( camera.position ); - controls = new OrbitControls( camera, renderer.domElement ); 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 sphereGeometry = new THREE.SphereGeometry( 0.25, 8, 4 ); const sphereInterMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, depthTest: false } ); const sphereOnLineMaterial = new THREE.MeshBasicMaterial( { color: 0x00ff00, depthTest: false } ); @@ -130,32 +168,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 ); @@ -183,6 +195,7 @@ geo.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); // + document.addEventListener( 'pointermove', onPointerMove ); window.addEventListener( 'resize', onWindowResize ); onWindowResize(); @@ -204,11 +217,9 @@ renderer.setSize( window.innerWidth, window.innerHeight ); - insetWidth = window.innerHeight / 4; // square - insetHeight = window.innerHeight / 4; - - camera2.aspect = insetWidth / insetHeight; - camera2.updateProjectionMatrix(); + // renderer will set this eventually + matLine.resolution.set( window.innerWidth, window.innerHeight ); + matThresholdLine.resolution.set( window.innerWidth, window.innerHeight ); } @@ -225,28 +236,42 @@ stats.update(); - // 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.1; - renderer.setClearColor( 0x000000, 0 ); + segments.rotation.y = line.rotation.y; - renderer.setViewport( 0, 0, window.innerWidth, window.innerHeight ); + } raycaster.setFromCamera( pointer, camera ); - const obj = line.visible ? line : segments; - const intersects = raycaster.intersectObject( obj, true ); + const intersects = raycaster.intersectObject( obj ); if ( intersects.length > 0 ) { sphereInter.visible = true; sphereOnLine.visible = true; + sphereInter.position.copy( intersects[ 0 ].point ); sphereOnLine.position.copy( intersects[ 0 ].pointOnLine ); - const i = intersects[ 0 ].faceIndex; + + const index = intersects[ 0 ].faceIndex; const colors = obj.geometry.getAttribute( 'instanceColorStart' ); - const color = new THREE.Color().setRGB( colors.getX( i ), colors.getY( i ), colors.getZ( i ) ); - sphereInter.material.color.copy( color.clone().offsetHSL( 0.3, 0, 0 ) ); - sphereOnLine.material.color.copy( color.clone().offsetHSL( 0.7, 0, 0 ) ); + + color.fromBufferAttribute( colors, index ); + + sphereInter.material.color.copy( color ).offsetHSL( 0.3, 0, 0 ); + sphereOnLine.material.color.copy( color ).offsetHSL( 0.7, 0, 0 ); + renderer.domElement.style.cursor = 'crosshair'; } else { @@ -257,36 +282,10 @@ } - // 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(); - // inset scene - - renderer.setClearColor( 0x222222, 1 ); - - renderer.clearDepth(); // important! - - renderer.setScissorTest( true ); - - renderer.setScissor( 20, 20, insetWidth, insetHeight ); - - renderer.setViewport( 20, 20, insetWidth, insetHeight ); - - camera2.position.copy( camera.position ); - camera2.quaternion.copy( camera.quaternion ); - - // renderer will set this eventually - matLine.resolution.set( insetWidth, insetHeight ); // resolution of the inset viewport - - renderer.render( scene, camera2 ); - - renderer.setScissorTest( false ); - } // @@ -321,56 +320,57 @@ 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; + matThresholdLine.worldUnits = val; matThresholdLine.needsUpdate = true; } ); - 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 657529f6be56e8..c2334a510fd359 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 'bmap-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 da2e21e944c585..5c8db3c1b9e274 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 e62d59d528b067..cb29ca9b88fb57 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 'bmap-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; @@ -61,7 +62,7 @@ function init() { - THREE.Object3D.DefaultUp = new THREE.Vector3( 0, 0, 1 ); + THREE.Object3D.DEFAULT_UP.set( 0, 0, 1 ); renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); diff --git a/examples/webgl_loader_3ds.html b/examples/webgl_loader_3ds.html index aeeac44dd684cd..057880bf525b29 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 'bmap-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 091a874aade5a1..23354779e93a7f 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 'bmap-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 fd5e4c4af12736..2c7e7911bf7036 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 'bmap-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; @@ -77,7 +78,7 @@ const loader = new ThreeMFLoader( manager ); loader.load( './models/3mf/truck.3mf', function ( object ) { - object.quaternion.setFromEuler( new THREE.Euler( - Math.PI / 2, 0, 0 ) ); // z-up conversion + object.rotation.set( - Math.PI / 2, 0, 0 ); // z-up conversion object.traverse( function ( child ) { diff --git a/examples/webgl_loader_amf.html b/examples/webgl_loader_amf.html index 6572bfe71c389a..f9ca4446e01c2a 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 'bmap-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 3e6266bde6cf40..5f63577e73b7b8 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 'bmap-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 03d00f0c080117..52f6c7a5e70e56 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 'bmap-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 c9ad36f482a0ce..ee67a308a345e5 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 'bmap-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 0d90f4d971e214..3cccd344145955 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 'bmap-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 2264029402e2c9..00e525859eb073 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 'bmap-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 29be384e317e8d..699dba85ad8a4d 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 'bmap-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 31faed2cb95e81..82a823f3630256 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 'bmap-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 44547f110192db..7802b00c8909e1 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 'bmap-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_avif.html b/examples/webgl_loader_gltf_avif.html new file mode 100644 index 00000000000000..0f4e5e32de2f8c --- /dev/null +++ b/examples/webgl_loader_gltf_avif.html @@ -0,0 +1,131 @@ + + + + three.js webgl - GLTFloader + EXT_texture_avif + + + + + + +
          + three.js + - GLTFLoader + + EXT_texture_avif
          +
          + + + + + + + + + + diff --git a/examples/webgl_loader_gltf_compressed.html b/examples/webgl_loader_gltf_compressed.html index bf416916719685..f385277becb093 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 'bmap-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; @@ -72,7 +74,7 @@ scene.add( grid ); const ktx2Loader = new KTX2Loader() - .setTranscoderPath( 'js/libs/basis/' ) + .setTranscoderPath( 'jsm/libs/basis/' ) .detectSupport( renderer ); const loader = new GLTFLoader().setPath( 'models/gltf/' ); 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 new file mode 100644 index 00000000000000..090b724d2f8630 --- /dev/null +++ b/examples/webgl_loader_gltf_iridescence.html @@ -0,0 +1,113 @@ + + + + three.js webgl - GLTFloader + Iridescence + + + + + + +
          + three.js - GLTFLoader + KHR_materials_iridescence
          + Iridescence Lamp from glTF-Sample-Models
          + Venice Sunset by HDRI Haven +
          + + + + + + + + + + + diff --git a/examples/webgl_loader_gltf_sheen.html b/examples/webgl_loader_gltf_sheen.html index 49bbe59b74b8a5..309f800959b08f 100644 --- a/examples/webgl_loader_gltf_sheen.html +++ b/examples/webgl_loader_gltf_sheen.html @@ -1,7 +1,7 @@ - three.js webgl - GLTFloader + sheen + three.js webgl - GLTFloader + Sheen @@ -25,7 +25,8 @@ @@ -34,11 +35,11 @@ import * as THREE from 'bmap-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 81233d2fa821b1..6dc211ad14a1b1 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 'bmap-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; @@ -66,7 +67,7 @@ new GLTFLoader() .setPath( 'models/gltf/' ) - .setDRACOLoader( new DRACOLoader().setDecoderPath( 'js/libs/draco/gltf/' ) ) + .setDRACOLoader( new DRACOLoader().setDecoderPath( 'jsm/libs/draco/gltf/' ) ) .load( 'IridescentDishWithOlives.glb', function ( gltf ) { mixer = new THREE.AnimationMixer( gltf.scene ); diff --git a/examples/webgl_loader_gltf_variants.html b/examples/webgl_loader_gltf_variants.html index e89ff3fd87f5d7..0be8e01f5ef082 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 'bmap-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 0c7d91268b6416..023bb01fa28e44 100644 --- a/examples/webgl_loader_ifc.html +++ b/examples/webgl_loader_ifc.html @@ -24,17 +24,23 @@ @@ -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 96659d1390ac0e..3f3a957c9b4490 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 'bmap-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 a207366d9ee8b4..c41561433aedad 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 'bmap-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 e57212016f05ad..f8ceef65e2cafe 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 'bmap-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 a441bc88bec68e..a7b0704106c329 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 'bmap-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 421a1b113a45f5..420b1980460c79 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 'bmap-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 17fb7f73df07f3..32a2fd6fb70bcb 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 'bmap-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 ce0d20a09231dd..b800fa0fcbccaf 100644 --- a/examples/webgl_loader_mmd.html +++ b/examples/webgl_loader_mmd.html @@ -25,7 +25,7 @@ Dance Data - + @@ -34,7 +34,8 @@ @@ -43,13 +44,13 @@ import * as THREE from 'bmap-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 c5de94fbcee21a..4ff10772263107 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 df8a54b00af2a2..bb3ba852f0eaa2 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 'bmap-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 8ca04e0f2641c2..f04a7213f00b5b 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 'bmap-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 38e8f84c1ab486..a258bf1a2ff60a 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 'bmap-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 fc1c93ecbf5f46..35837de85e2ab4 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 'bmap-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 52ca944e7bc3d3..74e29083b929f6 100644 --- a/examples/webgl_lod.html +++ b/examples/webgl_lod.html @@ -19,7 +19,8 @@ @@ -28,7 +29,7 @@ import * as THREE from 'bmap-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 ae726f00c90442..965bcc550bb845 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 'bmap-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 8ec07c514f5a0b..22a10e6f28b065 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 fd21a792bdd690..4945b5fdaeee82 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 'bmap-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 a580138c2a5be9..1a3476258fb32d 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 'bmap-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 6f1cc64fa4ce9c..5d4fade0bd3c71 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 'bmap-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; @@ -145,7 +146,7 @@ const shadow = new THREE.TextureLoader().load( 'models/gltf/ferrari_ao.png' ); const dracoLoader = new DRACOLoader(); - dracoLoader.setDecoderPath( 'js/libs/draco/gltf/' ); + dracoLoader.setDecoderPath( 'jsm/libs/draco/gltf/' ); const loader = new GLTFLoader(); loader.setDRACOLoader( dracoLoader ); diff --git a/examples/webgl_materials_channels.html b/examples/webgl_materials_channels.html index 679466b957bf8e..77990e545e0097 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 'bmap-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 e5932181291817..f7c26cd20e4d16 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 'bmap-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 b60f3f83e25467..57e23ccef081bc 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 'bmap-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 308caa377083ff..a3a4dfafe1c2c9 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 'bmap-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 e4f8a8cd8290b0..87afec5015126d 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 'bmap-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 c2765b53c8a0c1..6567d5d96d2c70 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 'bmap-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 b7c9f784efbc7c..7f424e5c9b1a86 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 'bmap-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 e8e40d410e6a9b..1f3667b25a0a76 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 'bmap-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 cd92c9b9b29fa0..d2d0328e77e9da 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 'bmap-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,13 +62,20 @@ 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; // let geometry = new THREE.TorusKnotGeometry( 18, 8, 150, 20 ); let material = new THREE.MeshStandardMaterial( { - metalness: params.roughness, - roughness: params.metalness, + metalness: params.metalness, + roughness: params.roughness, envMapIntensity: 1.0 } ); @@ -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 new file mode 100644 index 00000000000000..5a2bc08acbabed --- /dev/null +++ b/examples/webgl_materials_envmaps_groundprojected.html @@ -0,0 +1,183 @@ + + + + + threejs webgl - materials - ground projected environment mapping + + + + + + +
          +
          + threejs - Ground projected environment mapping. By Faraz Shaikh.
          + Ferrari 458 Italia model by vicent091036
          + Blouberg Sunrise 2 by Greg Zaal +
          + + + + + + + + + + diff --git a/examples/webgl_materials_envmaps_hdr.html b/examples/webgl_materials_envmaps_hdr.html index 55ee44a09a7276..ac125b71d48dff 100644 --- a/examples/webgl_materials_envmaps_hdr.html +++ b/examples/webgl_materials_envmaps_hdr.html @@ -21,7 +21,8 @@ @@ -30,13 +31,13 @@ import * as THREE from 'bmap-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_instance_uniform_nodes.html b/examples/webgl_materials_instance_uniform_nodes.html deleted file mode 100644 index b1139857154c6f..00000000000000 --- a/examples/webgl_materials_instance_uniform_nodes.html +++ /dev/null @@ -1,230 +0,0 @@ - - - - three.js webgl - material instance uniform - - - - - -
          - three.js - webgl material instance uniform -
          - - - - - - - - - - - diff --git a/examples/webgl_materials_lightmap.html b/examples/webgl_materials_lightmap.html index ee9e23417c6558..ed48872be7345f 100644 --- a/examples/webgl_materials_lightmap.html +++ b/examples/webgl_materials_lightmap.html @@ -9,39 +9,6 @@ - - - - @@ -49,7 +16,9 @@ @@ -58,27 +27,28 @@ import * as THREE from 'bmap-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; + import { MeshBasicNodeMaterial, vec4, color, positionLocal, mix } from 'three/nodes'; + import { nodeFrame } from 'three/addons/renderers/webgl/nodes/WebGLNodes.js'; let container, stats; let camera, scene, renderer; - await init(); - animate(); + init().then( animate ); async function init() { + const { innerWidth, innerHeight } = window; + container = document.createElement( 'div' ); document.body.appendChild( container ); // CAMERA - camera = new THREE.PerspectiveCamera( 40, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 ); + camera = new THREE.PerspectiveCamera( 40, innerWidth / innerHeight, 1, 10000 ); camera.position.set( 700, 200, - 500 ); // SCENE @@ -95,32 +65,25 @@ // SKYDOME - const vertexShader = document.getElementById( 'vertexShader' ).textContent; - const fragmentShader = document.getElementById( 'fragmentShader' ).textContent; - const uniforms = { - topColor: { value: new THREE.Color( 0x0077ff ) }, - bottomColor: { value: new THREE.Color( 0xffffff ) }, - offset: { value: 400 }, - exponent: { value: 0.6 } - }; - uniforms.topColor.value.copy( light.color ); - - const skyGeo = new THREE.SphereGeometry( 4000, 32, 15 ); - const skyMat = new THREE.ShaderMaterial( { - uniforms: uniforms, - vertexShader: vertexShader, - fragmentShader: fragmentShader, - side: THREE.BackSide - } ); - - const sky = new THREE.Mesh( skyGeo, skyMat ); + const topColor = new THREE.Color().copy( light.color ).convertSRGBToLinear(); + const bottomColor = new THREE.Color( 0xffffff ).convertSRGBToLinear(); + const offset = 400; + const exponent = 0.6; + + const h = positionLocal.add( offset ).normalize().y; + + const skyMat = new MeshBasicNodeMaterial(); + skyMat.colorNode = vec4( mix( color( bottomColor ), color( topColor ), h.max( 0.0 ).pow( exponent ) ), 1.0 ); + skyMat.side = THREE.BackSide; + + const sky = new THREE.Mesh( new THREE.SphereGeometry( 4000, 32, 15 ), skyMat ); scene.add( sky ); // RENDERER renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); - renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT ); + renderer.setSize( innerWidth, innerHeight ); container.appendChild( renderer.domElement ); renderer.outputEncoding = THREE.sRGBEncoding; @@ -162,6 +125,8 @@ requestAnimationFrame( animate ); + nodeFrame.update(); + renderer.render( scene, camera ); stats.update(); diff --git a/examples/webgl_materials_matcap.html b/examples/webgl_materials_matcap.html index 7bca170dfbf3be..72b89006122755 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, AVIF, or EXR MatCap image files
          @@ -20,7 +20,8 @@ @@ -29,10 +30,10 @@ import * as THREE from 'bmap-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, AVIF, too function imgCallback( event ) { diff --git a/examples/webgl_materials_modified.html b/examples/webgl_materials_modified.html index c84a431d0fe209..f3502fa8e853df 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 'bmap-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 d0032ad61d6941..7d06cfb373ab1b 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 'bmap-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 6e71df92cf258a..eb7c77ba3e63c5 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 'bmap-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 c0d01da7ccbc53..683ceb7550d1e5 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 'bmap-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 0500a7b53c03ab..63197254437690 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 'bmap-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 126e8be67586bb..b0271b68410490 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 'bmap-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 968d45e431ad91..4cca914c314fb4 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 'bmap-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_standard_nodes.html b/examples/webgl_materials_standard_nodes.html deleted file mode 100644 index b4f253a1b256dd..00000000000000 --- a/examples/webgl_materials_standard_nodes.html +++ /dev/null @@ -1,237 +0,0 @@ - - - - three.js webgl - materials - standard (nodes) - - - - - - -
          - three.js - webgl physically based material
          - Cerberus(FFVII Gun) model by Andrew Maximov. -
          - - - - - - - - - - - diff --git a/examples/webgl_materials_subsurface_scattering.html b/examples/webgl_materials_subsurface_scattering.html index 33fff4e3625856..67ac3b7a746eaa 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 'bmap-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 edf1f737ff63e6..0318bf3e05a036 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 f25061f80f5751..49fbdde20db7ad 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 c9e841deb1ca67..a20e2967b4bb83 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 e0916780023968..1e3625fbc54e4c 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 a839544aaa93b5..e96efdc5cec5c8 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 'bmap-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 dc1b4a6bc764de..7fd487729ca9c9 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 'bmap-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 79e5c5a24425f1..b5029458c8507f 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 'bmap-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 a5b31072f3f09e..32de1cb23c9f74 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 'bmap-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 f8a1cc5d44149f..7af9591d542808 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 'bmap-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 0347cce73eed41..1f7700bd2c65d5 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 'bmap-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 40d6fe830828bf..193140011c6cdc 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 'bmap-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 85a5454dce5f47..8a572084c262f6 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 'bmap-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 167db7a52f7512..4a027b975d882f 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 'bmap-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 86c9a629c4e013..5ec51cc8fc6d9a 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 'bmap-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 959945b9a7891d..f64bed2375499c 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 'bmap-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 55f4e5de5339de..8a2a5f3dfa687b 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 f1ca5f194dcb11..c15ebdab9a93d4 100644 --- a/examples/webgl_mirror.html +++ b/examples/webgl_mirror.html @@ -27,7 +27,8 @@ @@ -36,8 +37,8 @@ import * as THREE from 'bmap-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 9dc96f5630b07b..b86ee8d612bda8 100644 --- a/examples/webgl_modifier_curve.html +++ b/examples/webgl_modifier_curve.html @@ -21,18 +21,28 @@ @@ -24,12 +25,12 @@ import * as THREE from 'bmap-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 193b6aece2daf6..c87c17aa0df5f2 100644 --- a/examples/webgl_modifier_simplifier.html +++ b/examples/webgl_modifier_simplifier.html @@ -1,7 +1,7 @@ - three.js webgl - modifier - Subdivisions using Loop Subdivision Scheme + three.js webgl - modifier - simplify modifier @@ -15,7 +15,8 @@ @@ -24,9 +25,9 @@ import * as THREE from 'bmap-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 2d4409dd397e5f..6ce5acc6122515 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 'bmap-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 a3c8af204f04d0..a9e254d26f39f2 100644 --- a/examples/webgl_morphtargets.html +++ b/examples/webgl_morphtargets.html @@ -21,7 +21,8 @@ @@ -30,8 +31,8 @@ import * as THREE from 'bmap-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 250e317f20f428..fc7d132fa71d99 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 'bmap-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(); @@ -72,7 +73,7 @@ container.appendChild( renderer.domElement ); const ktx2Loader = new KTX2Loader() - .setTranscoderPath( 'js/libs/basis/' ) + .setTranscoderPath( 'jsm/libs/basis/' ) .detectSupport( renderer ); new GLTFLoader() diff --git a/examples/webgl_morphtargets_horse.html b/examples/webgl_morphtargets_horse.html index 93479a3fab5183..39929551728524 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 'bmap-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 14546b1fa70061..c7b62883b9f444 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 'bmap-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 7e0d7287137d1e..d3cc6e01f61483 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 06b4c20f99050a..65858247743011 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 e4cd89025a652c..87cf05536bd7d4 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 77ccb61b9c7081..a7d208f14dfcf4 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 'bmap-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 ba32b56382645e..bd25d3ca7c84cd 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 'bmap-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 776ee820ebc37c..269f4f858c9d23 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 12667e228d47a9..eeaa048ea92a65 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 'bmap-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 4d204a28ae88f0..8c759dff2eccc3 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 'bmap-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 new file mode 100644 index 00000000000000..f420d9aa02b880 --- /dev/null +++ b/examples/webgl_nodes_loader_gltf_sheen.html @@ -0,0 +1,141 @@ + + + + three.js webgl - GLTFloader + Sheen + Nodes + + + + + + + +
          + three.js - GLTFLoader + KHR_materials_sheen + Nodes
          + Sheen Chair from glTF-Sample-Models +
          + + + + + + + + + + + diff --git a/examples/webgl_nodes_loader_gltf_transmission.html b/examples/webgl_nodes_loader_gltf_transmission.html new file mode 100644 index 00000000000000..ba90c974ecc1f7 --- /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..08fe99a8ad821b --- /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 new file mode 100644 index 00000000000000..15fdf267da38ac --- /dev/null +++ b/examples/webgl_nodes_materials_instance_uniform.html @@ -0,0 +1,236 @@ + + + + three.js webgl - material instance uniform + + + + + +
          + three.js - webgl material instance uniform +
          + + + + + + + + + + + diff --git a/examples/webgl_nodes_materials_physical_clearcoat.html b/examples/webgl_nodes_materials_physical_clearcoat.html new file mode 100644 index 00000000000000..0bd5b9646aac98 --- /dev/null +++ b/examples/webgl_nodes_materials_physical_clearcoat.html @@ -0,0 +1,257 @@ + + + + three.js webgl - materials - clearcoat nodes + + + + + +
          + three.js webgl - materials - clearcoat nodes +
          + + + + + + + + + + diff --git a/examples/webgl_nodes_materials_standard.html b/examples/webgl_nodes_materials_standard.html new file mode 100644 index 00000000000000..b663fd88ab5f0b --- /dev/null +++ b/examples/webgl_nodes_materials_standard.html @@ -0,0 +1,275 @@ + + + + three.js webgl - materials - standard (nodes) + + + + + + +
          + three.js - webgl physically based material
          + Cerberus(FFVII Gun) model by Andrew Maximov. +
          + + + + + + + + + + + diff --git a/examples/webgl_nodes_materialx_noise.html b/examples/webgl_nodes_materialx_noise.html new file mode 100644 index 00000000000000..b8032688aa94b6 --- /dev/null +++ b/examples/webgl_nodes_materialx_noise.html @@ -0,0 +1,208 @@ + + + + three.js webgl - materials - materialx nodes + + + + + +
          + three.js webgl - MaterialX - Noise +
          + + + + + + + + + + diff --git a/examples/webgl_nodes_playground.html b/examples/webgl_nodes_playground.html index bfe8c316bf72d6..c5079af4a3efdc 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,207 @@ 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 new file mode 100644 index 00000000000000..5aceb1666ee9f9 --- /dev/null +++ b/examples/webgl_nodes_points.html @@ -0,0 +1,215 @@ + + + + three.js webgl - node particles + + + + + + +
          + three.js - webgl node particles example +
          + + + + + + + + + + diff --git a/examples/webgl_panorama_cube.html b/examples/webgl_panorama_cube.html index 6e9a79194876cf..b0e5d1d8e8010f 100644 --- a/examples/webgl_panorama_cube.html +++ b/examples/webgl_panorama_cube.html @@ -19,7 +19,8 @@ @@ -28,7 +29,7 @@ import * as THREE from 'bmap-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 2a6c30bdf28442..d5fe749fe0c811 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 85037710e617a7..3ed26818b6d1cf 100644 --- a/examples/webgl_performance.html +++ b/examples/webgl_performance.html @@ -20,7 +20,8 @@ @@ -29,7 +30,7 @@ import * as THREE from 'bmap-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 810031acb1e83f..2bb806d3ff538c 100644 --- a/examples/webgl_performance_shader.html +++ b/examples/webgl_performance_shader.html @@ -81,15 +81,21 @@ @@ -29,7 +30,7 @@ import * as THREE from 'bmap-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 6bc90957e3b6f1..5126768014ab3f 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 'bmap-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 901ca1e73430d7..09731843634371 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 'bmap-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 c42037999f5d74..f11e095c45208a 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 'bmap-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_nodes.html b/examples/webgl_points_nodes.html deleted file mode 100644 index e4d742fd8d6cf0..00000000000000 --- a/examples/webgl_points_nodes.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - three.js webgl - node particles - - - - - - -
          - three.js - webgl node particles example -
          - - - - - - - - - - diff --git a/examples/webgl_points_sprites.html b/examples/webgl_points_sprites.html index 3973279d962095..1b83ce0ebe211c 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 'bmap-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 10be7c4d0f3bdd..1df6ac4bcbc075 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 'bmap-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 b7e4e571089c1f..671c0264e3852b 100644 --- a/examples/webgl_portal.html +++ b/examples/webgl_portal.html @@ -27,7 +27,8 @@ @@ -36,8 +37,8 @@ import * as THREE from 'bmap-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 9b745c41084794..30d92a9419cadb 100644 --- a/examples/webgl_postprocessing.html +++ b/examples/webgl_postprocessing.html @@ -15,7 +15,8 @@ @@ -24,12 +25,12 @@ import * as THREE from 'bmap-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 6c1e1d65c5e686..a4322da4d532cc 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 'bmap-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 d00969a7091e37..b533de12433f20 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 'bmap-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 22174969c2f184..26536b98baaff1 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 'bmap-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 b6005514f7859b..ddaf930866bd56 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 'bmap-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 787c2591ff3531..dad09118a080a9 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 'bmap-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 fb2c2cc41cba3b..5fff1e822b7da9 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 'bmap-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; @@ -108,7 +109,8 @@ shininess: 0.5, specular: 0xffffff, envMap: textureCube, - side: THREE.DoubleSide + side: THREE.DoubleSide, + forceSinglePass: true } ); const rand = Math.random; diff --git a/examples/webgl_postprocessing_fxaa.html b/examples/webgl_postprocessing_fxaa.html index 46f238a9855a9f..32f085b93dc8a4 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 'bmap-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 0003549eb17162..72bcfb2ab7afc4 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 'bmap-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 bee50848063ffa..08ae277f3c2e80 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 'bmap-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 831308bfb1f9d4..a81b9bfd13cf3a 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 'bmap-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 d042834630d52c..468e30fbe8c1bb 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 'bmap-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 a959e689049862..a856a41e0ffe8e 100644 --- a/examples/webgl_postprocessing_pixel.html +++ b/examples/webgl_postprocessing_pixel.html @@ -1,5 +1,6 @@ +<<<<<<< HEAD three.js webgl - postprocessing - pixel shader @@ -31,149 +32,281 @@ import * as THREE from 'bmap-three'; import { GUI } from './jsm/libs/lil-gui.module.min.js'; +======= +>>>>>>> mrdoob-dev + + + three.js webgl - post processing - pixelation + + + + + + +
          + three.js - Pixelation pass with optional single pixel outlines by + Kody King

          +
          + +
          + + + + + + - import { TrackballControls } from './jsm/controls/TrackballControls.js'; - import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; - import { RenderPass } from './jsm/postprocessing/RenderPass.js'; - import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; - import { PixelShader } from './jsm/shaders/PixelShader.js'; - - let camera, scene, renderer, gui, composer, controls; - let pixelPass, params; + + - - diff --git a/examples/webgl_postprocessing_procedural.html b/examples/webgl_postprocessing_procedural.html index e90afc141db57f..cabd25bec74cb2 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 'bmap-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 56b6eb973ad203..fd5829b32320d4 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 'bmap-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 5fed2630806c53..dcfb02bf417835 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 'bmap-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 eaf12cc39c1857..f5401ddf213e75 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 'bmap-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 c19872362ad5c3..dc4305cfced312 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 'bmap-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 4e39a42ba8a379..aead8e18df3484 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 'bmap-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 727b6885f12b2b..b789b803e1974f 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 'bmap-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 d37e0ecab4cbeb..11e679b40e3fc6 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 'bmap-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 a195e62d36f0de..24eeec42cacac4 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 'bmap-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 15b336f281a60b..87921adfff67b4 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 'bmap-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_raycast_sprite.html b/examples/webgl_raycast_sprite.html deleted file mode 100644 index 860813aba55e2b..00000000000000 --- a/examples/webgl_raycast_sprite.html +++ /dev/null @@ -1,157 +0,0 @@ - - - - - three.js webgl - raycast - sprite - - - - - - -
          three.js - webgl raycast sprite
          - - - - - - - - - - diff --git a/examples/webgl_raycast_texture.html b/examples/webgl_raycast_texture.html deleted file mode 100644 index ad7f042463e064..00000000000000 --- a/examples/webgl_raycast_texture.html +++ /dev/null @@ -1,400 +0,0 @@ - - - - three.js raycast - texture - - - - - - -
          -
          - three.js - raycast texture
          Left to right: buffer geometry - geometry - indexed buffer geometry -
          - Circle -
          - WrapS : -
          -
          - WrapT : -
          -
          - Offset : X - Y
          -
          -
          - Repeat : X - Y -
          -
          - Rotation : -
          -
          -
          - - - - - - - - - - diff --git a/examples/webgl_raycaster_bvh.html b/examples/webgl_raycaster_bvh.html new file mode 100644 index 00000000000000..0a6624e211ea92 --- /dev/null +++ b/examples/webgl_raycaster_bvh.html @@ -0,0 +1,304 @@ + + + + three.js raycaster - bvh + + + + + + + +
          + three.js raycaster - three-mesh-bvh
          + See main project repository for more information and examples on high performance spatial queries. +
          + + + + + + + + + + + diff --git a/examples/webgl_raycaster_sprite.html b/examples/webgl_raycaster_sprite.html new file mode 100644 index 00000000000000..5cb180a5c07e41 --- /dev/null +++ b/examples/webgl_raycaster_sprite.html @@ -0,0 +1,159 @@ + + + + three.js raycaster - sprite + + + + + + +
          three.js raycaster - sprite
          + + + + + + + + + + diff --git a/examples/webgl_raycaster_texture.html b/examples/webgl_raycaster_texture.html new file mode 100644 index 00000000000000..0917ac9df192bd --- /dev/null +++ b/examples/webgl_raycaster_texture.html @@ -0,0 +1,368 @@ + + + + three.js raycaster - texture + + + + + + +
          +
          + three.js raycaster - texture +
          + + + + + + + + + + diff --git a/examples/webgl_raymarching_reflect.html b/examples/webgl_raymarching_reflect.html index 3ca1877b267230..5dbc8c0e251e69 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 'bmap-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 567d77e4291bdb..d09311294647e2 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 'bmap-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 fc1aa928924f42..2d3e1d4fb3f150 100644 --- a/examples/webgl_refraction.html +++ b/examples/webgl_refraction.html @@ -28,7 +28,8 @@ @@ -37,9 +38,9 @@ import * as THREE from 'bmap-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..8991c5f7a3445b --- /dev/null +++ b/examples/webgl_renderer_pathtracer.html @@ -0,0 +1,494 @@ + + + + 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 a4ec9feb3301be..bc2a25d580cd9e 100644 --- a/examples/webgl_rtt.html +++ b/examples/webgl_rtt.html @@ -62,7 +62,8 @@ @@ -71,7 +72,7 @@ import * as THREE from 'bmap-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 22b4e69d2424c8..7e9875ab7e37e9 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 62b8b84f3ff6f2..9b2442a07e6890 100644 --- a/examples/webgl_shader2.html +++ b/examples/webgl_shader2.html @@ -138,7 +138,8 @@ @@ -147,7 +148,7 @@ import * as THREE from 'bmap-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 0e03f54bcf4d84..32c4e31a5c3887 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 'bmap-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 c471d408e3fca5..f7ea789ed10ad6 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 'bmap-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; @@ -111,6 +112,7 @@ }; const pmremGenerator = new THREE.PMREMGenerator( renderer ); + let renderTarget; function updateSun() { @@ -122,7 +124,11 @@ sky.material.uniforms[ 'sunPosition' ].value.copy( sun ); water.material.uniforms[ 'sunDirection' ].value.copy( sun ).normalize(); - scene.environment = pmremGenerator.fromScene( sky ).texture; + if ( renderTarget !== undefined ) renderTarget.dispose(); + + renderTarget = pmremGenerator.fromScene( sky ); + + scene.environment = renderTarget.texture; } diff --git a/examples/webgl_shaders_sky.html b/examples/webgl_shaders_sky.html index 530c7e73bae899..6870a47823dfd1 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 'bmap-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 417d1040b069c4..60db6a8a4fbeb9 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 'bmap-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 4f4ec8a5bce81a..0d7b6375f63b0d 100644 --- a/examples/webgl_shadow_contact.html +++ b/examples/webgl_shadow_contact.html @@ -26,19 +26,29 @@ @@ -31,13 +32,13 @@ import * as THREE from 'bmap-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 c81885da684c3f..237bd822c07ea1 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 'bmap-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 8e4120e1be6235..ba985e6ea96fa8 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 'bmap-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 0b5cb781051100..43781b515e4796 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 'bmap-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 1d84f8d1c24854..f329ca393e807f 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 'bmap-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; @@ -79,13 +80,6 @@ sphere.receiveShadow = true; light.add( sphere ); - // custom distance material - const distanceMaterial = new THREE.MeshDistanceMaterial( { - alphaMap: material.alphaMap, - alphaTest: material.alphaTest - } ); - sphere.customDistanceMaterial = distanceMaterial; - return light; } diff --git a/examples/webgl_shadowmap_progressive.html b/examples/webgl_shadowmap_progressive.html index 6ed26d2b82b228..a691817a5cc5ca 100644 --- a/examples/webgl_shadowmap_progressive.html +++ b/examples/webgl_shadowmap_progressive.html @@ -20,18 +20,28 @@ @@ -27,10 +28,10 @@ import * as THREE from 'bmap-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 3077893991cdda..8e62e26c70dbdf 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 'bmap-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 72ad9d011730b3..792ce439db43a4 100644 --- a/examples/webgl_shadowmesh.html +++ b/examples/webgl_shadowmesh.html @@ -21,7 +21,8 @@ @@ -30,7 +31,7 @@ import * as THREE from 'bmap-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 708cc4e26a9eca..6610bd6355015d 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 'bmap-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 070a66074b18c2..2c0fe232ed4fa1 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 'bmap-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 8c568d74a62209..83131d5bad20a1 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 10f8323f99a3d3..907517f32b8c35 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 75c07323fb155d..6db8702618b2d2 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 cdb5de0386923f..49d094b0f071e9 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 'bmap-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 9cc147a1e8605e..07245a0bfe5e76 100644 --- a/examples/webgl_tonemapping.html +++ b/examples/webgl_tonemapping.html @@ -12,7 +12,7 @@ three.js - Tone Mapping
          Battle Damaged Sci-fi Helmet by theblueturtle_
          - Royal Esplanade by HDRI Haven + Venice Sunset by HDRI Haven @@ -22,7 +22,8 @@ @@ -31,17 +32,18 @@ import * as THREE from 'bmap-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 ); @@ -115,16 +118,8 @@ // model - gltf.scene.traverse( function ( child ) { - - if ( child.isMesh ) { - - mesh = child; - scene.add( mesh ); - - } - - } ); + mesh = gltf.scene.getObjectByName( 'node_damagedHelmet_-6514' ); + scene.add( mesh ); render(); @@ -143,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 c793adb3032f0b..2d376573765768 100644 --- a/examples/webgl_trails.html +++ b/examples/webgl_trails.html @@ -14,7 +14,8 @@ @@ -23,7 +24,7 @@ import * as THREE from 'bmap-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 a1cbf61f2739e6..b39885aab765d0 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 'bmap-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 24259ca08458ba..c3294e1c605092 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 9e06bd376d2192..3a532f59e1038c 100644 --- a/examples/webgl_water.html +++ b/examples/webgl_water.html @@ -20,7 +20,8 @@ @@ -29,9 +30,9 @@ import * as THREE from 'bmap-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 955113e4d9b541..6265c983e61fd5 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 'bmap-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 707210948b03a0..3e4c257c35148a 100644 --- a/examples/webgpu_compute.html +++ b/examples/webgpu_compute.html @@ -17,27 +17,32 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } diff --git a/examples/webgpu_cubemap_adjustments.html b/examples/webgpu_cubemap_adjustments.html new file mode 100644 index 00000000000000..4ce5b7878c2630 --- /dev/null +++ b/examples/webgpu_cubemap_adjustments.html @@ -0,0 +1,215 @@ + + + + three.js webgpu - cubemap adjustments + + + + + + +
          + three.js - Env. Adjustments
          + Battle Damaged Sci-fi Helmet by + theblueturtle_
          +
          + + + + + + + + + + + diff --git a/examples/webgpu_cubemap_mix.html b/examples/webgpu_cubemap_mix.html index cc3ed6008d8959..fe4e4228e8e421 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 70b2f0e8b29d1e..c356fa5dc25e04 100644 --- a/examples/webgpu_depth_texture.html +++ b/examples/webgpu_depth_texture.html @@ -17,23 +17,29 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } 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 0c84a4e42821e7..51eb350c8e9c30 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 'bmap-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 { normalWorld } 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 ) { @@ -61,7 +62,11 @@ scene = new THREE.Scene(); const material = new THREE.MeshBasicMaterial(); - material.colorNode = normalWorld; + + // random colors between instances from 0x000000 to 0xFFFFFF + const randomColors = range( new THREE.Color( 0x000000 ), new THREE.Color( 0xFFFFFF ) ); + + material.colorNode = mix( normalWorld, randomColors, oscSine( timerLocal( .1 ) ) ); const loader = new THREE.BufferGeometryLoader(); loader.load( 'models/json/suzanne_buffergeometry.json', function ( geometry ) { @@ -84,6 +89,7 @@ renderer = new WebGPURenderer(); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); + renderer.setAnimationLoop( animate ); document.body.appendChild( renderer.domElement ); // @@ -95,8 +101,6 @@ window.addEventListener( 'resize', onWindowResize ); - return renderer.init(); - } function onWindowResize() { @@ -112,15 +116,13 @@ function animate() { - requestAnimationFrame( animate ); - render(); stats.update(); } - function render() { + async function render() { if ( mesh ) { @@ -154,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 dc91b09fe75985..968715f0d849df 100644 --- a/examples/webgpu_instance_uniform.html +++ b/examples/webgpu_instance_uniform.html @@ -18,35 +18,41 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } diff --git a/examples/webgpu_lights_ies_spotlight.html b/examples/webgpu_lights_ies_spotlight.html new file mode 100644 index 00000000000000..69c5a0bcafca3d --- /dev/null +++ b/examples/webgpu_lights_ies_spotlight.html @@ -0,0 +1,178 @@ + + + + three.js WebGPU - lights - ies spotlight + + + + + + +
          + three.js WebGPU - ies spotlight
          +
          + + + + + + + + + + + + diff --git a/examples/webgpu_lights_phong.html b/examples/webgpu_lights_phong.html new file mode 100644 index 00000000000000..4aa5147a15c18c --- /dev/null +++ b/examples/webgpu_lights_phong.html @@ -0,0 +1,199 @@ + + + + three.js - WebGPU - Lights Phong + + + + + + +
          + three.js - WebGPU - Phong Model Lighting
          + Left: Red lights - Center: All lights - Right: blue light +
          + + + + + + + + diff --git a/examples/webgpu_lights_selective.html b/examples/webgpu_lights_selective.html index 4f13f109dd6451..8e52398a5ac92b 100644 --- a/examples/webgpu_lights_selective.html +++ b/examples/webgpu_lights_selective.html @@ -19,35 +19,41 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } @@ -31,21 +32,22 @@ diff --git a/examples/webgpu_materials.html b/examples/webgpu_materials.html index 06c746148f8e03..43666c6b1117ba 100644 --- a/examples/webgpu_materials.html +++ b/examples/webgpu_materials.html @@ -18,24 +18,30 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } + + + + + + diff --git a/examples/webgpu_rtt.html b/examples/webgpu_rtt.html index 7c43057210dfff..6848a876f3e384 100644 --- a/examples/webgpu_rtt.html +++ b/examples/webgpu_rtt.html @@ -17,19 +17,25 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } diff --git a/examples/webgpu_sandbox.html b/examples/webgpu_sandbox.html index 0ca05dee75d1d1..5b065c3a84d298 100644 --- a/examples/webgpu_sandbox.html +++ b/examples/webgpu_sandbox.html @@ -17,28 +17,34 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } diff --git a/examples/webgpu_skinning.html b/examples/webgpu_skinning.html index d4acfb84533ff8..2a7a24abba482b 100644 --- a/examples/webgpu_skinning.html +++ b/examples/webgpu_skinning.html @@ -18,28 +18,34 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } diff --git a/examples/webgpu_skinning_instancing.html b/examples/webgpu_skinning_instancing.html index 6efd7be81fc0a9..9c1fd25995d076 100644 --- a/examples/webgpu_skinning_instancing.html +++ b/examples/webgpu_skinning_instancing.html @@ -18,28 +18,36 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } diff --git a/examples/webgpu_skinning_points.html b/examples/webgpu_skinning_points.html index 290c2f868fa56f..e4ff97a62ce85d 100644 --- a/examples/webgpu_skinning_points.html +++ b/examples/webgpu_skinning_points.html @@ -18,28 +18,34 @@ { "imports": { "three": "../build/three.module.js", - "three-nodes/": "./jsm/nodes/" + "three/addons/": "./jsm/", + "three/nodes": "./jsm/nodes/Nodes.js" } } diff --git a/examples/webgpu_sprites.html b/examples/webgpu_sprites.html index 427c01442f9232..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 bacc851f7d41c8..3c6c37974ff7c3 100644 --- a/examples/webxr_ar_cones.html +++ b/examples/webxr_ar_cones.html @@ -19,15 +19,21 @@ + + + + + + diff --git a/examples/webxr_ar_hittest.html b/examples/webxr_ar_hittest.html index 22d01eb3968cb0..6455204131e961 100644 --- a/examples/webxr_ar_hittest.html +++ b/examples/webxr_ar_hittest.html @@ -19,15 +19,21 @@ + + + + + + diff --git a/examples/webxr_vr_ballshooter.html b/examples/webxr_vr_ballshooter.html index b1b4a49399788b..927a57a325ee52 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 'bmap-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 696e7063878e37..9a089918531085 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 'bmap-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 c278d1b03da177..cfabe50faa9887 100644 --- a/examples/webxr_vr_dragging.html +++ b/examples/webxr_vr_dragging.html @@ -19,17 +19,25 @@ @@ -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 d5f8e3563f21d2..2faf462941ec09 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 'bmap-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 09da85e222da1b..5b7a7d98e59ffb 100644 --- a/examples/webxr_vr_sculpt.html +++ b/examples/webxr_vr_sculpt.html @@ -19,17 +19,25 @@ @@ -28,9 +29,9 @@ import * as THREE from 'bmap-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; @@ -82,12 +83,11 @@ renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.outputEncoding = THREE.sRGBEncoding; - renderer.xr.addEventListener( 'sessionstart', () => baseReferenceSpace = renderer.xr.getReferenceSpace() ) - renderer.xr.enabled = true; - document.body.appendChild( renderer.domElement ); - // + renderer.xr.addEventListener( 'sessionstart', () => baseReferenceSpace = renderer.xr.getReferenceSpace() ); + renderer.xr.enabled = true; + document.body.appendChild( renderer.domElement ); document.body.appendChild( VRButton.createButton( renderer ) ); // controllers diff --git a/examples/webxr_vr_video.html b/examples/webxr_vr_video.html index 5b6a626ded3e1d..048015c23c4b17 100644 --- a/examples/webxr_vr_video.html +++ b/examples/webxr_vr_video.html @@ -26,15 +26,21 @@ @@ -56,8 +56,8 @@

          Aligning HTML Elements to 3D

          Let's start simple. We'll make a 3D scene with a few primitives and then add a label to each primitive. We'll start with an example from the article on responsive pages

          We'll add some OrbitControls like we did in the article on lighting.

          -
          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);
          @@ -659,9 +659,9 @@ 

          Aligning HTML Elements to 3D

          Finally, since I'm not sure what good values are for these settings lets add a GUI so we can play with them

          -
          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,
          @@ -721,8 +721,8 @@ 

          Aligning HTML Elements to 3D

          - - + + diff --git a/manual/en/backgrounds.html b/manual/en/backgrounds.html index fc027f8c05f997..d1982bc95b317b 100644 --- a/manual/en/backgrounds.html +++ b/manual/en/backgrounds.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -189,7 +189,7 @@

          Backgrounds and Skyboxes

          }

          Let's add some controls in so we can rotate the camera.

          -
          import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
          +
          import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
           
          const fov = 75;
           const aspect = 2;  // the canvas default
          @@ -258,8 +258,8 @@ 

          Backgrounds and Skyboxes

          - - + + diff --git a/manual/en/billboards.html b/manual/en/billboards.html index 28195dc1c739d7..0f0037bd985876 100644 --- a/manual/en/billboards.html +++ b/manual/en/billboards.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -316,8 +316,8 @@

          Billboards

          - - + + diff --git a/manual/en/cameras.html b/manual/en/cameras.html index b1bc9e32bcbcce..eeb2ed897d2985 100644 --- a/manual/en/cameras.html +++ b/manual/en/cameras.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -557,8 +557,8 @@

          Cameras

          - - + + diff --git a/manual/en/canvas-textures.html b/manual/en/canvas-textures.html index d4f136666c9941..bc5a2075e99a26 100644 --- a/manual/en/canvas-textures.html +++ b/manual/en/canvas-textures.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -260,8 +260,8 @@

          Canvas Textures

          What's left is to add some OrbitControls so we can move the camera.

          -
          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
          @@ -420,8 +420,8 @@ 

          Canvas Textures

          - - + + diff --git a/manual/en/cleanup.html b/manual/en/cleanup.html index b07f324aee0efc..a4ad06cb998933 100644 --- a/manual/en/cleanup.html +++ b/manual/en/cleanup.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -439,8 +439,8 @@

          Cleanup

          - - + + diff --git a/manual/en/custom-buffergeometry.html b/manual/en/custom-buffergeometry.html index d524578a1aa758..86100c8d3632ea 100644 --- a/manual/en/custom-buffergeometry.html +++ b/manual/en/custom-buffergeometry.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -446,8 +446,8 @@

          Custom BufferGeometry

          - - + + diff --git a/manual/en/custom-geometry.html b/manual/en/custom-geometry.html deleted file mode 100644 index aca1053b5f548a..00000000000000 --- a/manual/en/custom-geometry.html +++ /dev/null @@ -1,470 +0,0 @@ - - - Custom Geometry - - - - - - - - - - - - - - - - - -
          -
          -

          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/debugging-glsl.html b/manual/en/debugging-glsl.html index 8b09d645fa679a..2e81c0dd2dcfac 100644 --- a/manual/en/debugging-glsl.html +++ b/manual/en/debugging-glsl.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -115,8 +115,8 @@

          Debugging - GLSL

          - - + + diff --git a/manual/en/debugging-javascript.html b/manual/en/debugging-javascript.html index 0126a9ea8d574e..4a1301786b4007 100644 --- a/manual/en/debugging-javascript.html +++ b/manual/en/debugging-javascript.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -496,8 +496,8 @@

          Put something in front of the came - - + + diff --git a/manual/en/fog.html b/manual/en/fog.html index 1b96eb2d26ca46..c07fda78563194 100644 --- a/manual/en/fog.html +++ b/manual/en/fog.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -276,8 +276,8 @@

          Fog

          - - + + diff --git a/manual/en/fundamentals.html b/manual/en/fundamentals.html index 49b1b194564180..05b9bc565af3db 100644 --- a/manual/en/fundamentals.html +++ b/manual/en/fundamentals.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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>
             
            @@ -439,10 +455,10 @@

            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..a316136299f334 100644 --- a/manual/en/game.html +++ b/manual/en/game.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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);
            @@ -1927,8 +1927,8 @@ 

            Making a Game

            - - + + diff --git a/manual/en/indexed-textures.html b/manual/en/indexed-textures.html index 83d3533e6e1787..b6ac20e66ad1ef 100644 --- a/manual/en/indexed-textures.html +++ b/manual/en/indexed-textures.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -631,8 +631,8 @@

            Indexed Textures for Picking and Color

            - - + + diff --git a/manual/en/lights.html b/manual/en/lights.html index 393bd26003d0e0..8078ec4d35cae2 100644 --- a/manual/en/lights.html +++ b/manual/en/lights.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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() {
            @@ -517,8 +517,8 @@ 

            - - + + diff --git a/manual/en/load-gltf.html b/manual/en/load-gltf.html index 93601619fa371f..e55db00bd97973 100644 --- a/manual/en/load-gltf.html +++ b/manual/en/load-gltf.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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], }, + ]; @@ -701,10 +701,10 @@

            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..6dc923635dab14 100644 --- a/manual/en/load-obj.html +++ b/manual/en/load-obj.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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 @@ -619,8 +619,8 @@

            Loading a .OBJ File

            - - + + diff --git a/manual/en/material-table.html b/manual/en/material-table.html index 0427ecc71ecd35..fae94743dd1444 100644 --- a/manual/en/material-table.html +++ b/manual/en/material-table.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -43,8 +43,8 @@

            Material Feature Table

            - - + + diff --git a/manual/en/materials.html b/manual/en/materials.html index 5f41ac6d53c460..5f5dcfe2f9a7e2 100644 --- a/manual/en/materials.html +++ b/manual/en/materials.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -305,8 +305,8 @@

            material.needsUpdate

            - - + + diff --git a/manual/en/multiple-scenes.html b/manual/en/multiple-scenes.html index fa4ef72656d6d7..f41eb031176fdf 100644 --- a/manual/en/multiple-scenes.html +++ b/manual/en/multiple-scenes.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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() {
            @@ -633,8 +633,8 @@ 

            Adding Controls to each element

            - - + + diff --git a/manual/en/offscreencanvas.html b/manual/en/offscreencanvas.html index 4a64755e755862..9c8d686cd90f5b 100644 --- a/manual/en/offscreencanvas.html +++ b/manual/en/offscreencanvas.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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;
            @@ -1083,8 +1083,8 @@ 

            OffscreenCanvas

            - - + + diff --git a/manual/en/optimize-lots-of-objects-animated.html b/manual/en/optimize-lots-of-objects-animated.html index 1aeb39f6f32ac5..1b82d36cdc1fa6 100644 --- a/manual/en/optimize-lots-of-objects-animated.html +++ b/manual/en/optimize-lots-of-objects-animated.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -312,6 +312,12 @@

            Optimize Lots of Objects Animated

            + attribute.name = name; + return attribute; +}); ++baseGeometry.morphAttributes.color = geometries.map((geometry, ndx) => { ++ const attribute = geometry.getAttribute('color'); ++ const name = `target${ndx}`; ++ attribute.name = name; ++ return attribute; ++}); +const material = new THREE.MeshBasicMaterial({ + vertexColors: true, +}); @@ -348,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
            @@ -463,209 +469,7 @@ 

            Optimize Lots of Objects Animated

            -

            That seems to work but unfortunately we lost the colors.

            -

            Three.js does not support morphtarget colors and in fact this is an issue -with the original webgl globe. -Basically it just makes colors for the first data set. Any other datasets -use the same colors even if they are vastly different.

            -

            Let's see if we can add support for morphing the colors. This might -be brittle. The least brittle way would probably be to 100% write our own -shaders but I think it would be useful to see how to modify the built -in shaders.

            -

            The first thing we need to do is make the code extract color a BufferAttribute from -each data set's geometry.

            -
            // use the first geometry as the base
            -// and add all the geometries as morphtargets
            -const baseGeometry = geometries[0];
            -baseGeometry.morphAttributes.position = geometries.map((geometry, ndx) => {
            -  const attribute = geometry.getAttribute('position');
            -  const name = `target${ndx}`;
            -  attribute.name = name;
            -  return attribute;
            -});
            -+const colorAttributes = geometries.map((geometry, ndx) => {
            -+  const attribute = geometry.getAttribute('color');
            -+  const name = `morphColor${ndx}`;
            -+  attribute.name = `color${ndx}`;  // just for debugging
            -+  return {name, attribute};
            -+});
            -const material = new THREE.MeshBasicMaterial({
            -  vertexColors: true,
            -});
            -
            -

            We then need to modify the three.js shader. Three.js materials have an -Material.onBeforeCompile property we can assign a function. It gives us a -chance to modify the material's shader before it is passed to WebGL. In fact the -shader that is provided is actually a special three.js only syntax of shader -that lists a bunch of shader chunks that three.js will substitute with the -actual GLSL code for each chunk. Here is what the unmodified vertex shader code -looks like as passed to onBeforeCompile.

            -
            #include <common>
            -#include <uv_pars_vertex>
            -#include <uv2_pars_vertex>
            -#include <envmap_pars_vertex>
            -#include <color_pars_vertex>
            -#include <fog_pars_vertex>
            -#include <morphtarget_pars_vertex>
            -#include <skinning_pars_vertex>
            -#include <logdepthbuf_pars_vertex>
            -#include <clipping_planes_pars_vertex>
            -void main() {
            -    #include <uv_vertex>
            -    #include <uv2_vertex>
            -    #include <color_vertex>
            -    #include <skinbase_vertex>
            -    #ifdef USE_ENVMAP
            -    #include <beginnormal_vertex>
            -    #include <morphnormal_vertex>
            -    #include <skinnormal_vertex>
            -    #include <defaultnormal_vertex>
            -    #endif
            -    #include <begin_vertex>
            -    #include <morphtarget_vertex>
            -    #include <skinning_vertex>
            -    #include <project_vertex>
            -    #include <logdepthbuf_vertex>
            -    #include <worldpos_vertex>
            -    #include <clipping_planes_vertex>
            -    #include <envmap_vertex>
            -    #include <fog_vertex>
            -}
            -
            -

            Digging through the various chunks we want to replace -the morphtarget_pars_vertex chunk -the morphnormal_vertex chunk -the morphtarget_vertex chunk -the color_pars_vertex chunk -and the color_vertex chunk

            -

            To do that we'll make a simple array of replacements and apply them in Material.onBeforeCompile

            -
            const material = new THREE.MeshBasicMaterial({
            -  vertexColors: true,
            -});
            -+const vertexShaderReplacements = [
            -+  {
            -+    from: '#include <morphtarget_pars_vertex>',
            -+    to: `
            -+      uniform float morphTargetInfluences[8];
            -+    `,
            -+  },
            -+  {
            -+    from: '#include <morphnormal_vertex>',
            -+    to: `
            -+    `,
            -+  },
            -+  {
            -+    from: '#include <morphtarget_vertex>',
            -+    to: `
            -+      transformed += (morphTarget0 - position) * morphTargetInfluences[0];
            -+      transformed += (morphTarget1 - position) * morphTargetInfluences[1];
            -+      transformed += (morphTarget2 - position) * morphTargetInfluences[2];
            -+      transformed += (morphTarget3 - position) * morphTargetInfluences[3];
            -+    `,
            -+  },
            -+  {
            -+    from: '#include <color_pars_vertex>',
            -+    to: `
            -+      varying vec3 vColor;
            -+      attribute vec3 morphColor0;
            -+      attribute vec3 morphColor1;
            -+      attribute vec3 morphColor2;
            -+      attribute vec3 morphColor3;
            -+    `,
            -+  },
            -+  {
            -+    from: '#include <color_vertex>',
            -+    to: `
            -+      vColor.xyz = morphColor0 * morphTargetInfluences[0] +
            -+                   morphColor1 * morphTargetInfluences[1] +
            -+                   morphColor2 * morphTargetInfluences[2] +
            -+                   morphColor3 * morphTargetInfluences[3];
            -+    `,
            -+  },
            -+];
            -+material.onBeforeCompile = (shader) => {
            -+  vertexShaderReplacements.forEach((rep) => {
            -+    shader.vertexShader = shader.vertexShader.replace(rep.from, rep.to);
            -+  });
            -+};
            -
            -

            Three.js also sorts morphtargets and applies only the highest influences. This -lets it allow many more morphtargets as long as only a few are used at a time. -Unfortunately three.js does not provide any way to know how many morph targets -will be used nor which attributes the morph targets will be assigned to. So, -we'll have to look into the code and reproduce what it does here. If that -algorithm changes in three.js we'll need to refactor this code.

            -

            First we remove all the color attributes. It doesn't matter if we did not add -them before as it's safe to remove an attribute that was not previously added. -Then we'll compute which targets we think three.js will use and finally assign -those targets to the attributes we think three.js would assign them to.

            -
            const mesh = new THREE.Mesh(baseGeometry, material);
            -scene.add(mesh);
            -
            -+function updateMorphTargets() {
            -+  // remove all the color attributes
            -+  for (const {name} of colorAttributes) {
            -+    baseGeometry.deleteAttribute(name);
            -+  }
            -+
            -+  // three.js provides no way to query this so we have to guess and hope it doesn't change.
            -+  const maxInfluences = 8;
            -+
            -+  // three provides no way to query which morph targets it will use
            -+  // nor which attributes it will assign them to so we'll guess.
            -+  // If the algorithm in three.js changes we'll need to refactor this.
            -+  mesh.morphTargetInfluences
            -+    .map((influence, i) => [i, influence])            // map indices to influence
            -+    .sort((a, b) => Math.abs(b[1]) - Math.abs(a[1]))  // sort by highest influence first
            -+    .slice(0, maxInfluences)                          // keep only top influences
            -+    .sort((a, b) => a[0] - b[0])                      // sort by index
            -+    .filter(a => !!a[1])                              // remove no influence entries
            -+    .forEach(([ndx], i) => {                          // assign the attributes
            -+      const name = `morphColor${i}`;
            -+      baseGeometry.setAttribute(name, colorAttributes[ndx].attribute);
            -+    });
            -+}
            -
            -

            We'll return this function from our loadAll function. This way we don't -need to leak any variables.

            -
            async function loadAll() {
            -  ...
            -
            -+  return updateMorphTargets;
            -}
            -
            -+// use a no-op update function until the data is ready
            -+let updateMorphTargets = () => {};
            --loadAll();
            -+loadAll().then(fn => {
            -+  updateMorphTargets = fn;
            -+});
            -
            -

            And finally we need to call updateMorphTargets after we've let the values -be updated by the tween manager and before rendering.

            -
            function render() {
            -
            -  ...
            -
            -  if (tweenManager.update()) {
            -    requestRenderIfNotRequested();
            -  }
            -
            -+  updateMorphTargets();
            -
            -  controls.update();
            -  renderer.render(scene, camera);
            -}
            -
            -

            And with that we should have the colors animating as well as the boxes.

            -

            - -

            -

            I hope going through this was helpful. Using morphtargets either through the -services three.js provides or by writing custom shaders is a common technique to +

            I hope going through this was helpful. Using morphtargets is a common technique to move lots of objects. As an example we could give every cube a random place in another target and morph from that to their first positions on the globe. That might be a cool way to introduce the globe.

            @@ -683,8 +487,8 @@

            Optimize Lots of Objects Animated

            - - + + diff --git a/manual/en/optimize-lots-of-objects.html b/manual/en/optimize-lots-of-objects.html index 01efdd0324e521..bdf4db59053861 100644 --- a/manual/en/optimize-lots-of-objects.html +++ b/manual/en/optimize-lots-of-objects.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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

            @@ -507,8 +507,8 @@

            Optimize Lots of Objects

            - - + + diff --git a/manual/en/picking.html b/manual/en/picking.html index d348d9f3c9dd45..d70446f3d8ce8d 100644 --- a/manual/en/picking.html +++ b/manual/en/picking.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -402,8 +402,8 @@

            Picking

            - - + + diff --git a/manual/en/post-processing-3dlut.html b/manual/en/post-processing-3dlut.html index b09d2fae526ff3..15a8ad5ca4fc98 100644 --- a/manual/en/post-processing-3dlut.html +++ b/manual/en/post-processing-3dlut.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -440,8 +440,8 @@

            Post Processing 3DLUT

            - - + + diff --git a/manual/en/post-processing.html b/manual/en/post-processing.html index 6b60ba1168f13b..4e4a682c32d484 100644 --- a/manual/en/post-processing.html +++ b/manual/en/post-processing.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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.

            @@ -156,7 +156,7 @@

            renderToScree can easily adjust and how to adjust them requires digging through the code for that effect.

            Looking inside -BloomPass.js +BloomPass.js I found this line:

            this.copyUniforms[ "opacity" ].value = strength;
             
            @@ -164,7 +164,7 @@

            renderToScree
            bloomPass.copyUniforms.opacity.value = someValue;
             

            Similarly looking in -FilmPass.js +FilmPass.js I found these lines:

            if ( grayscale !== undefined )    this.uniforms.grayscale.value = grayscale;
             if ( noiseIntensity !== undefined ) this.uniforms.nIntensity.value = noiseIntensity;
            @@ -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();
            @@ -272,12 +272,12 @@ 

            renderToScree too much for these articles. If you really want to know how WebGL itself works then check out these articles. Another great resources is just to -read through the existing post processing shaders in the THREE.js repo. Some +read through the existing post processing shaders in the THREE.js repo. Some are more complicated than others but if you start with the smaller ones you can hopefully get an idea of how they work.

            Most of the post processing effects in the THREE.js repo are unfortunately undocumented so to use them you'll have to read through the examples or -the code for the effects themselves. +the code for the effects themselves. Hopefully these simple example and the article on render targets provide enough context to get started.

            @@ -285,8 +285,8 @@

            renderToScree - - + + diff --git a/manual/en/prerequisites.html b/manual/en/prerequisites.html index e5a88d96065c57..fdfec0bc841e46 100644 --- a/manual/en/prerequisites.html +++ b/manual/en/prerequisites.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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 @@ -322,8 +331,8 @@

            If you r - - + + diff --git a/manual/en/primitives.html b/manual/en/primitives.html index a84eab25c4880e..fbe2bdad078a7e 100644 --- a/manual/en/primitives.html +++ b/manual/en/primitives.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -355,8 +355,8 @@

            Primitives

            - - + + diff --git a/manual/en/rendering-on-demand.html b/manual/en/rendering-on-demand.html index 49e330df402dad..6e057c29daafe7 100644 --- a/manual/en/rendering-on-demand.html +++ b/manual/en/rendering-on-demand.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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 @@ -226,8 +226,8 @@

            Rendering on Demand

            - - + + diff --git a/manual/en/rendertargets.html b/manual/en/rendertargets.html index 469a1c61992528..d824d0f99dd2c6 100644 --- a/manual/en/rendertargets.html +++ b/manual/en/rendertargets.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -164,8 +164,8 @@

            Render Targets

            - - + + diff --git a/manual/en/responsive.html b/manual/en/responsive.html index 0212a5e73ac212..d227b1241a6c9d 100644 --- a/manual/en/responsive.html +++ b/manual/en/responsive.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -268,8 +268,8 @@

            Handling HD-DPI displays

            - - + + diff --git a/manual/en/scenegraph.html b/manual/en/scenegraph.html index cfc209baf17fc3..76100cfb9c2c38 100644 --- a/manual/en/scenegraph.html +++ b/manual/en/scenegraph.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -473,8 +473,8 @@

            Scene Graph

            - - + + diff --git a/manual/en/setup.html b/manual/en/setup.html index 58ff903435974a..446921b83c053d 100644 --- a/manual/en/setup.html +++ b/manual/en/setup.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -34,7 +34,7 @@

            Setup

            The first article was
            about three.js fundamentals. If you haven't read that yet you might want to start there.

            Before we go any further we need to talk about setting up your -computer to do development. In particular, for security reasons, +computer as a development environment. In particular, for security reasons, WebGL cannot use images from your hard drive directly. That means in order to do development you need to use a web server. Fortunately development web servers are super easy to setup and use.

            @@ -51,7 +51,7 @@

            Setup

            Just point it at the folder where you unzipped the files, click "Start", then go to in your browser http://localhost:8080/ or if you'd like to browse the samples go to http://localhost:8080/threejs.

            -

            To stop serving pick stop or quit Servez.

            +

            To stop serving click stop or quit Servez.

            If you prefer the command line (I do), another way is to use node.js. Download it, install it, then open a command prompt / console / terminal window. If you're on Windows the installer will add a special "Node Command Prompt" so use that.

            Then install the servez by typing

            @@ -79,10 +79,10 @@

            Setup

            - - + + - \ No newline at end of file + diff --git a/manual/en/shadertoy.html b/manual/en/shadertoy.html index cc4fe1ee48da0f..739ce46cd406d9 100644 --- a/manual/en/shadertoy.html +++ b/manual/en/shadertoy.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -407,8 +407,8 @@

            and Shadertoy

            - - + + diff --git a/manual/en/shadows.html b/manual/en/shadows.html index 66878e150eed52..1a11401a75295c 100644 --- a/manual/en/shadows.html +++ b/manual/en/shadows.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -463,8 +463,8 @@

            Shadows

            - - + + diff --git a/manual/en/textures.html b/manual/en/textures.html index edcf70b45d9512..65ec40d03168dc 100644 --- a/manual/en/textures.html +++ b/manual/en/textures.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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 @@ -560,8 +560,8 @@

            - + + diff --git a/manual/en/tips.html b/manual/en/tips.html index f968342f7ab402..7dd97dc1371449 100644 --- a/manual/en/tips.html +++ b/manual/en/tips.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -365,8 +365,8 @@

            Making your background a th - - + + diff --git a/manual/en/transparency.html b/manual/en/transparency.html index 6c02b4081bfa91..c4c4d14bcada7c 100644 --- a/manual/en/transparency.html +++ b/manual/en/transparency.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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

            @@ -397,8 +397,8 @@

            Transparency

            - - + + diff --git a/manual/en/voxel-geometry.html b/manual/en/voxel-geometry.html index 06387c9d88503e..ae5c94afbd0d53 100644 --- a/manual/en/voxel-geometry.html +++ b/manual/en/voxel-geometry.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -1127,8 +1127,8 @@

            Voxel(Minecraft Like) Geometry

            - - + + diff --git a/manual/en/webxr-basics.html b/manual/en/webxr-basics.html new file mode 100644 index 00000000000000..c5ea427c324050 --- /dev/null +++ b/manual/en/webxr-basics.html @@ -0,0 +1,383 @@ + + + VR + + + + + + + + + + + + + + + + + +
            +
            +

            VR

            +
            +
            +
            +

            Making a VR app in three.js is pretty simple. You basically just have to tell +three.js you want to use WebXR. If you think about it a few things about WebXR +should be clear. Which way the camera is pointing is supplied by the VR system +itself since the user turns their head to choose a direction to look. Similarly +the field of view and aspect will be supplied by the VR system since each system +has a different field of view and display aspect.

            +

            Let's take an example from the article on making a responsive webpage +and make it support VR.

            +

            Before we get started you're going to need a VR capable device like an Android +smartphone, Google Daydream, Oculus Go, Oculus Rift, Vive, Samsung Gear VR., an +iPhone with a WebXR browser.

            +

            Next, if you are running locally you need to run a simple web server like is +covered in the article on setting up.

            +

            If the device you are using to view VR is not the same computer you're running +on you need to serve your webpage via https or else the browser will not allow using +the WebXR API. The server mentioned in the article on setting up +called Servez has an option to use https. +Check it and start the server.

            +
            + +

            The note the URLs. You need the one that is your computer's local ipaddress. +It will usually start with 192, 172 or 10. Type that full address, including the https:// part +into your VR device's browser. Note: Your computer and your VR device need to be on the same local network +or WiFi and you probably need to be on a home network. note: Many cafes are setup to disallow this kind of +machine to machine connection.

            +

            You'll be greeted with an error something like the one below. Click "advanced" and then click +proceed.

            +
            + +

            Now you can run your examples.

            +

            If you're really going to do WebXR development another thing you should learn about is +remote debugging +so that you can see console warnings, errors, and of course actually +debug your code.

            +

            If you just want to see the code work below you can just run the code from +this site.

            +

            The first thing we need to do is include the VR support after +including three.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

            +
            function main() {
            +  const canvas = document.querySelector('#c');
            +  const renderer = new THREE.WebGLRenderer({canvas});
            ++  renderer.xr.enabled = true;
            ++  document.body.appendChild(VRButton.createButton(renderer));
            +
            +

            We need to let three.js run our render loop. Until now we have used a +requestAnimationFrame loop but to support VR we need to let three.js handle +our render loop for us. We can do that by calling +WebGLRenderer.setAnimationLoop and passing a function to call for the loop.

            +
            function render(time) {
            +  time *= 0.001;
            +
            +  if (resizeRendererToDisplaySize(renderer)) {
            +    const canvas = renderer.domElement;
            +    camera.aspect = canvas.clientWidth / canvas.clientHeight;
            +    camera.updateProjectionMatrix();
            +  }
            +
            +  cubes.forEach((cube, ndx) => {
            +    const speed = 1 + ndx * .1;
            +    const rot = time * speed;
            +    cube.rotation.x = rot;
            +    cube.rotation.y = rot;
            +  });
            +
            +  renderer.render(scene, camera);
            +
            +-  requestAnimationFrame(render);
            +}
            +
            +-requestAnimationFrame(render);
            ++renderer.setAnimationLoop(render);
            +
            +

            There is one more detail. We should probably set a camera height +that's kind of average for a standing user.

            +
            const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
            ++camera.position.set(0, 1.6, 0);
            +
            +

            and move the cubes up to be in front of the camera

            +
            const cube = new THREE.Mesh(geometry, material);
            +scene.add(cube);
            +
            +cube.position.x = x;
            ++cube.position.y = 1.6;
            ++cube.position.z = -2;
            +
            +

            We set them to z = -2 since the camera will now be at z = 0 and +camera defaults to looking down the -z axis.

            +

            This brings up an extremely important point. Units in VR are in meters. +In other words One Unit = One Meter. This means the camera is 1.6 meters above 0. +The cube's centers are 2 meters in front of the camera. Each cube +is 1x1x1 meter large. This is important because VR needs to adjust things to the +user in the real world. That means we need the units used in three.js to match +the user's own movements.

            +

            And with that we should get 3 spinning cubes in front +of the camera with a button to enter VR.

            +

            + +

            +

            I find that VR works better if we have something surrounding the camera like +room for reference so let's add a simple grid cubemap like we covered in +the article on backgrounds. We'll just use the same grid +texture for each side of the cube which will give as a grid room.

            +
            const scene = new THREE.Scene();
            ++{
            ++  const loader = new THREE.CubeTextureLoader();
            ++  const texture = loader.load([
            ++    'resources/images/grid-1024.png',
            ++    'resources/images/grid-1024.png',
            ++    'resources/images/grid-1024.png',
            ++    'resources/images/grid-1024.png',
            ++    'resources/images/grid-1024.png',
            ++    'resources/images/grid-1024.png',
            ++  ]);
            ++  scene.background = texture;
            ++}
            +
            +

            That's better.

            +

            + +

            +

            Note: To actually see VR you will need a WebXR compatible device. +I believe most Android Phones can support WebXR using Chrome or Firefox. +For iOS you might be able to use this WebXR App +though in general WebXR support on iOS is unsupported as of May 2019.

            +

            To use WebXR on Android or iPhone you'll need a VR Headset +for phones. You can get them for anywhere from $5 for one made of cardboard +to $100. Unfortunately I don't know which ones to recommend. I've purchased +6 of them over the years and they are all of varying quality. I've +never paid more than about $25.

            +

            Just to mention some of the issues

            +
              +
            1. Do they fit your phone

              +

              Phones come in a variety of sizes and so the VR headsets need to match. +Many headsets claim to match a large variety of sizes. My experience +is the more sizes they match the worse they actually are since instead +of being designed for a specific size they have to make compromises +to match more sizes. Unfortunately multi-size headsets are the most common type.

              +
            2. +
            3. Can they focus for your face

              +

              Some devices have more adjustments than others. Generally there +are at most 2 adjustments. How far the lenses are from your eyes +and how far apart the lenses are.

              +
            4. +
            5. Are they too reflective

              +

              Many headsets of a cone of plastic from your eye to the phone. +If that plastic is shinny or reflective then it will act like +a mirror reflecting the screen and be very distracting.

              +

              Few if any of the reviews seem to cover this issue.

              +
            6. +
            7. Are the comfortable on your face.

              +

              Most of the devices rest on your nose like a pair of glasses. +That can hurt after a few minutes. Some have straps that go around +your head. Others have a 3rd strap that goes over your head. These +may or may not help keep the device at the right place.

              +

              It turns out for most (all?) devices, you eyes need to be centered +with the lenses. If the lenses are slightly above or below your +eyes the image gets out of focus. This can be very frustrating +as things might start in focus but 45-60 seconds later the device +has shifted up or down 1 millimeter and you suddenly realize you've +been struggling to focus on a blurry image.

              +
            8. +
            9. Can they support your glasses.

              +

              If you wear eye glasses then you'll need to read the reviews to see +if a particular headset works well with eye glasses.

              +
            10. +
            +

            I really can't make any recommendations unfortunately. Google has some +cheap recommendations made from cardboard +some of them as low as $5 so maybe start there and if you enjoy it +then consider upgrading. $5 is like the price of 1 coffee so seriously, give it try!

            +

            There are also 3 basic types of devices.

            +
              +
            1. 3 degrees of freedom (3dof), no input device

              +

              This is generally the phone style although sometimes you can +buy a 3rd party input device. The 3 degrees of freedom +mean you can look up/down (1), left/right(2) and you can tilt +your head left and right (3).

              +
            2. +
            3. 3 degrees of freedom (3dof) with 1 input device (3dof)

              +

              This is basically Google Daydream and Oculus GO

              +

              These also allow 3 degrees of freedom and include a small +controller that acts like a laser pointer inside VR. +The laser pointer also only has 3 degrees of freedom. The +system can tell which way the input device is pointing but +it can not tell where the device is.

              +
            4. +
            5. 6 degrees of freedom (6dof) with input devices (6dof)

              +

              These are the real deal haha. 6 degrees of freedom +means not only do these device know which way you are looking +but they also know where your head actually is. That means +if you move from left to right or forward and back or stand up / sit down +the devices can register this and everything in VR moves accordingly. +It's spookily and amazingly real feeling. With a good demo +you'll be blown away or at least I was and still am.

              +

              Further these devices usually include 2 controllers, one +for each hand and the system can tell exactly where your +hands are and which way they are oriented and so you can +manipulate things in VR by just reaching out, touching, +pushing, twisting, etc...

              +

              6 degree of freedom devices include the Vive and Vive Pro, +the Oculus Rift and Quest, and I believe all of the Windows MR devices.

              +
            6. +
            +

            With all that covered I don't for sure know which devices will work with WebXR. +I'm 99% sure that most Android phones will work when running Chrome. You may +need to turn on WebXR support in about:flags. I also know Google +Daydream will also work and similarly you need to enable WebXR support in +about:flags. Oculus Rift, Vive, and Vive Pro will work via +Chrome or Firefox. I'm less sure about Oculus Go and Oculus Quest as both of +them use custom OSes but according to the internet they both appear to work.

            +

            Okay, after that long detour about VR Devices and WebXR +there's some things to cover

            +
              +
            • Supporting both VR and Non-VR

              +

              AFAICT, at least as of r112, there is no easy way to support +both VR and non-VR modes with three.js. Ideally +if not in VR mode you'd be able to control the camera using +whatever means you want, for example the OrbitControls, +and you'd get some kind of event when switching into and +out of VR mode so that you could turn the controls on/off.

              +
            • +
            +

            If three.js adds some support to do both I'll try to update +this article. Until then you might need 2 versions of your +site OR pass in a flag in the URL, something like

            +
            https://mysite.com/mycooldemo?allowvr=true
            +

            Then we could add some links in to switch modes

            +
            <body>
            +  <canvas id="c"></canvas>
            ++  <div class="mode">
            ++    <a href="?allowvr=true" id="vr">Allow VR</a>
            ++    <a href="?" id="nonvr">Use Non-VR Mode</a>
            ++  </div>
            +</body>
            +
            +

            and some CSS to position them

            +
            body {
            +    margin: 0;
            +}
            +#c {
            +    width: 100%;
            +    height: 100%;
            +    display: block;
            +}
            ++.mode {
            ++  position: absolute;
            ++  right: 1em;
            ++  top: 1em;
            ++}
            +
            +

            in your code you could use that parameter like this

            +
            function main() {
            +  const canvas = document.querySelector('#c');
            +  const renderer = new THREE.WebGLRenderer({canvas});
            +-  renderer.xr.enabled = true;
            +-  document.body.appendChild(VRButton.createButton(renderer));
            +
            +  const fov = 75;
            +  const aspect = 2;  // the canvas default
            +  const near = 0.1;
            +  const far = 5;
            +  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
            +  camera.position.set(0, 1.6, 0);
            +
            ++  const params = (new URL(document.location)).searchParams;
            ++  const allowvr = params.get('allowvr') === 'true';
            ++  if (allowvr) {
            ++    renderer.xr.enabled = true;
            ++    document.body.appendChild(VRButton.createButton(renderer));
            ++    document.querySelector('#vr').style.display = 'none';
            ++  } else {
            ++    // no VR, add some controls
            ++    const controls = new OrbitControls(camera, canvas);
            ++    controls.target.set(0, 1.6, -2);
            ++    controls.update();
            ++    document.querySelector('#nonvr').style.display = 'none';
            ++  }
            +
            +

            Whether that's good or bad I don't know. I have a feeling the differences +between what's needed for VR and what's needed for non-VR are often +very different so for all but the most simple things maybe 2 separate pages +are better? You'll have to decide.

            +

            Note for various reasons this will not work in the live editor +on this site so if you want to check it out +click here. +It should start in non-VR mode and you can use the mouse or fingers to move +the camera. Clicking "Allow VR" should switch to allow VR mode and you should +be able to click "Enter VR" if you're on a VR device.

            +
              +
            • Deciding on the level of VR support

              +

              Above we covered 3 types of VR devices.

              +
                +
              • 3DOF no input
              • +
              • 3DOF + 3DOF input
              • +
              • 6DOF + 6DOF input
              • +
              +

              You need to decide how much effort you're willing to put in +to support each type of device.

              +

              For example the simplest device has no input. The best you can +generally do is make it so there are some buttons or objects in the user's view +and if the user aligns some marker in the center of the display +on those objects for 1/2 a second or so then that button is clicked. +A common UX is to display a small timer that will appear over the object indicating +if you keep the marker there for a moment the object/button will be selected.

              +

              Since there is no other input that's about the best you can do

              +

              The next level up you have one 3DOF input device. Generally it +can point at things and the user has at least 2 buttons. The Daydream +also has a touchpad which provides normal touch inputs.

              +

              In any case if a user has this type of device it's far more +comfortable for the user to by able to point at things with +their controller than it is to make them do it with their +head by looking at things.

              +

              A similar level to that might be 3DOF or 6DOF device with a +game console controller. You'll have to decide what to do here. +I suspect the most common thing is the user still has to look +to point and the controller is just used for buttons.

              +

              The last level is a user with a 6DOF headset and 2 6DOF controllers. +Those users will find an experience that is only 3DOF to often +be frustrating. Similarly they usually expect to be able to +virtually manipulate things with their hands in VR so you'll +have to decide if you want to support that or not.

              +
            • +
            +

            As you can see getting started in VR is pretty easy but +actually making something shippable in VR will require +lots of decision making and design.

            +

            This was a pretty brief intro into VR with three.js. We'll +cover some of the input methods in future articles.

            + +
            +
            +
            + + + + + + + + diff --git a/manual/en/webxr-look-to-select.html b/manual/en/webxr-look-to-select.html index 89c6f296fbeea9..d746092c523534 100644 --- a/manual/en/webxr-look-to-select.html +++ b/manual/en/webxr-look-to-select.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -450,8 +450,8 @@

            VR - Look to Select

            - - + + diff --git a/manual/en/webxr-point-to-select.html b/manual/en/webxr-point-to-select.html index e745e815d389b6..c45b66fc3ded6f 100644 --- a/manual/en/webxr-point-to-select.html +++ b/manual/en/webxr-point-to-select.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -390,8 +390,8 @@

            VR - 3DOF Point to Select

            - - + + diff --git a/manual/en/webxr.html b/manual/en/webxr.html deleted file mode 100644 index 5e50991a451781..00000000000000 --- a/manual/en/webxr.html +++ /dev/null @@ -1,383 +0,0 @@ - - - VR - - - - - - - - - - - - - - - - - -
            -
            -

            VR

            -
            -
            -
            -

            Making a VR app in three.js is pretty simple. You basically just have to tell -three.js you want to use WebXR. If you think about it a few things about WebXR -should be clear. Which way the camera is pointing is supplied by the VR system -itself since the user turns their head to choose a direction to look. Similarly -the field of view and aspect will be supplied by the VR system since each system -has a different field of view and display aspect.

            -

            Let's take an example from the article on making a responsive webpage -and make it support VR.

            -

            Before we get started you're going to need a VR capable device like an Android -smartphone, Google Daydream, Oculus Go, Oculus Rift, Vive, Samsung Gear VR., an -iPhone with a WebXR browser.

            -

            Next, if you are running locally you need to run a simple web server like is -covered in the article on setting up.

            -

            If the device you are using to view VR is not the same computer you're running -on you need to serve your webpage via https or else the browser will not allow using -the WebXR API. The server mentioned in the article on setting up -called Servez has an option to use https. -Check it and start the server.

            -
            - -

            The note the URLs. You need the one that is your computer's local ipaddress. -It will usually start with 192, 172 or 10. Type that full address, including the https:// part -into your VR device's browser. Note: Your computer and your VR device need to be on the same local network -or WiFi and you probably need to be on a home network. note: Many cafes are setup to disallow this kind of -machine to machine connection.

            -

            You'll be greeted with an error something like the one below. Click "advanced" and then click -proceed.

            -
            - -

            Now you can run your examples.

            -

            If you're really going to do WebXR development another thing you should learn about is -remote debugging -so that you can see console warnings, errors, and of course actually -debug your code.

            -

            If you just want to see the code work below you can just run the code from -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';
            -
            -

            Then we need to enable three.js's WebXR support and add its -VR button to our page

            -
            function main() {
            -  const canvas = document.querySelector('#c');
            -  const renderer = new THREE.WebGLRenderer({canvas});
            -+  renderer.xr.enabled = true;
            -+  document.body.appendChild(VRButton.createButton(renderer));
            -
            -

            We need to let three.js run our render loop. Until now we have used a -requestAnimationFrame loop but to support VR we need to let three.js handle -our render loop for us. We can do that by calling -WebGLRenderer.setAnimationLoop and passing a function to call for the loop.

            -
            function render(time) {
            -  time *= 0.001;
            -
            -  if (resizeRendererToDisplaySize(renderer)) {
            -    const canvas = renderer.domElement;
            -    camera.aspect = canvas.clientWidth / canvas.clientHeight;
            -    camera.updateProjectionMatrix();
            -  }
            -
            -  cubes.forEach((cube, ndx) => {
            -    const speed = 1 + ndx * .1;
            -    const rot = time * speed;
            -    cube.rotation.x = rot;
            -    cube.rotation.y = rot;
            -  });
            -
            -  renderer.render(scene, camera);
            -
            --  requestAnimationFrame(render);
            -}
            -
            --requestAnimationFrame(render);
            -+renderer.setAnimationLoop(render);
            -
            -

            There is one more detail. We should probably set a camera height -that's kind of average for a standing user.

            -
            const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
            -+camera.position.set(0, 1.6, 0);
            -
            -

            and move the cubes up to be in front of the camera

            -
            const cube = new THREE.Mesh(geometry, material);
            -scene.add(cube);
            -
            -cube.position.x = x;
            -+cube.position.y = 1.6;
            -+cube.position.z = -2;
            -
            -

            We set them to z = -2 since the camera will now be at z = 0 and -camera defaults to looking down the -z axis.

            -

            This brings up an extremely important point. Units in VR are in meters. -In other words One Unit = One Meter. This means the camera is 1.6 meters above 0. -The cube's centers are 2 meters in front of the camera. Each cube -is 1x1x1 meter large. This is important because VR needs to adjust things to the -user in the real world. That means we need the units used in three.js to match -the user's own movements.

            -

            And with that we should get 3 spinning cubes in front -of the camera with a button to enter VR.

            -

            - -

            -

            I find that VR works better if we have something surrounding the camera like -room for reference so let's add a simple grid cubemap like we covered in -the article on backgrounds. We'll just use the same grid -texture for each side of the cube which will give as a grid room.

            -
            const scene = new THREE.Scene();
            -+{
            -+  const loader = new THREE.CubeTextureLoader();
            -+  const texture = loader.load([
            -+    'resources/images/grid-1024.png',
            -+    'resources/images/grid-1024.png',
            -+    'resources/images/grid-1024.png',
            -+    'resources/images/grid-1024.png',
            -+    'resources/images/grid-1024.png',
            -+    'resources/images/grid-1024.png',
            -+  ]);
            -+  scene.background = texture;
            -+}
            -
            -

            That's better.

            -

            - -

            -

            Note: To actually see VR you will need a WebXR compatible device. -I believe most Android Phones can support WebXR using Chrome or Firefox. -For iOS you might be able to use this WebXR App -though in general WebXR support on iOS is unsupported as of May 2019.

            -

            To use WebXR on Android or iPhone you'll need a VR Headset -for phones. You can get them for anywhere from $5 for one made of cardboard -to $100. Unfortunately I don't know which ones to recommend. I've purchased -6 of them over the years and they are all of varying quality. I've -never paid more than about $25.

            -

            Just to mention some of the issues

            -
              -
            1. Do they fit your phone

              -

              Phones come in a variety of sizes and so the VR headsets need to match. -Many headsets claim to match a large variety of sizes. My experience -is the more sizes they match the worse they actually are since instead -of being designed for a specific size they have to make compromises -to match more sizes. Unfortunately multi-size headsets are the most common type.

              -
            2. -
            3. Can they focus for your face

              -

              Some devices have more adjustments than others. Generally there -are at most 2 adjustments. How far the lenses are from your eyes -and how far apart the lenses are.

              -
            4. -
            5. Are they too reflective

              -

              Many headsets of a cone of plastic from your eye to the phone. -If that plastic is shinny or reflective then it will act like -a mirror reflecting the screen and be very distracting.

              -

              Few if any of the reviews seem to cover this issue.

              -
            6. -
            7. Are the comfortable on your face.

              -

              Most of the devices rest on your nose like a pair of glasses. -That can hurt after a few minutes. Some have straps that go around -your head. Others have a 3rd strap that goes over your head. These -may or may not help keep the device at the right place.

              -

              It turns out for most (all?) devices, you eyes need to be centered -with the lenses. If the lenses are slightly above or below your -eyes the image gets out of focus. This can be very frustrating -as things might start in focus but 45-60 seconds later the device -has shifted up or down 1 millimeter and you suddenly realize you've -been struggling to focus on a blurry image.

              -
            8. -
            9. Can they support your glasses.

              -

              If you wear eye glasses then you'll need to read the reviews to see -if a particular headset works well with eye glasses.

              -
            10. -
            -

            I really can't make any recommendations unfortunately. Google has some -cheap recommendations made from cardboard -some of them as low as $5 so maybe start there and if you enjoy it -then consider upgrading. $5 is like the price of 1 coffee so seriously, give it try!

            -

            There are also 3 basic types of devices.

            -
              -
            1. 3 degrees of freedom (3dof), no input device

              -

              This is generally the phone style although sometimes you can -buy a 3rd party input device. The 3 degrees of freedom -mean you can look up/down (1), left/right(2) and you can tilt -your head left and right (3).

              -
            2. -
            3. 3 degrees of freedom (3dof) with 1 input device (3dof)

              -

              This is basically Google Daydream and Oculus GO

              -

              These also allow 3 degrees of freedom and include a small -controller that acts like a laser pointer inside VR. -The laser pointer also only has 3 degrees of freedom. The -system can tell which way the input device is pointing but -it can not tell where the device is.

              -
            4. -
            5. 6 degrees of freedom (6dof) with input devices (6dof)

              -

              These are the real deal haha. 6 degrees of freedom -means not only do these device know which way you are looking -but they also know where your head actually is. That means -if you move from left to right or forward and back or stand up / sit down -the devices can register this and everything in VR moves accordingly. -It's spookily and amazingly real feeling. With a good demo -you'll be blown away or at least I was and still am.

              -

              Further these devices usually include 2 controllers, one -for each hand and the system can tell exactly where your -hands are and which way they are oriented and so you can -manipulate things in VR by just reaching out, touching, -pushing, twisting, etc...

              -

              6 degree of freedom devices include the Vive and Vive Pro, -the Oculus Rift and Quest, and I believe all of the Windows MR devices.

              -
            6. -
            -

            With all that covered I don't for sure know which devices will work with WebXR. -I'm 99% sure that most Android phones will work when running Chrome. You may -need to turn on WebXR support in about:flags. I also know Google -Daydream will also work and similarly you need to enable WebXR support in -about:flags. Oculus Rift, Vive, and Vive Pro will work via -Chrome or Firefox. I'm less sure about Oculus Go and Oculus Quest as both of -them use custom OSes but according to the internet they both appear to work.

            -

            Okay, after that long detour about VR Devices and WebXR -there's some things to cover

            -
              -
            • Supporting both VR and Non-VR

              -

              AFAICT, at least as of r112, there is no easy way to support -both VR and non-VR modes with three.js. Ideally -if not in VR mode you'd be able to control the camera using -whatever means you want, for example the OrbitControls, -and you'd get some kind of event when switching into and -out of VR mode so that you could turn the controls on/off.

              -
            • -
            -

            If three.js adds some support to do both I'll try to update -this article. Until then you might need 2 versions of your -site OR pass in a flag in the URL, something like

            -
            https://mysite.com/mycooldemo?allowvr=true
            -

            Then we could add some links in to switch modes

            -
            <body>
            -  <canvas id="c"></canvas>
            -+  <div class="mode">
            -+    <a href="?allowvr=true" id="vr">Allow VR</a>
            -+    <a href="?" id="nonvr">Use Non-VR Mode</a>
            -+  </div>
            -</body>
            -
            -

            and some CSS to position them

            -
            body {
            -    margin: 0;
            -}
            -#c {
            -    width: 100%;
            -    height: 100%;
            -    display: block;
            -}
            -+.mode {
            -+  position: absolute;
            -+  right: 1em;
            -+  top: 1em;
            -+}
            -
            -

            in your code you could use that parameter like this

            -
            function main() {
            -  const canvas = document.querySelector('#c');
            -  const renderer = new THREE.WebGLRenderer({canvas});
            --  renderer.xr.enabled = true;
            --  document.body.appendChild(VRButton.createButton(renderer));
            -
            -  const fov = 75;
            -  const aspect = 2;  // the canvas default
            -  const near = 0.1;
            -  const far = 5;
            -  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
            -  camera.position.set(0, 1.6, 0);
            -
            -+  const params = (new URL(document.location)).searchParams;
            -+  const allowvr = params.get('allowvr') === 'true';
            -+  if (allowvr) {
            -+    renderer.xr.enabled = true;
            -+    document.body.appendChild(VRButton.createButton(renderer));
            -+    document.querySelector('#vr').style.display = 'none';
            -+  } else {
            -+    // no VR, add some controls
            -+    const controls = new OrbitControls(camera, canvas);
            -+    controls.target.set(0, 1.6, -2);
            -+    controls.update();
            -+    document.querySelector('#nonvr').style.display = 'none';
            -+  }
            -
            -

            Whether that's good or bad I don't know. I have a feeling the differences -between what's needed for VR and what's needed for non-VR are often -very different so for all but the most simple things maybe 2 separate pages -are better? You'll have to decide.

            -

            Note for various reasons this will not work in the live editor -on this site so if you want to check it out -click here. -It should start in non-VR mode and you can use the mouse or fingers to move -the camera. Clicking "Allow VR" should switch to allow VR mode and you should -be able to click "Enter VR" if you're on a VR device.

            -
              -
            • Deciding on the level of VR support

              -

              Above we covered 3 types of VR devices.

              -
                -
              • 3DOF no input
              • -
              • 3DOF + 3DOF input
              • -
              • 6DOF + 6DOF input
              • -
              -

              You need to decide how much effort you're willing to put in -to support each type of device.

              -

              For example the simplest device has no input. The best you can -generally do is make it so there are some buttons or objects in the user's view -and if the user aligns some marker in the center of the display -on those objects for 1/2 a second or so then that button is clicked. -A common UX is to display a small timer that will appear over the object indicating -if you keep the marker there for a moment the object/button will be selected.

              -

              Since there is no other input that's about the best you can do

              -

              The next level up you have one 3DOF input device. Generally it -can point at things and the user has at least 2 buttons. The Daydream -also has a touchpad which provides normal touch inputs.

              -

              In any case if a user has this type of device it's far more -comfortable for the user to by able to point at things with -their controller than it is to make them do it with their -head by looking at things.

              -

              A similar level to that might be 3DOF or 6DOF device with a -game console controller. You'll have to decide what to do here. -I suspect the most common thing is the user still has to look -to point and the controller is just used for buttons.

              -

              The last level is a user with a 6DOF headset and 2 6DOF controllers. -Those users will find an experience that is only 3DOF to often -be frustrating. Similarly they usually expect to be able to -virtually manipulate things with their hands in VR so you'll -have to decide if you want to support that or not.

              -
            • -
            -

            As you can see getting started in VR is pretty easy but -actually making something shippable in VR will require -lots of decision making and design.

            -

            This was a pretty brief intro into VR with three.js. We'll -cover some of the input methods in future articles.

            - -
            -
            -
            - - - - - - - - \ 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 b882ab4cd31d10..5e0fa601938cbb 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,20 @@ @@ -31,13 +32,13 @@ import * as THREE from 'bmap-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 5d520012bb80c6..82911b0e6885a4 100644 --- a/manual/examples/postprocessing-3dlut.html +++ b/manual/examples/postprocessing-3dlut.html @@ -26,12 +26,14 @@ @@ -42,9 +43,9 @@

            Adobe LUT to PNG converter

            import * as THREE from 'bmap-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 c3a079838a4e59..7a33f7705e56ca 100644 --- a/manual/examples/postprocessing-custom.html +++ b/manual/examples/postprocessing-custom.html @@ -27,17 +27,26 @@ ') || - getHTMLPart(inlineModuleScriptRE, obj, ''); - html = obj.html; - - const fqURL = getFQUrl(url); - /** @type Object */ - const scriptInfos = {}; - g.rootScriptInfo = { - fqURL, - deps: [], - source: rootScript, - }; - scriptInfos[fqURL] = g.rootScriptInfo; + } - const {text} = await getWorkerScripts(rootScript, fqURL, scriptInfos); - g.rootScriptInfo.source = text; - g.scriptInfos = scriptInfos; - for (const [fqURL, scriptInfo] of Object.entries(scriptInfos)) { - addSource('js', basename(fqURL), scriptInfo.source, scriptInfo); - } + function getHTMLPart( re, obj, tag ) { - const tm = titleRE.exec(html); - if (tm) { - g.title = tm[1]; - } + let part = ''; + obj.html = obj.html.replace( re, function ( p0, p1 ) { - const kScript = 'script'; - const scripts = []; - html = html.replace(externalScriptRE, function(p0, p1, p2, type, p3, p4) { - p1 = p1 || ''; - scripts.push(`${p1}<${kScript} ${p2}${safeStr(type)}src="${p3}"${p4}>`); - return ''; - }); + part = p1; + return tag; - const prefix = getPrefix(url); - const rootPrefix = getRootPrefix(url); + } ); + return part.replace( /\s*/, '' ); - function addCorrectPrefix(href) { - return (href.startsWith('/')) - ? `${rootPrefix}${href}` - : removeDotDotSlash((`${prefix}/${href}`).replace(/\/.\//g, '/')); - } + } - function addPrefix(url) { - return url.indexOf('://') < 0 && !url.startsWith('data:') && url[0] !== '?' - ? removeDotDotSlash(addCorrectPrefix(url)) - : url; - } + // doesn't handle multi-line comments or comments with { or } in them + function formatCSS( css ) { - const importMapRE = /type\s*=["']importmap["']/; - const dataScripts = []; - html = html.replace(dataScriptRE, function(p0, blockComments, scriptTagAttrs, content) { - blockComments = blockComments || ''; - if (importMapRE.test(scriptTagAttrs)) { - const imap = JSON.parse(content); - const imports = imap.imports; - if (imports) { - for (let [k, url] of Object.entries(imports)) { - if (url.indexOf('://') < 0 && !url.startsWith('data:')) { - imports[k] = addPrefix(url); - } - } - } - content = JSON.stringify(imap, null, '\t'); - } - dataScripts.push(`${blockComments}<${kScript} ${scriptTagAttrs}>${content}`); - return ''; - }); + let indent = ''; + return css.split( '\n' ).map( ( line ) => { + let currIndent = indent; + if ( line.includes( '{' ) ) { - htmlParts.html.sources[0].source += dataScripts.join('\n'); - htmlParts.html.sources[0].source += scripts.join('\n'); + indent = indent + ' '; - // add style section if there is non - if (html.indexOf('${css}') < 0) { - html = html.replace('', '\n'); - } + } else if ( line.includes( '}' ) ) { - // add hackedparams section. - // We need a way to pass parameters to a blob. Normally they'd be passed as - // query params but that only works in Firefox >:( - html = html.replace('', '\n'); - - html = extraHTMLParsing(html, htmlParts); - - let links = ''; - html = html.replace(cssLinkRE, function(p0, p1) { - if (isCSSLinkRE.test(p1)) { - const m = hrefRE.exec(p1); - if (m) { - links += `@import url("${m[1]}");\n`; - } - return ''; - } else { - return p0; - } - }); + indent = indent.substring( 0, indent.length - 2 ); + currIndent = indent; - htmlParts.css.sources[0].source = links + htmlParts.css.sources[0].source; + } - g.html = html; -} + return `${currIndent}${line.trim()}`; -async function main() { - const query = getQuery(); - g.url = getFQUrl(query.url); - g.query = getSearch(g.url); - let html; - try { - html = await getHTML(query.url); - } catch (err) { - console.log(err); // eslint-disable-line - return; - } - await parseHTML(query.url, html); - setupEditor(); - if (query.startPane) { - const button = document.querySelector('.button-' + query.startPane); - toggleSourcePane(button); - } -} + } ).join( '\n' ); -function getJavaScriptBlob(source) { - const blob = new Blob([source], {type: 'application/javascript'}); - return URL.createObjectURL(blob); -} + } -let blobGeneration = 0; -function makeBlobURLsForSources(scriptInfo) { - ++blobGeneration; - - function makeBlobURLForSourcesImpl(scriptInfo) { - if (scriptInfo.blobGenerationId !== blobGeneration) { - scriptInfo.blobGenerationId = blobGeneration; - if (scriptInfo.blobUrl) { - URL.revokeObjectURL(scriptInfo.blobUrl); - } - scriptInfo.deps.forEach(makeBlobURLForSourcesImpl); - let text = scriptInfo.source; - scriptInfo.deps.forEach((depScriptInfo) => { - text = text.split(depScriptInfo.fqURL).join(depScriptInfo.blobUrl); - }); - scriptInfo.numLinesBeforeScript = 0; - if (scriptInfo.isWorker) { - const extra = `self.lessonSettings = ${JSON.stringify(lessonSettings)}; -import '${dirname(scriptInfo.fqURL)}/resources/webgl-debug-helper.js'; -import '${dirname(scriptInfo.fqURL)}/resources/lessons-worker-helper.js';`; - scriptInfo.numLinesBeforeScript = extra.split('\n').length; - text = `${extra}\n${text}`; - } - scriptInfo.blobUrl = getJavaScriptBlob(text); - scriptInfo.munged = text; - } - } - makeBlobURLForSourcesImpl(scriptInfo); -} + async function getScript( url, scriptInfos ) { -function getSourceBlob(htmlParts) { - g.rootScriptInfo.source = htmlParts.js; - makeBlobURLsForSources(g.rootScriptInfo); - - const dname = dirname(g.url); - // HACK! for webgl-2d-vs... those examples are not in /webgl they're in /webgl/resources - // We basically assume url is https://foo/base/example.html so there will be 4 slashes - // If the path is longer than then we need '../' to back up so prefix works below - const prefix = dname; //`${dname}${dname.split('/').slice(4).map(() => '/..').join('')}`; - let source = g.html; - source = source.replace('${hackedParams}', JSON.stringify(g.query)); - source = source.replace('${html}', htmlParts.html); - source = source.replace('${css}', htmlParts.css); - source = source.replace('${js}', g.rootScriptInfo.munged); //htmlParts.js); - source = source.replace('', ` - - `); + // check it's an example script, not some other lib + if ( ! scriptInfos[ url ].source ) { - source = source.replace('', ` - - `); - const scriptNdx = source.search(//); - g.rootScriptInfo.numLinesBeforeScript = (source.substring(0, scriptNdx).match(/\n/g) || []).length; - - const blob = new Blob([source], {type: 'text/html'}); - // This seems hacky. We are combining html/css/js into one html blob but we already made - // a blob for the JS so let's replace that blob. That means it will get auto-released when script blobs - // are regenerated. It also means error reporting will work - const blobUrl = URL.createObjectURL(blob); - URL.revokeObjectURL(g.rootScriptInfo.blobUrl); - g.rootScriptInfo.blobUrl = blobUrl; - return blobUrl; -} + const source = await getHTML( url ); + const fixedSource = fixSourceLinks( url, source ); + const { text } = await getWorkerScripts( fixedSource, url, scriptInfos ); + scriptInfos[ url ].source = text; -function getSourcesFromEditor() { - for (const partTypeInfo of Object.values(htmlParts)) { - for (const source of partTypeInfo.sources) { - source.source = source.editor.getValue(); - // hack: shouldn't store this twice. Also see other comment, - // should consolidate so scriptInfo is used for css and html - if (source.scriptInfo) { - source.scriptInfo.source = source.source; - } - } - } -} -function getSourceBlobFromEditor() { - getSourcesFromEditor(); + } - return getSourceBlob({ - html: htmlParts.html.sources[0].source, - css: htmlParts.css.sources[0].source, - js: htmlParts.js.sources[0].source, - }); -} + } -function getSourceBlobFromOrig() { - return getSourceBlob({ - html: htmlParts.html.sources[0].source, - css: htmlParts.css.sources[0].source, - js: htmlParts.js.sources[0].source, - }); -} + /** + * @typedef {Object} ScriptInfo + * @property {string} fqURL The original fully qualified URL + * @property {ScriptInfo[]} deps Array of other ScriptInfos this is script dependant on + * @property {boolean} isWorker True if this script came from `new Worker('someurl')` vs `import` or `importScripts` + * @property {string} blobUrl The blobUrl for this script if one has been made + * @property {number} blobGenerationId Used to not visit things twice while recursing. + * @property {string} source The source as extracted. Updated from editor by getSourcesFromEditor + * @property {string} munged The source after urls have been replaced with blob urls etc... (the text send to new Blob) + */ -function dirname(path) { - const ndx = path.lastIndexOf('/'); - return path.substring(0, ndx); -} + async function getWorkerScripts( text, baseUrl, scriptInfos = {} ) { -function basename(path) { - const ndx = path.lastIndexOf('/'); - return path.substring(ndx + 1); -} + const parentScriptInfo = scriptInfos[ baseUrl ]; + const workerRE = /(new\s+Worker\s*\(\s*)('|")(.*?)('|")/g; + const importScriptsRE = /(importScripts\s*\(\s*)('|")(.*?)('|")/g; + const importRE = /(import.*?)(?!'three')('|")(.*?)('|")/g; -function resize() { - forEachHTMLPart(function(info) { - info.editors.forEach((editorInfo) => { - editorInfo.editor.layout(); - }); - }); -} + const newScripts = []; + const slashRE = /\/manual\/examples\/[^/]+$/; -function getScripts(scriptInfo) { - ++blobGeneration; - - function getScriptsImpl(scriptInfo) { - const scripts = []; - if (scriptInfo.blobGenerationId !== blobGeneration) { - scriptInfo.blobGenerationId = blobGeneration; - scripts.push(...scriptInfo.deps.map(getScriptsImpl).flat()); - let text = scriptInfo.source; - scriptInfo.deps.forEach((depScriptInfo) => { - text = text.split(depScriptInfo.fqURL).join(`worker-${basename(depScriptInfo.fqURL)}`); - }); - - scripts.push({ - name: `worker-${basename(scriptInfo.fqURL)}`, - text, - }); - } - return scripts; - } - return getScriptsImpl(scriptInfo); -} + function replaceWithUUID( match, prefix, quote, url ) { -function makeScriptsForWorkers(scriptInfo) { - const scripts = getScripts(scriptInfo); - if (scripts.length === 1) { - return { - js: scripts[0].text, - html: '', - }; - } + const fqURL = getFQUrl( url, baseUrl ); + if ( ! slashRE.test( fqURL ) ) { - // scripts[last] = main script - // scripts[last - 1] = worker - const mainScriptInfo = scripts[scripts.length - 1]; - const workerScriptInfo = scripts[scripts.length - 2]; - const workerName = workerScriptInfo.name; - mainScriptInfo.text = mainScriptInfo.text.split(`'${workerName}'`).join('getWorkerBlob()'); - const html = scripts.map((nameText) => { - const {name, text} = nameText; - return `\n`; - }).join('\n'); - const init = ` + return match.toString(); + } + if ( ! scriptInfos[ url ] ) { -// ------ -// Creates Blobs for the Scripts so things can be self contained for snippets/JSFiddle/Codepen -// even though they are using workers -// -(function() { - const idsToUrls = []; - const scriptElements = [...document.querySelectorAll('script[type=x-worker]')]; - for (const scriptElement of scriptElements) { - let text = scriptElement.text; - for (const {id, url} of idsToUrls) { - text = text.split(id).join(url); - } - const blob = new Blob([text], {type: 'application/javascript'}); - const url = URL.createObjectURL(blob); - const id = scriptElement.id; - idsToUrls.push({id, url}); - } - window.getWorkerBlob = function() { - return idsToUrls.pop().url; - }; - import(window.getWorkerBlob()); -}()); -`; - return { - js: init, - html, - }; -} + scriptInfos[ fqURL ] = { + fqURL, + deps: [], + isWorker: prefix.indexOf( 'Worker' ) >= 0, + }; + newScripts.push( fqURL ); -async function fixHTMLForCodeSite(html) { - html = html.replace(lessonHelperScriptRE, ''); - html = html.replace(webglDebugHelperScriptRE, ''); - return html; -} + } -async function openInCodepen() { - const comment = `// ${g.title} -// from ${g.url} + parentScriptInfo.deps.push( scriptInfos[ fqURL ] ); + return `${prefix}${quote}${fqURL}${quote}`; -`; - getSourcesFromEditor(); - const scripts = makeScriptsForWorkers(g.rootScriptInfo); - const code = await fixJSForCodeSite(scripts.js); - const html = await fixHTMLForCodeSite(htmlParts.html.sources[0].source); + } - const pen = { - title : g.title, - description : 'from: ' + g.url, - tags : lessonEditorSettings.tags, - editors : '101', - html : scripts.html + html, - css : htmlParts.css.sources[0].source, - js : comment + code, - }; + function replaceWithUUIDModule( match, prefix, quote, url ) { - const elem = document.createElement('div'); - elem.innerHTML = ` - " - `; - elem.querySelector('input[name=data]').value = JSON.stringify(pen); - window.frameElement.ownerDocument.body.appendChild(elem); - elem.querySelector('form').submit(); - window.frameElement.ownerDocument.body.removeChild(elem); -} + // modules are either relative, fully qualified, or a module name + // Skip it if it's a module name + return ( url.startsWith( '.' ) || url.includes( '://' ) ) + ? replaceWithUUID( match, prefix, quote, url ) + : match.toString(); -async function openInJSFiddle() { - const comment = `// ${g.title} -// from ${g.url} + } -`; + text = text.replace( workerRE, replaceWithUUID ); + text = text.replace( importScriptsRE, replaceWithUUID ); + text = text.replace( importRE, replaceWithUUIDModule ); - getSourcesFromEditor(); - const scripts = makeScriptsForWorkers(g.rootScriptInfo); - const code = await fixJSForCodeSite(scripts.js); - const html = await fixHTMLForCodeSite(htmlParts.html.sources[0].source); + await Promise.all( newScripts.map( ( url ) => { - const elem = document.createElement('div'); - elem.innerHTML = ` - - `; - elem.querySelector('input[name=html]').value = scripts.html + html; - elem.querySelector('input[name=css]').value = htmlParts.css.sources[0].source; - elem.querySelector('input[name=js]').value = comment + code; - elem.querySelector('input[name=title]').value = g.title; - window.frameElement.ownerDocument.body.appendChild(elem); - elem.querySelector('form').submit(); - window.frameElement.ownerDocument.body.removeChild(elem); -} + return getScript( url, scriptInfos ); -async function openInJSGist() { - const comment = `// ${g.title} -// from ${g.url} + } ) ); + return { text, scriptInfos }; -`; - getSourcesFromEditor(); - const scripts = makeScriptsForWorkers(g.rootScriptInfo); - const code = await fixJSForCodeSite(scripts.js); - const html = await fixHTMLForCodeSite(htmlParts.html.sources[0].source); - const gist = { - name: g.title, - settings: {}, - files: [ - { name: 'index.html', content: scripts.html + html, }, - { name: 'index.css', content: htmlParts.css.sources[0].source, }, - { name: 'index.js', content: comment + code, }, - ], - }; + } - window.open('https://jsgist.org/?newGist=true', '_blank'); - const send = (e) => { - e.source.postMessage({type: 'newGist', data: gist}, '*'); - }; - window.addEventListener('message', send, {once: true}); -} + // hack: scriptInfo is undefined for html and css + // should try to include html and css in scriptInfos + function addSource( type, name, source, scriptInfo ) { -/* + htmlParts[ type ].sources.push( { source, name, scriptInfo } ); - + } - + function safeStr( s ) { - console.log(); + return s === undefined ? '' : s; - + } - h1 { color: red; } + async function parseHTML( url, html ) { - + html = fixSourceLinks( url, html ); -

            foo

            + html = html.replace( /
            [^]*?<\/div>/, '' ); - + const styleRE = /' ) ) ) ); + addSource( 'html', 'html', getHTMLPart( bodyRE, obj, '${html}' ) ); + const rootScript = getHTMLPart( inlineScriptRE, obj, '' ) || + getHTMLPart( inlineModuleScriptRE, obj, '' ); + html = obj.html; -function indent4(s) { - return s.split('\n').map(s => ` ${s}`).join('\n'); -} + const fqURL = getFQUrl( url ); + /** @type Object */ + const scriptInfos = {}; + g.rootScriptInfo = { + fqURL, + deps: [], + source: rootScript, + }; + scriptInfos[ fqURL ] = g.rootScriptInfo; -async function openInStackOverflow() { - const comment = `// ${g.title} -// from ${g.url} + const { text } = await getWorkerScripts( rootScript, fqURL, scriptInfos ); + g.rootScriptInfo.source = text; + g.scriptInfos = scriptInfos; + for ( const [ fqURL, scriptInfo ] of Object.entries( scriptInfos ) ) { + addSource( 'js', basename( fqURL ), scriptInfo.source, scriptInfo ); -`; - getSourcesFromEditor(); - const scripts = makeScriptsForWorkers(g.rootScriptInfo); - const code = await fixJSForCodeSite(scripts.js); - const html = await fixHTMLForCodeSite(htmlParts.html.sources[0].source); - const mainHTML = scripts.html + html; - const mainJS = comment + code; - const mainCSS = htmlParts.css.sources[0].source; - const asModule = /\bimport\b/.test(mainJS); - // Three.js wants us to use modules but Stack Overflow doesn't support them - const text = asModule - ? ` - + } - + const tm = titleRE.exec( html ); + if ( tm ) { - + g.title = tm[ 1 ]; -${indent4(mainCSS)} + } - + const kScript = 'script'; + const scripts = []; + html = html.replace( externalScriptRE, function ( p0, p1, p2, type, p3, p4 ) { -${indent4(mainHTML)} - + p1 = p1 || ''; + scripts.push( `${p1}<${kScript} ${p2}${safeStr( type )}src="${p3}"${p4}>` ); + return ''; - -` - : ` - + } ); - + const prefix = getPrefix( url ); + const rootPrefix = getRootPrefix( url ); -${indent4(mainJS)} + function addCorrectPrefix( href ) { - + return ( href.startsWith( '/' ) ) + ? `${rootPrefix}${href}` + : removeDotDotSlash( ( `${prefix}/${href}` ).replace( /\/.\//g, '/' ) ); -${indent4(mainCSS)} + } - + function addPrefix( url ) { -${indent4(mainHTML)} + return url.indexOf( '://' ) < 0 && ! url.startsWith( 'data:' ) && url[ 0 ] !== '?' + ? removeDotDotSlash( addCorrectPrefix( url ) ) + : url; - -`; - const dialogElem = document.querySelector('.copy-dialog'); - dialogElem.style.display = ''; - const copyAreaElem = dialogElem.querySelector('.copy-area'); - copyAreaElem.textContent = text; - const linkElem = dialogElem.querySelector('a'); - const tags = lessonEditorSettings.tags.filter(f => !f.endsWith('.org')).join(' '); - linkElem.href = `https://stackoverflow.com/questions/ask?&tags=javascript ${tags}`; -} + } -function htmlTemplate(s) { - return ` - - - - - ${s.title} - - - -${s.body} - -${s.script.startsWith('<') - ? s.script - : ` - -`} -`; -} + const importMapRE = /type\s*=["']importmap["']/; + const dataScripts = []; + html = html.replace( dataScriptRE, function ( p0, blockComments, scriptTagAttrs, content ) { -// ---vvv--- + blockComments = blockComments || ''; + if ( importMapRE.test( scriptTagAttrs ) ) { -// Copyright (c) 2013 Pieroxy -// This work is free. You can redistribute it and/or modify it -// under the terms of the WTFPL, Version 2 -// For more information see LICENSE.txt or http://www.wtfpl.net/ -// -// For more information, the home page: -// http://pieroxy.net/blog/pages/lz-string/testing.html -// -// LZ-based compression algorithm, version 1.4.4 -// -// Modified: + const imap = JSON.parse( content ); + const imports = imap.imports; + if ( imports ) { -// private property -const keyStrBase64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + for ( const [ k, url ] of Object.entries( imports ) ) { -function compressToBase64(input) { - if (input === null) { - return ''; - } - const res = _compress(input, 6, function(a) { - return keyStrBase64.charAt(a); - }); - switch (res.length % 4) { // To produce valid Base64 - default: // When could this happen ? - case 0 : return res; - case 1 : return res + '==='; - case 2 : return res + '=='; - case 3 : return res + '='; - } -} + if ( url.indexOf( '://' ) < 0 && ! url.startsWith( 'data:' ) ) { -function _compress(uncompressed, bitsPerChar, getCharFromInt) { - let i; - let value; - const context_dictionary = {}; - const context_dictionaryToCreate = {}; - let context_c = ''; - let context_wc = ''; - let context_w = ''; - let context_enlargeIn = 2; // Compensate for the first entry which should not count - let context_dictSize = 3; - let context_numBits = 2; - const context_data = []; - let context_data_val = 0; - let context_data_position = 0; - let ii; - - for (ii = 0; ii < uncompressed.length; ii += 1) { - context_c = uncompressed.charAt(ii); - if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) { - context_dictionary[context_c] = context_dictSize++; - context_dictionaryToCreate[context_c] = true; - } + imports[ k ] = addPrefix( url ); - context_wc = context_w + context_c; - if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) { - context_w = context_wc; - } else { - if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) { - if (context_w.charCodeAt(0) < 256) { - for (i = 0; i < context_numBits; i++) { - context_data_val = (context_data_val << 1); - if (context_data_position === bitsPerChar - 1) { - context_data_position = 0; - context_data.push(getCharFromInt(context_data_val)); - context_data_val = 0; - } else { - context_data_position++; - } - } - value = context_w.charCodeAt(0); - for (i = 0; i < 8; i++) { - context_data_val = (context_data_val << 1) | (value & 1); - if (context_data_position === bitsPerChar - 1) { - context_data_position = 0; - context_data.push(getCharFromInt(context_data_val)); - context_data_val = 0; - } else { - context_data_position++; - } - value = value >> 1; - } - } else { - value = 1; - for (i = 0; i < context_numBits; i++) { - context_data_val = (context_data_val << 1) | value; - if (context_data_position === bitsPerChar - 1) { - context_data_position = 0; - context_data.push(getCharFromInt(context_data_val)); - context_data_val = 0; - } else { - context_data_position++; - } - value = 0; - } - value = context_w.charCodeAt(0); - for (i = 0; i < 16; i++) { - context_data_val = (context_data_val << 1) | (value & 1); - if (context_data_position === bitsPerChar - 1) { - context_data_position = 0; - context_data.push(getCharFromInt(context_data_val)); - context_data_val = 0; - } else { - context_data_position++; - } - value = value >> 1; - } - } - context_enlargeIn--; - if (context_enlargeIn === 0) { - context_enlargeIn = Math.pow(2, context_numBits); - context_numBits++; - } - delete context_dictionaryToCreate[context_w]; - } else { - value = context_dictionary[context_w]; - for (i = 0; i < context_numBits; i++) { - context_data_val = (context_data_val << 1) | (value & 1); - if (context_data_position === bitsPerChar - 1) { - context_data_position = 0; - context_data.push(getCharFromInt(context_data_val)); - context_data_val = 0; - } else { - context_data_position++; - } - value = value >> 1; - } - - - } - context_enlargeIn--; - if (context_enlargeIn === 0) { - context_enlargeIn = Math.pow(2, context_numBits); - context_numBits++; - } - // Add wc to the dictionary. - context_dictionary[context_wc] = context_dictSize++; - context_w = String(context_c); - } - } + } - // Output the code for w. - if (context_w !== '') { - if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) { - if (context_w.charCodeAt(0) < 256) { - for (i = 0; i < context_numBits; i++) { - context_data_val = (context_data_val << 1); - if (context_data_position === bitsPerChar - 1) { - context_data_position = 0; - context_data.push(getCharFromInt(context_data_val)); - context_data_val = 0; - } else { - context_data_position++; - } - } - value = context_w.charCodeAt(0); - for (i = 0; i < 8; i++) { - context_data_val = (context_data_val << 1) | (value & 1); - if (context_data_position === bitsPerChar - 1) { - context_data_position = 0; - context_data.push(getCharFromInt(context_data_val)); - context_data_val = 0; - } else { - context_data_position++; - } - value = value >> 1; - } - } else { - value = 1; - for (i = 0; i < context_numBits; i++) { - context_data_val = (context_data_val << 1) | value; - if (context_data_position === bitsPerChar - 1) { - context_data_position = 0; - context_data.push(getCharFromInt(context_data_val)); - context_data_val = 0; - } else { - context_data_position++; - } - value = 0; - } - value = context_w.charCodeAt(0); - for (i = 0; i < 16; i++) { - context_data_val = (context_data_val << 1) | (value & 1); - if (context_data_position === bitsPerChar - 1) { - context_data_position = 0; - context_data.push(getCharFromInt(context_data_val)); - context_data_val = 0; - } else { - context_data_position++; - } - value = value >> 1; - } - } - context_enlargeIn--; - if (context_enlargeIn === 0) { - context_enlargeIn = Math.pow(2, context_numBits); - context_numBits++; - } - delete context_dictionaryToCreate[context_w]; - } else { - value = context_dictionary[context_w]; - for (i = 0; i < context_numBits; i++) { - context_data_val = (context_data_val << 1) | (value & 1); - if (context_data_position === bitsPerChar - 1) { - context_data_position = 0; - context_data.push(getCharFromInt(context_data_val)); - context_data_val = 0; - } else { - context_data_position++; - } - value = value >> 1; - } + } + } - } - context_enlargeIn--; - if (context_enlargeIn === 0) { - context_numBits++; - } - } + content = JSON.stringify( imap, null, '\t' ); - // Mark the end of the stream - value = 2; - for (i = 0; i < context_numBits; i++) { - context_data_val = (context_data_val << 1) | (value & 1); - if (context_data_position === bitsPerChar - 1) { - context_data_position = 0; - context_data.push(getCharFromInt(context_data_val)); - context_data_val = 0; - } else { - context_data_position++; - } - value = value >> 1; - } + } - // Flush the last char - for (;;) { - context_data_val = (context_data_val << 1); - if (context_data_position === bitsPerChar - 1) { - context_data.push(getCharFromInt(context_data_val)); - break; - } else { - context_data_position++; - } - } - return context_data.join(''); -} + dataScripts.push( `${blockComments}<${kScript} ${scriptTagAttrs}>${content}` ); + return ''; -function compress(input) { - return compressToBase64(input) - .replace(/\+/g, '-') // Convert '+' to '-' - .replace(/\//g, '_') // Convert '/' to '_' - .replace(/=+$/, ''); // Remove ending '=' -} + } ); -function getParameters(parameters) { - return compress(JSON.stringify(parameters)); -} -// -- ^^^ --- + htmlParts.html.sources[ 0 ].source += dataScripts.join( '\n' ); + htmlParts.html.sources[ 0 ].source += scripts.join( '\n' ); -async function openInCodeSandbox() { - const comment = `// ${g.title} -// from ${g.url} + // add style section if there is non + if ( html.indexOf( '${css}' ) < 0 ) { -`; - getSourcesFromEditor(); - const scripts = getScripts(g.rootScriptInfo); - const mainScript = scripts.pop(); - const code = await fixJSForCodeSite(mainScript.text); - const html = await fixHTMLForCodeSite(htmlParts.html.sources[0].source); - const names = scripts.map(s => s.name); - const files = scripts.reduce((files, {name, text: content}) => { - files[name] = {content}; - return files; - }, { - 'index.html': { - content: htmlTemplate({ - body: html, - css: htmlParts.css.sources[0].source, - title: g.title, - script: comment + code, - }), - }, - 'sandbox.config.json': { - content: '{\n "template": "static"\n}\n', - }, - 'package.json': { - content: JSON.stringify({ - 'name': 'static', - 'version': '1.0.0', - 'description': 'This is a static template with no bundling', - 'main': 'index.html', - 'scripts': { - 'start': 'serve', - 'build': 'echo This is a static template, there is no bundler or bundling involved!', - }, - 'license': 'MIT', - 'devDependencies': { - 'serve': '^11.2.0', - }, - }, null, 2), - }, - }); - for (const file of Object.values(files)) { - for (const name of names) { - file.content = file.content.split(name).join(`./${name}`); + html = html.replace( '', '\n' ); + + } + + // add hackedparams section. + // We need a way to pass parameters to a blob. Normally they'd be passed as + // query params but that only works in Firefox >:( + html = html.replace( '', '\n' ); + + html = extraHTMLParsing( html, htmlParts ); + + let links = ''; + html = html.replace( cssLinkRE, function ( p0, p1 ) { + + if ( isCSSLinkRE.test( p1 ) ) { + + const m = hrefRE.exec( p1 ); + if ( m ) { + + links += `@import url("${m[ 1 ]}");\n`; + + } + + return ''; + + } else { + + return p0; + + } + + } ); + + htmlParts.css.sources[ 0 ].source = links + htmlParts.css.sources[ 0 ].source; + + g.html = html; + + } + + async function main() { + + const query = getQuery(); + g.url = getFQUrl( query.url ); + g.query = getSearch( g.url ); + let html; + try { + + html = await getHTML( query.url ); + + } catch ( err ) { + + console.log(err); // eslint-disable-line + return; + + } + + await parseHTML( query.url, html ); + setupEditor(); + if ( query.startPane ) { + + const button = document.querySelector( '.button-' + query.startPane ); + toggleSourcePane( button ); + + } + + } + + function getJavaScriptBlob( source ) { + + const blob = new Blob( [ source ], { type: 'application/javascript' } ); + return URL.createObjectURL( blob ); + + } + + let blobGeneration = 0; + function makeBlobURLsForSources( scriptInfo ) { + + ++ blobGeneration; + + function makeBlobURLForSourcesImpl( scriptInfo ) { + + if ( scriptInfo.blobGenerationId !== blobGeneration ) { + + scriptInfo.blobGenerationId = blobGeneration; + if ( scriptInfo.blobUrl ) { + + URL.revokeObjectURL( scriptInfo.blobUrl ); + + } + + scriptInfo.deps.forEach( makeBlobURLForSourcesImpl ); + let text = scriptInfo.source; + scriptInfo.deps.forEach( ( depScriptInfo ) => { + + text = text.split( depScriptInfo.fqURL ).join( depScriptInfo.blobUrl ); + + } ); + scriptInfo.numLinesBeforeScript = 0; + if ( scriptInfo.isWorker ) { + + const extra = `self.lessonSettings = ${JSON.stringify( lessonSettings )}; +import '${dirname( scriptInfo.fqURL )}/resources/webgl-debug-helper.js'; +import '${dirname( scriptInfo.fqURL )}/resources/lessons-worker-helper.js';`; + scriptInfo.numLinesBeforeScript = extra.split( '\n' ).length; + text = `${extra}\n${text}`; + + } + + scriptInfo.blobUrl = getJavaScriptBlob( text ); + scriptInfo.munged = text; + + } + + } + + makeBlobURLForSourcesImpl( scriptInfo ); + + } + + function getSourceBlob( htmlParts ) { + + g.rootScriptInfo.source = htmlParts.js; + makeBlobURLsForSources( g.rootScriptInfo ); + + const dname = dirname( g.url ); + // HACK! for webgl-2d-vs... those examples are not in /webgl they're in /webgl/resources + // We basically assume url is https://foo/base/example.html so there will be 4 slashes + // If the path is longer than then we need '../' to back up so prefix works below + const prefix = dname; //`${dname}${dname.split('/').slice(4).map(() => '/..').join('')}`; + let source = g.html; + source = source.replace( '${hackedParams}', JSON.stringify( g.query ) ); + source = source.replace( '${html}', htmlParts.html ); + source = source.replace( '${css}', htmlParts.css ); + source = source.replace( '${js}', g.rootScriptInfo.munged ); //htmlParts.js); + source = source.replace( '', ` + + ` ); + + source = source.replace( '', ` + + ` ); + const scriptNdx = source.search( // ); + g.rootScriptInfo.numLinesBeforeScript = ( source.substring( 0, scriptNdx ).match( /\n/g ) || [] ).length; + + const blob = new Blob( [ source ], { type: 'text/html' } ); + // This seems hacky. We are combining html/css/js into one html blob but we already made + // a blob for the JS so let's replace that blob. That means it will get auto-released when script blobs + // are regenerated. It also means error reporting will work + const blobUrl = URL.createObjectURL( blob ); + URL.revokeObjectURL( g.rootScriptInfo.blobUrl ); + g.rootScriptInfo.blobUrl = blobUrl; + return blobUrl; + + } + + function getSourcesFromEditor() { + + for ( const partTypeInfo of Object.values( htmlParts ) ) { + + for ( const source of partTypeInfo.sources ) { + + source.source = source.editor.getValue(); + // hack: shouldn't store this twice. Also see other comment, + // should consolidate so scriptInfo is used for css and html + if ( source.scriptInfo ) { + + source.scriptInfo.source = source.source; + + } + + } + + } + + } + + function getSourceBlobFromEditor() { + + getSourcesFromEditor(); + + return getSourceBlob( { + html: htmlParts.html.sources[ 0 ].source, + css: htmlParts.css.sources[ 0 ].source, + js: htmlParts.js.sources[ 0 ].source, + } ); + + } + + function getSourceBlobFromOrig() { + + return getSourceBlob( { + html: htmlParts.html.sources[ 0 ].source, + css: htmlParts.css.sources[ 0 ].source, + js: htmlParts.js.sources[ 0 ].source, + } ); + + } + + function dirname( path ) { + + const ndx = path.lastIndexOf( '/' ); + return path.substring( 0, ndx ); + + } + + function basename( path ) { + + const ndx = path.lastIndexOf( '/' ); + return path.substring( ndx + 1 ); + + } + + function resize() { + + forEachHTMLPart( function ( info ) { + + info.editors.forEach( ( editorInfo ) => { + + editorInfo.editor.layout(); + + } ); + + } ); + + } + + function getScripts( scriptInfo ) { + + ++ blobGeneration; + + function getScriptsImpl( scriptInfo ) { + + const scripts = []; + if ( scriptInfo.blobGenerationId !== blobGeneration ) { + + scriptInfo.blobGenerationId = blobGeneration; + scripts.push( ...scriptInfo.deps.map( getScriptsImpl ).flat() ); + let text = scriptInfo.source; + scriptInfo.deps.forEach( ( depScriptInfo ) => { + + text = text.split( depScriptInfo.fqURL ).join( `worker-${basename( depScriptInfo.fqURL )}` ); + + } ); + + scripts.push( { + name: `worker-${basename( scriptInfo.fqURL )}`, + text, + } ); + + } + + return scripts; + + } + + return getScriptsImpl( scriptInfo ); + + } + + function makeScriptsForWorkers( scriptInfo ) { + + const scripts = getScripts( scriptInfo ); + if ( scripts.length === 1 ) { + + return { + js: scripts[ 0 ].text, + html: '', + }; + + } + + // scripts[last] = main script + // scripts[last - 1] = worker + const mainScriptInfo = scripts[ scripts.length - 1 ]; + const workerScriptInfo = scripts[ scripts.length - 2 ]; + const workerName = workerScriptInfo.name; + mainScriptInfo.text = mainScriptInfo.text.split( `'${workerName}'` ).join( 'getWorkerBlob()' ); + const html = scripts.map( ( nameText ) => { + + const { name, text } = nameText; + return `\n`; + + } ).join( '\n' ); + const init = ` + + + +// ------ +// Creates Blobs for the Scripts so things can be self contained for snippets/JSFiddle/Codepen +// even though they are using workers +// +(function() { + const idsToUrls = []; + const scriptElements = [...document.querySelectorAll('script[type=x-worker]')]; + for (const scriptElement of scriptElements) { + let text = scriptElement.text; + for (const {id, url} of idsToUrls) { + text = text.split(id).join(url); } + const blob = new Blob([text], {type: 'application/javascript'}); + const url = URL.createObjectURL(blob); + const id = scriptElement.id; + idsToUrls.push({id, url}); } + window.getWorkerBlob = function() { + return idsToUrls.pop().url; + }; + import(window.getWorkerBlob()); +}()); +`; + return { + js: init, + html, + }; + + } + + async function fixHTMLForCodeSite( html ) { + + html = html.replace( lessonHelperScriptRE, '' ); + html = html.replace( webglDebugHelperScriptRE, '' ); + return html; + + } + + async function openInCodepen() { + + const comment = `// ${g.title} +// from ${g.url} + + +`; + getSourcesFromEditor(); + const scripts = makeScriptsForWorkers( g.rootScriptInfo ); + const code = await fixJSForCodeSite( scripts.js ); + const html = await fixHTMLForCodeSite( htmlParts.html.sources[ 0 ].source ); + + const pen = { + title: g.title, + description: 'from: ' + g.url, + tags: lessonEditorSettings.tags, + editors: '101', + html: scripts.html + html, + css: htmlParts.css.sources[ 0 ].source, + js: comment + code, + }; + + const elem = document.createElement( 'div' ); + elem.innerHTML = ` + " + `; + elem.querySelector( 'input[name=data]' ).value = JSON.stringify( pen ); + window.frameElement.ownerDocument.body.appendChild( elem ); + elem.querySelector( 'form' ).submit(); + window.frameElement.ownerDocument.body.removeChild( elem ); + + } + + async function openInJSFiddle() { + + const comment = `// ${g.title} +// from ${g.url} + +`; + + getSourcesFromEditor(); + const scripts = makeScriptsForWorkers( g.rootScriptInfo ); + const code = await fixJSForCodeSite( scripts.js ); + const html = await fixHTMLForCodeSite( htmlParts.html.sources[ 0 ].source ); + + const elem = document.createElement( 'div' ); + elem.innerHTML = ` + + `; + elem.querySelector( 'input[name=html]' ).value = scripts.html + html; + elem.querySelector( 'input[name=css]' ).value = htmlParts.css.sources[ 0 ].source; + elem.querySelector( 'input[name=js]' ).value = comment + code; + elem.querySelector( 'input[name=title]' ).value = g.title; + window.frameElement.ownerDocument.body.appendChild( elem ); + elem.querySelector( 'form' ).submit(); + window.frameElement.ownerDocument.body.removeChild( elem ); + + } + + async function openInJSGist() { + + const comment = `// ${g.title} +// from ${g.url} + + +`; + getSourcesFromEditor(); + const scripts = makeScriptsForWorkers( g.rootScriptInfo ); + const code = await fixJSForCodeSite( scripts.js ); + const html = await fixHTMLForCodeSite( htmlParts.html.sources[ 0 ].source ); + const gist = { + name: g.title, + settings: {}, + files: [ + { name: 'index.html', content: scripts.html + html, }, + { name: 'index.css', content: htmlParts.css.sources[ 0 ].source, }, + { name: 'index.js', content: comment + code, }, + ], + }; + + window.open( 'https://jsgist.org/?newGist=true', '_blank' ); + const send = ( e ) => { + + e.source.postMessage( { type: 'newGist', data: gist }, '*' ); + + }; + + window.addEventListener( 'message', send, { once: true } ); + + } + + /* + + + + + + console.log(); + + + + h1 { color: red; } + + + +

            foo

            + + + +*/ + + function indent4( s ) { + + return s.split( '\n' ).map( s => ` ${s}` ).join( '\n' ); + + } + + async function openInStackOverflow() { + + const comment = `// ${g.title} +// from ${g.url} + + +`; + getSourcesFromEditor(); + const scripts = makeScriptsForWorkers( g.rootScriptInfo ); + const code = await fixJSForCodeSite( scripts.js ); + const html = await fixHTMLForCodeSite( htmlParts.html.sources[ 0 ].source ); + const mainHTML = scripts.html + html; + const mainJS = comment + code; + const mainCSS = htmlParts.css.sources[ 0 ].source; + const asModule = /\bimport\b/.test( mainJS ); + // Three.js wants us to use modules but Stack Overflow doesn't support them + const text = asModule + ? ` + + + + + + +${indent4( mainCSS )} + + + +${indent4( mainHTML )} + + + +` + : ` + + + + +${indent4( mainJS )} + + + +${indent4( mainCSS )} + + + +${indent4( mainHTML )} + + +`; + const dialogElem = document.querySelector( '.copy-dialog' ); + dialogElem.style.display = ''; + const copyAreaElem = dialogElem.querySelector( '.copy-area' ); + copyAreaElem.textContent = text; + const linkElem = dialogElem.querySelector( 'a' ); + const tags = lessonEditorSettings.tags.filter( f => ! f.endsWith( '.org' ) ).join( ' ' ); + linkElem.href = `https://stackoverflow.com/questions/ask?&tags=javascript ${tags}`; + + } + + function htmlTemplate( s ) { + + return ` + + + + + ${s.title} + + + +${s.body} + +${s.script.startsWith( '<' ) + ? s.script + : ` + +`} +`; + + } + + // ---vvv--- + + // Copyright (c) 2013 Pieroxy + // This work is free. You can redistribute it and/or modify it + // under the terms of the WTFPL, Version 2 + // For more information see LICENSE.txt or http://www.wtfpl.net/ + // + // For more information, the home page: + // http://pieroxy.net/blog/pages/lz-string/testing.html + // + // LZ-based compression algorithm, version 1.4.4 + // + // Modified: + + // private property + const keyStrBase64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + + function compressToBase64( input ) { + + if ( input === null ) { + + return ''; + + } + + const res = _compress( input, 6, function ( a ) { + + return keyStrBase64.charAt( a ); + + } ); + switch ( res.length % 4 ) { // To produce valid Base64 + + default: // When could this happen ? + case 0 : return res; + case 1 : return res + '==='; + case 2 : return res + '=='; + case 3 : return res + '='; + + } + + } + + function _compress( uncompressed, bitsPerChar, getCharFromInt ) { + + let i; + let value; + const context_dictionary = {}; + const context_dictionaryToCreate = {}; + let context_c = ''; + let context_wc = ''; + let context_w = ''; + let context_enlargeIn = 2; // Compensate for the first entry which should not count + let context_dictSize = 3; + let context_numBits = 2; + const context_data = []; + let context_data_val = 0; + let context_data_position = 0; + let ii; + + for ( ii = 0; ii < uncompressed.length; ii += 1 ) { + + context_c = uncompressed.charAt( ii ); + if ( ! Object.prototype.hasOwnProperty.call( context_dictionary, context_c ) ) { + + context_dictionary[ context_c ] = context_dictSize ++; + context_dictionaryToCreate[ context_c ] = true; + + } + + context_wc = context_w + context_c; + if ( Object.prototype.hasOwnProperty.call( context_dictionary, context_wc ) ) { + + context_w = context_wc; + + } else { + + if ( Object.prototype.hasOwnProperty.call( context_dictionaryToCreate, context_w ) ) { + + if ( context_w.charCodeAt( 0 ) < 256 ) { + + for ( i = 0; i < context_numBits; i ++ ) { + + context_data_val = ( context_data_val << 1 ); + if ( context_data_position === bitsPerChar - 1 ) { + + context_data_position = 0; + context_data.push( getCharFromInt( context_data_val ) ); + context_data_val = 0; + + } else { + + context_data_position ++; + + } + + } + + value = context_w.charCodeAt( 0 ); + for ( i = 0; i < 8; i ++ ) { + + context_data_val = ( context_data_val << 1 ) | ( value & 1 ); + if ( context_data_position === bitsPerChar - 1 ) { + + context_data_position = 0; + context_data.push( getCharFromInt( context_data_val ) ); + context_data_val = 0; + + } else { + + context_data_position ++; + + } + + value = value >> 1; + + } + + } else { + + value = 1; + for ( i = 0; i < context_numBits; i ++ ) { + + context_data_val = ( context_data_val << 1 ) | value; + if ( context_data_position === bitsPerChar - 1 ) { + + context_data_position = 0; + context_data.push( getCharFromInt( context_data_val ) ); + context_data_val = 0; + + } else { + + context_data_position ++; + + } + + value = 0; + + } + + value = context_w.charCodeAt( 0 ); + for ( i = 0; i < 16; i ++ ) { + + context_data_val = ( context_data_val << 1 ) | ( value & 1 ); + if ( context_data_position === bitsPerChar - 1 ) { + + context_data_position = 0; + context_data.push( getCharFromInt( context_data_val ) ); + context_data_val = 0; + + } else { + + context_data_position ++; + + } + + value = value >> 1; + + } + + } + + context_enlargeIn --; + if ( context_enlargeIn === 0 ) { + + context_enlargeIn = Math.pow( 2, context_numBits ); + context_numBits ++; + + } + + delete context_dictionaryToCreate[ context_w ]; + + } else { + + value = context_dictionary[ context_w ]; + for ( i = 0; i < context_numBits; i ++ ) { + + context_data_val = ( context_data_val << 1 ) | ( value & 1 ); + if ( context_data_position === bitsPerChar - 1 ) { + + context_data_position = 0; + context_data.push( getCharFromInt( context_data_val ) ); + context_data_val = 0; + + } else { + + context_data_position ++; + + } + + value = value >> 1; + + } + + + } + + context_enlargeIn --; + if ( context_enlargeIn === 0 ) { + + context_enlargeIn = Math.pow( 2, context_numBits ); + context_numBits ++; + + } + + // Add wc to the dictionary. + context_dictionary[ context_wc ] = context_dictSize ++; + context_w = String( context_c ); + + } + + } + + // Output the code for w. + if ( context_w !== '' ) { + + if ( Object.prototype.hasOwnProperty.call( context_dictionaryToCreate, context_w ) ) { + + if ( context_w.charCodeAt( 0 ) < 256 ) { + + for ( i = 0; i < context_numBits; i ++ ) { + + context_data_val = ( context_data_val << 1 ); + if ( context_data_position === bitsPerChar - 1 ) { + + context_data_position = 0; + context_data.push( getCharFromInt( context_data_val ) ); + context_data_val = 0; + + } else { + + context_data_position ++; + + } + + } + + value = context_w.charCodeAt( 0 ); + for ( i = 0; i < 8; i ++ ) { + + context_data_val = ( context_data_val << 1 ) | ( value & 1 ); + if ( context_data_position === bitsPerChar - 1 ) { + + context_data_position = 0; + context_data.push( getCharFromInt( context_data_val ) ); + context_data_val = 0; + + } else { + + context_data_position ++; + + } + + value = value >> 1; + + } + + } else { + + value = 1; + for ( i = 0; i < context_numBits; i ++ ) { + + context_data_val = ( context_data_val << 1 ) | value; + if ( context_data_position === bitsPerChar - 1 ) { - const parameters = getParameters({files}); - const elem = document.createElement('div'); - elem.innerHTML = ` + context_data_position = 0; + context_data.push( getCharFromInt( context_data_val ) ); + context_data_val = 0; + + } else { + + context_data_position ++; + + } + + value = 0; + + } + + value = context_w.charCodeAt( 0 ); + for ( i = 0; i < 16; i ++ ) { + + context_data_val = ( context_data_val << 1 ) | ( value & 1 ); + if ( context_data_position === bitsPerChar - 1 ) { + + context_data_position = 0; + context_data.push( getCharFromInt( context_data_val ) ); + context_data_val = 0; + + } else { + + context_data_position ++; + + } + + value = value >> 1; + + } + + } + + context_enlargeIn --; + if ( context_enlargeIn === 0 ) { + + context_enlargeIn = Math.pow( 2, context_numBits ); + context_numBits ++; + + } + + delete context_dictionaryToCreate[ context_w ]; + + } else { + + value = context_dictionary[ context_w ]; + for ( i = 0; i < context_numBits; i ++ ) { + + context_data_val = ( context_data_val << 1 ) | ( value & 1 ); + if ( context_data_position === bitsPerChar - 1 ) { + + context_data_position = 0; + context_data.push( getCharFromInt( context_data_val ) ); + context_data_val = 0; + + } else { + + context_data_position ++; + + } + + value = value >> 1; + + } + + + } + + context_enlargeIn --; + if ( context_enlargeIn === 0 ) { + + context_numBits ++; + + } + + } + + // Mark the end of the stream + value = 2; + for ( i = 0; i < context_numBits; i ++ ) { + + context_data_val = ( context_data_val << 1 ) | ( value & 1 ); + if ( context_data_position === bitsPerChar - 1 ) { + + context_data_position = 0; + context_data.push( getCharFromInt( context_data_val ) ); + context_data_val = 0; + + } else { + + context_data_position ++; + + } + + value = value >> 1; + + } + + // Flush the last char + for ( ;; ) { + + context_data_val = ( context_data_val << 1 ); + if ( context_data_position === bitsPerChar - 1 ) { + + context_data.push( getCharFromInt( context_data_val ) ); + break; + + } else { + + context_data_position ++; + + } + + } + + return context_data.join( '' ); + + } + + function compress( input ) { + + return compressToBase64( input ) + .replace( /\+/g, '-' ) // Convert '+' to '-' + .replace( /\//g, '_' ) // Convert '/' to '_' + .replace( /=+$/, '' ); // Remove ending '=' + + } + + function getParameters( parameters ) { + + return compress( JSON.stringify( parameters ) ); + + } + + // -- ^^^ --- + + async function openInCodeSandbox() { + + const comment = `// ${g.title} +// from ${g.url} + +`; + getSourcesFromEditor(); + const scripts = getScripts( g.rootScriptInfo ); + const mainScript = scripts.pop(); + const code = await fixJSForCodeSite( mainScript.text ); + const html = await fixHTMLForCodeSite( htmlParts.html.sources[ 0 ].source ); + const names = scripts.map( s => s.name ); + const files = scripts.reduce( ( files, { name, text: content } ) => { + + files[ name ] = { content }; + return files; + + }, { + 'index.html': { + content: htmlTemplate( { + body: html, + css: htmlParts.css.sources[ 0 ].source, + title: g.title, + script: comment + code, + } ), + }, + 'sandbox.config.json': { + content: '{\n "template": "static"\n}\n', + }, + 'package.json': { + content: JSON.stringify( { + 'name': 'static', + 'version': '1.0.0', + 'description': 'This is a static template with no bundling', + 'main': 'index.html', + 'scripts': { + 'start': 'serve', + 'build': 'echo This is a static template, there is no bundler or bundling involved!', + }, + 'license': 'MIT', + 'devDependencies': { + 'serve': '^11.2.0', + }, + }, null, 2 ), + }, + } ); + for ( const file of Object.values( files ) ) { + + for ( const name of names ) { + + file.content = file.content.split( name ).join( `./${name}` ); + + } + + } + + const parameters = getParameters( { files } ); + const elem = document.createElement( 'div' ); + elem.innerHTML = ` `; - elem.querySelector('input[name=parameters]').value = parameters; - window.frameElement.ownerDocument.body.appendChild(elem); - elem.querySelector('form').submit(); - window.frameElement.ownerDocument.body.removeChild(elem); -} + elem.querySelector( 'input[name=parameters]' ).value = parameters; + window.frameElement.ownerDocument.body.appendChild( elem ); + elem.querySelector( 'form' ).submit(); + window.frameElement.ownerDocument.body.removeChild( elem ); + + } -/* + /* async function openInStackBlitz() { const comment = `// ${g.title} // from ${g.url} @@ -1186,313 +1525,447 @@ async function openInStackBlitz() { } */ -document.querySelectorAll('.dialog').forEach(dialogElem => { - dialogElem.addEventListener('click', function(e) { - if (e.target === this) { - this.style.display = 'none'; - } - }); - dialogElem.addEventListener('keydown', function(e) { - console.log(e.keyCode); - if (e.keyCode === 27) { - this.style.display = 'none'; - } - }); -}); -const exportDialogElem = document.querySelector('.export'); + document.querySelectorAll( '.dialog' ).forEach( dialogElem => { -function openExport() { - exportDialogElem.style.display = ''; - exportDialogElem.firstElementChild.focus(); -} + dialogElem.addEventListener( 'click', function ( e ) { -function closeExport(fn) { - return () => { - exportDialogElem.style.display = 'none'; - fn(); - }; -} -document.querySelector('.button-export').addEventListener('click', openExport); + if ( e.target === this ) { -function selectFile(info, ndx, fileDivs) { - if (info.editors.length <= 1) { - return; - } - info.editors.forEach((editorInfo, i) => { - const selected = i === ndx; - editorInfo.div.style.display = selected ? '' : 'none'; - editorInfo.editor.layout(); - addRemoveClass(fileDivs.children[i], 'fileSelected', selected); - }); -} + this.style.display = 'none'; -function showEditorSubPane(type, ndx) { - const info = htmlParts[type]; - selectFile(info, ndx, info.files); -} + } -function setupEditor() { - - forEachHTMLPart(function(info, ndx, name) { - info.pane = document.querySelector('.panes>.' + name); - info.code = info.pane.querySelector('.code'); - info.files = info.pane.querySelector('.files'); - info.editors = info.sources.map((sourceInfo, ndx) => { - if (info.sources.length > 1) { - const div = document.createElement('div'); - div.textContent = basename(sourceInfo.name); - info.files.appendChild(div); - div.addEventListener('click', () => { - selectFile(info, ndx, info.files); - }); - } - const div = document.createElement('div'); - info.code.appendChild(div); - const editor = runEditor(div, sourceInfo.source, info.language); - sourceInfo.editor = editor; - return { - div, - editor, - }; - }); - info.button = document.querySelector('.button-' + name); - info.button.addEventListener('click', function() { - toggleSourcePane(info.button); - runIfNeeded(); - }); - }); + } ); + dialogElem.addEventListener( 'keydown', function ( e ) { - g.fullscreen = document.querySelector('.button-fullscreen'); - g.fullscreen.addEventListener('click', toggleFullscreen); + console.log( e.keyCode ); + if ( e.keyCode === 27 ) { - g.run = document.querySelector('.button-run'); - g.run.addEventListener('click', run); + this.style.display = 'none'; - g.iframe = document.querySelector('.result>iframe'); - g.other = document.querySelector('.panes .other'); + } - document.querySelector('.button-codepen').addEventListener('click', closeExport(openInCodepen)); - document.querySelector('.button-jsfiddle').addEventListener('click', closeExport(openInJSFiddle)); - document.querySelector('.button-jsgist').addEventListener('click', closeExport(openInJSGist)); - document.querySelector('.button-stackoverflow').addEventListener('click', closeExport(openInStackOverflow)); - document.querySelector('.button-codesandbox').addEventListener('click', closeExport(openInCodeSandbox)); - //document.querySelector('.button-stackblitz').addEventListener('click', openInStackBlitz); + } ); - g.result = document.querySelector('.panes .result'); - g.resultButton = document.querySelector('.button-result'); - g.resultButton.addEventListener('click', function() { - toggleResultPane(); - runIfNeeded(); - }); - g.result.style.display = 'none'; - toggleResultPane(); + } ); + const exportDialogElem = document.querySelector( '.export' ); - if (window.innerWidth >= 1000) { - toggleSourcePane(htmlParts.js.button); - } + function openExport() { - window.addEventListener('resize', resize); + exportDialogElem.style.display = ''; + exportDialogElem.firstElementChild.focus(); - showEditorSubPane('js', 0); - showOtherIfAllPanesOff(); - document.querySelector('.other .loading').style.display = 'none'; + } - resize(); - run(); -} + function closeExport( fn ) { + + return () => { + + exportDialogElem.style.display = 'none'; + fn(); + + }; + + } + + document.querySelector( '.button-export' ).addEventListener( 'click', openExport ); + + function selectFile( info, ndx, fileDivs ) { + + if ( info.editors.length <= 1 ) { + + return; + + } + + info.editors.forEach( ( editorInfo, i ) => { + + const selected = i === ndx; + editorInfo.div.style.display = selected ? '' : 'none'; + editorInfo.editor.layout(); + addRemoveClass( fileDivs.children[ i ], 'fileSelected', selected ); + + } ); + + } + + function showEditorSubPane( type, ndx ) { + + const info = htmlParts[ type ]; + selectFile( info, ndx, info.files ); + + } + + function setupEditor() { + + forEachHTMLPart( function ( info, ndx, name ) { + + info.pane = document.querySelector( '.panes>.' + name ); + info.code = info.pane.querySelector( '.code' ); + info.files = info.pane.querySelector( '.files' ); + info.editors = info.sources.map( ( sourceInfo, ndx ) => { + + if ( info.sources.length > 1 ) { + + const div = document.createElement( 'div' ); + div.textContent = basename( sourceInfo.name ); + info.files.appendChild( div ); + div.addEventListener( 'click', () => { + + selectFile( info, ndx, info.files ); + + } ); + + } + + const div = document.createElement( 'div' ); + info.code.appendChild( div ); + const editor = runEditor( div, sourceInfo.source, info.language ); + sourceInfo.editor = editor; + return { + div, + editor, + }; + + } ); + info.button = document.querySelector( '.button-' + name ); + info.button.addEventListener( 'click', function () { + + toggleSourcePane( info.button ); + runIfNeeded(); + + } ); + + } ); + + g.fullscreen = document.querySelector( '.button-fullscreen' ); + g.fullscreen.addEventListener( 'click', toggleFullscreen ); + + g.run = document.querySelector( '.button-run' ); + g.run.addEventListener( 'click', run ); + + g.iframe = document.querySelector( '.result>iframe' ); + g.other = document.querySelector( '.panes .other' ); + + document.querySelector( '.button-codepen' ).addEventListener( 'click', closeExport( openInCodepen ) ); + document.querySelector( '.button-jsfiddle' ).addEventListener( 'click', closeExport( openInJSFiddle ) ); + document.querySelector( '.button-jsgist' ).addEventListener( 'click', closeExport( openInJSGist ) ); + document.querySelector( '.button-stackoverflow' ).addEventListener( 'click', closeExport( openInStackOverflow ) ); + document.querySelector( '.button-codesandbox' ).addEventListener( 'click', closeExport( openInCodeSandbox ) ); + //document.querySelector('.button-stackblitz').addEventListener('click', openInStackBlitz); + + g.result = document.querySelector( '.panes .result' ); + g.resultButton = document.querySelector( '.button-result' ); + g.resultButton.addEventListener( 'click', function () { + + toggleResultPane(); + runIfNeeded(); + + } ); + g.result.style.display = 'none'; + toggleResultPane(); + + if ( window.innerWidth >= 1000 ) { + + toggleSourcePane( htmlParts.js.button ); + + } + + window.addEventListener( 'resize', resize ); + + showEditorSubPane( 'js', 0 ); + showOtherIfAllPanesOff(); + document.querySelector( '.other .loading' ).style.display = 'none'; + + resize(); + run(); + + } + + function toggleFullscreen() { + + try { + + toggleIFrameFullscreen( window ); + resize(); + runIfNeeded(); + + } catch ( e ) { -function toggleFullscreen() { - try { - toggleIFrameFullscreen(window); - resize(); - runIfNeeded(); - } catch (e) { console.error(e); // eslint-disable-line - } -} + } -function runIfNeeded() { - if (runOnResize) { - run(); - } -} + } -function run() { - g.setPosition = false; - const url = getSourceBlobFromEditor(); - g.iframe.src = url; -} + function runIfNeeded() { -function addClass(elem, className) { - const parts = elem.className.split(' '); - if (parts.indexOf(className) < 0) { - elem.className = elem.className + ' ' + className; - } -} + if ( runOnResize ) { -function removeClass(elem, className) { - const parts = elem.className.split(' '); - const numParts = parts.length; - for (;;) { - const ndx = parts.indexOf(className); - if (ndx < 0) { - break; - } - parts.splice(ndx, 1); - } - if (parts.length !== numParts) { - elem.className = parts.join(' '); - return true; - } - return false; -} + run(); -function toggleClass(elem, className) { - if (removeClass(elem, className)) { - return false; - } else { - addClass(elem, className); - return true; - } -} + } -function toggleIFrameFullscreen(childWindow) { - const frame = childWindow.frameElement; - if (frame) { - const isFullScreen = toggleClass(frame, 'fullscreen'); - frame.ownerDocument.body.style.overflow = isFullScreen ? 'hidden' : ''; - } -} + } + function run() { -function addRemoveClass(elem, className, add) { - if (add) { - addClass(elem, className); - } else { - removeClass(elem, className); - } -} + g.setPosition = false; + const url = getSourceBlobFromEditor(); + g.iframe.src = url; -function toggleSourcePane(pressedButton) { - forEachHTMLPart(function(info) { - const pressed = pressedButton === info.button; - if (pressed && !info.showing) { - addClass(info.button, 'show'); - info.pane.style.display = 'flex'; - info.showing = true; - } else { - removeClass(info.button, 'show'); - info.pane.style.display = 'none'; - info.showing = false; - } - }); - showOtherIfAllPanesOff(); - resize(); -} + } -function showingResultPane() { - return g.result.style.display !== 'none'; -} -function toggleResultPane() { - const showing = showingResultPane(); - g.result.style.display = showing ? 'none' : 'block'; - addRemoveClass(g.resultButton, 'show', !showing); - showOtherIfAllPanesOff(); - resize(); -} + function addClass( elem, className ) { -function showOtherIfAllPanesOff() { - let paneOn = showingResultPane(); - forEachHTMLPart(function(info) { - paneOn = paneOn || info.showing; - }); - g.other.style.display = paneOn ? 'none' : 'block'; -} + const parts = elem.className.split( ' ' ); + if ( parts.indexOf( className ) < 0 ) { -// seems like we should probably store a map -function getEditorNdxByBlobUrl(type, url) { - return htmlParts[type].sources.findIndex(source => source.scriptInfo.blobUrl === url); -} + elem.className = elem.className + ' ' + className; -function getActualLineNumberAndMoveTo(url, lineNo, colNo) { - let origUrl = url; - let actualLineNo = lineNo; - const scriptInfo = Object.values(g.scriptInfos).find(scriptInfo => scriptInfo.blobUrl === url); - if (scriptInfo) { - actualLineNo = lineNo - scriptInfo.numLinesBeforeScript; - origUrl = basename(scriptInfo.fqURL); - if (!g.setPosition) { - // Only set the first position - g.setPosition = true; - const editorNdx = getEditorNdxByBlobUrl('js', url); - if (editorNdx >= 0) { - showEditorSubPane('js', editorNdx); - const editor = htmlParts.js.editors[editorNdx].editor; - editor.setPosition({ - lineNumber: actualLineNo, - column: colNo, - }); - editor.revealLineInCenterIfOutsideViewport(actualLineNo); - editor.focus(); - } - } - } - return {origUrl, actualLineNo}; -} + } -window.getActualLineNumberAndMoveTo = getActualLineNumberAndMoveTo; - -function runEditor(parent, source, language) { - return monaco.editor.create(parent, { - value: source, - language: language, - //lineNumbers: false, - theme: 'vs-dark', - disableTranslate3d: true, - // model: null, - scrollBeyondLastLine: false, - minimap: { enabled: false }, - }); -} + } + + function removeClass( elem, className ) { + + const parts = elem.className.split( ' ' ); + const numParts = parts.length; + for ( ;; ) { + + const ndx = parts.indexOf( className ); + if ( ndx < 0 ) { + + break; + + } + + parts.splice( ndx, 1 ); + + } + + if ( parts.length !== numParts ) { + + elem.className = parts.join( ' ' ); + return true; + + } + + return false; + + } + + function toggleClass( elem, className ) { + + if ( removeClass( elem, className ) ) { + + return false; + + } else { + + addClass( elem, className ); + return true; + + } + + } + + function toggleIFrameFullscreen( childWindow ) { + + const frame = childWindow.frameElement; + if ( frame ) { + + const isFullScreen = toggleClass( frame, 'fullscreen' ); + frame.ownerDocument.body.style.overflow = isFullScreen ? 'hidden' : ''; + + } + + } + + + function addRemoveClass( elem, className, add ) { + + if ( add ) { + + addClass( elem, className ); + + } else { + + removeClass( elem, className ); + + } + + } + + function toggleSourcePane( pressedButton ) { + + forEachHTMLPart( function ( info ) { + + const pressed = pressedButton === info.button; + if ( pressed && ! info.showing ) { + + addClass( info.button, 'show' ); + info.pane.style.display = 'flex'; + info.showing = true; + + } else { + + removeClass( info.button, 'show' ); + info.pane.style.display = 'none'; + info.showing = false; + + } + + } ); + showOtherIfAllPanesOff(); + resize(); + + } + + function showingResultPane() { + + return g.result.style.display !== 'none'; + + } + + function toggleResultPane() { + + const showing = showingResultPane(); + g.result.style.display = showing ? 'none' : 'block'; + addRemoveClass( g.resultButton, 'show', ! showing ); + showOtherIfAllPanesOff(); + resize(); + + } + + function showOtherIfAllPanesOff() { + + let paneOn = showingResultPane(); + forEachHTMLPart( function ( info ) { + + paneOn = paneOn || info.showing; + + } ); + g.other.style.display = paneOn ? 'none' : 'block'; + + } + + // seems like we should probably store a map + function getEditorNdxByBlobUrl( type, url ) { + + return htmlParts[ type ].sources.findIndex( source => source.scriptInfo.blobUrl === url ); + + } + + function getActualLineNumberAndMoveTo( url, lineNo, colNo ) { + + let origUrl = url; + let actualLineNo = lineNo; + const scriptInfo = Object.values( g.scriptInfos ).find( scriptInfo => scriptInfo.blobUrl === url ); + if ( scriptInfo ) { + + actualLineNo = lineNo - scriptInfo.numLinesBeforeScript; + origUrl = basename( scriptInfo.fqURL ); + if ( ! g.setPosition ) { + + // Only set the first position + g.setPosition = true; + const editorNdx = getEditorNdxByBlobUrl( 'js', url ); + if ( editorNdx >= 0 ) { + + showEditorSubPane( 'js', editorNdx ); + const editor = htmlParts.js.editors[ editorNdx ].editor; + editor.setPosition( { + lineNumber: actualLineNo, + column: colNo, + } ); + editor.revealLineInCenterIfOutsideViewport( actualLineNo ); + editor.focus(); + + } + + } + + } + + return { origUrl, actualLineNo }; + + } + + window.getActualLineNumberAndMoveTo = getActualLineNumberAndMoveTo; + + function runEditor( parent, source, language ) { + + return monaco.editor.create( parent, { + value: source, + language: language, + //lineNumbers: false, + theme: 'vs-dark', + disableTranslate3d: true, + // model: null, + scrollBeyondLastLine: false, + minimap: { enabled: false }, + } ); + + } + + async function runAsBlob() { + + const query = getQuery(); + g.url = getFQUrl( query.url ); + g.query = getSearch( g.url ); + let html; + try { + + html = await getHTML( query.url ); + + } catch ( err ) { -async function runAsBlob() { - const query = getQuery(); - g.url = getFQUrl(query.url); - g.query = getSearch(g.url); - let html; - try { - html = await getHTML(query.url); - } catch (err) { console.log(err); // eslint-disable-line - return; - } - await parseHTML(query.url, html); - window.location.href = getSourceBlobFromOrig(); -} + return; -function applySubstitutions() { - [...document.querySelectorAll('[data-subst]')].forEach((elem) => { - elem.dataset.subst.split('&').forEach((pair) => { - const [attr, key] = pair.split('|'); - elem[attr] = lessonEditorSettings[key]; - }); - }); -} + } -function start() { - const parentQuery = getQuery(window.parent.location.search); - const isSmallish = window.navigator.userAgent.match(/Android|iPhone|iPod|Windows Phone/i); - const isEdge = window.navigator.userAgent.match(/Edge/i); - if (isEdge || isSmallish || parentQuery.editor === 'false') { - runAsBlob(); - // var url = query.url; - // window.location.href = url; - } else { - applySubstitutions(); - require.config({ paths: { 'vs': '/manual/3rdparty/monaco-editor/min/vs' }}); - require(['vs/editor/editor.main'], main); - } -} + await parseHTML( query.url, html ); + window.location.href = getSourceBlobFromOrig(); -start(); -}()); + } + + function applySubstitutions() { + + [ ...document.querySelectorAll( '[data-subst]' ) ].forEach( ( elem ) => { + + elem.dataset.subst.split( '&' ).forEach( ( pair ) => { + + const [ attr, key ] = pair.split( '|' ); + elem[ attr ] = lessonEditorSettings[ key ]; + + } ); + + } ); + + } + + function start() { + + const parentQuery = getQuery( window.parent.location.search ); + const isSmallish = window.navigator.userAgent.match( /Android|iPhone|iPod|Windows Phone/i ); + const isEdge = window.navigator.userAgent.match( /Edge/i ); + if ( isEdge || isSmallish || parentQuery.editor === 'false' ) { + + runAsBlob(); + // var url = query.url; + // window.location.href = url; + + } else { + + applySubstitutions(); + require.config( { paths: { 'vs': '/manual/3rdparty/monaco-editor/min/vs' } } ); + require( [ 'vs/editor/editor.main' ], main ); + + } + + } + + start(); + +}() ); diff --git a/manual/examples/resources/lessons-helper.js b/manual/examples/resources/lessons-helper.js index caf0e3f2944512..b49078531aea73 100644 --- a/manual/examples/resources/lessons-helper.js +++ b/manual/examples/resources/lessons-helper.js @@ -32,51 +32,72 @@ /* global define */ (function(root, factory) { // eslint-disable-line - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define([], function() { - return factory.call(root); - }); - } else { - // Browser globals - root.lessonsHelper = factory.call(root); - } -}(this, function() { + if ( typeof define === 'function' && define.amd ) { + + // AMD. Register as an anonymous module. + define( [], function () { + + return factory.call( root ); + + } ); + + } else { + + // Browser globals + root.lessonsHelper = factory.call( root ); + + } + +}( this, function () { + 'use strict'; // eslint-disable-line - const lessonSettings = window.lessonSettings || {}; - const topWindow = this; + const lessonSettings = window.lessonSettings || {}; + const topWindow = this; - /** + /** * Check if the page is embedded. * @param {Window?) w window to check * @return {boolean} True of we are in an iframe */ - function isInIFrame(w) { - w = w || topWindow; - return w !== w.top; - } - - function updateCSSIfInIFrame() { - if (isInIFrame()) { - try { - document.getElementsByTagName('html')[0].className = 'iframe'; - } catch (e) { + function isInIFrame( w ) { + + w = w || topWindow; + return w !== w.top; + + } + + function updateCSSIfInIFrame() { + + if ( isInIFrame() ) { + + try { + + document.getElementsByTagName( 'html' )[ 0 ].className = 'iframe'; + + } catch ( e ) { // eslint-disable-line - } - try { - document.body.className = 'iframe'; - } catch (e) { + } + + try { + + document.body.className = 'iframe'; + + } catch ( e ) { // eslint-disable-line - } - } - } + } + + } + + } + + function isInEditor() { - function isInEditor() { - return window.location.href.substring(0, 4) === 'blob'; - } + return window.location.href.substring( 0, 4 ) === 'blob'; - /** + } + + /** * Creates a webgl context. If creation fails it will * change the contents of the container of the * tag to an error message with the correct links for WebGL. @@ -87,11 +108,13 @@ * @return {WebGLRenderingContext} The created context. * @memberOf module:webgl-utils */ - function showNeedWebGL(canvas) { - const doc = canvas.ownerDocument; - if (doc) { - const temp = doc.createElement('div'); - temp.innerHTML = ` + function showNeedWebGL( canvas ) { + + const doc = canvas.ownerDocument; + if ( doc ) { + + const temp = doc.createElement( 'div' ); + temp.innerHTML = `
            0) { - rafRequestId = oldRAF(rAFHandler); - } - } - - function stopRAF() { - if (rafRequestId) { - oldCancelRAF(rafRequestId); - rafRequestId = undefined; - } - } - - function initIntersectionObserver() { - const intersectionObserver = new IntersectionObserver((entries) => { - entries.forEach(entry => { - isBodyOnScreen = entry.isIntersecting; - }); - if (isBodyOnScreen) { - startRAFIfIntersectingAndNeeded(); - } else { - stopRAF(); - } - }); - intersectionObserver.observe(document.body); - } - - function betterRAF(callback) { - const fakeRAFId = nextFakeRAFId++; - fakeRAFIdToCallbackMap.set(fakeRAFId, callback); - startRAFIfIntersectingAndNeeded(); - return fakeRAFId; - } - - function betterCancelRAF(id) { - fakeRAFIdToCallbackMap.delete(id); - } - - topWindow.cancelAnimationFrame = betterCancelRAF; - - return function(callback) { - // we need to lazy init this because this code gets parsed - // before body exists. We could fix it by moving lesson-helper.js - // after but that would require changing 100s of examples - initIntersectionObserver(); - topWindow.requestAnimationFrame = betterRAF; - return betterRAF(callback); - }; - - }(topWindow.requestAnimationFrame, topWindow.cancelAnimationFrame)); - } - - updateCSSIfInIFrame(); - - function captureJSErrors() { - // capture JavaScript Errors - window.addEventListener('error', function(e) { - const msg = e.message || e.error; - const url = e.filename; - const lineNo = e.lineno || 1; - const colNo = e.colno || 1; - reportJSError(url, lineNo, colNo, msg); - origConsole.error(e.error); - }); - } - - // adapted from http://stackoverflow.com/a/2401861/128511 - function getBrowser() { - const userAgent = navigator.userAgent; - let m = userAgent.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; - if (/trident/i.test(m[1])) { - m = /\brv[ :]+(\d+)/g.exec(userAgent) || []; - return { - name: 'IE', - version: m[1], - }; - } - if (m[1] === 'Chrome') { - const temp = userAgent.match(/\b(OPR|Edge)\/(\d+)/); - if (temp) { - return { - name: temp[1].replace('OPR', 'Opera'), - version: temp[2], - }; - } - } - m = m[2] ? [m[1], m[2]] : [navigator.appName, navigator.appVersion, '-?']; - const version = userAgent.match(/version\/(\d+)/i); - if (version) { - m.splice(1, 1, version[1]); - } - return { - name: m[0], - version: m[1], - }; - } - - const canvasesToTimeoutMap = new Map(); - const isWebGLRE = /^(webgl|webgl2|experimental-webgl)$/i; - const isWebGL2RE = /^webgl2$/i; - function installWebGLLessonSetup() { - HTMLCanvasElement.prototype.getContext = (function(oldFn) { - return function() { - const timeoutId = canvasesToTimeoutMap.get(this); - if (timeoutId) { - clearTimeout(timeoutId); - } - const type = arguments[0]; - const isWebGL1or2 = isWebGLRE.test(type); - const isWebGL2 = isWebGL2RE.test(type); - if (isWebGL1or2) { - setupLesson(this); - } - const args = [].slice.apply(arguments); - args[1] = { - powerPreference: 'low-power', - ...args[1], - }; - const ctx = oldFn.apply(this, args); - if (!ctx) { - if (isWebGL2) { - // three tries webgl2 then webgl1 - // so wait 1/2 a second before showing the failure - // message. If we get success on the same canvas - // we'll cancel this. - canvasesToTimeoutMap.set(this, setTimeout(() => { - canvasesToTimeoutMap.delete(this); - showNeedWebGL(this); - }, 500)); - } else { - showNeedWebGL(this); - } - } - return ctx; - }; - }(HTMLCanvasElement.prototype.getContext)); - } - - function installWebGLDebugContextCreator() { - if (!self.webglDebugHelper) { - return; - } + } + + if ( isInIFrame() ) { + + updateCSSIfInIFrame(); + + } + + }; + + // Replace requestAnimationFrame and cancelAnimationFrame with one + // that only executes when the body is visible (we're in an iframe). + // It's frustrating that th browsers don't do this automatically. + // It's half of the point of rAF that it shouldn't execute when + // content is not visible but browsers execute rAF in iframes even + // if they are not visible. + if ( topWindow.requestAnimationFrame ) { + + topWindow.requestAnimationFrame = ( function ( oldRAF, oldCancelRAF ) { + + let nextFakeRAFId = 1; + const fakeRAFIdToCallbackMap = new Map(); + let rafRequestId; + let isBodyOnScreen; + + function rAFHandler( time ) { + + rafRequestId = undefined; + const ids = [ ...fakeRAFIdToCallbackMap.keys() ]; // WTF! Map.keys() iterates over live keys! + for ( const id of ids ) { + + const callback = fakeRAFIdToCallbackMap.get( id ); + fakeRAFIdToCallbackMap.delete( id ); + if ( callback ) { + + callback( time ); + + } + + } + + } + + function startRAFIfIntersectingAndNeeded() { + + if ( ! rafRequestId && isBodyOnScreen && fakeRAFIdToCallbackMap.size > 0 ) { + + rafRequestId = oldRAF( rAFHandler ); + + } + + } + + function stopRAF() { + + if ( rafRequestId ) { + + oldCancelRAF( rafRequestId ); + rafRequestId = undefined; + + } + + } + + function initIntersectionObserver() { + + const intersectionObserver = new IntersectionObserver( ( entries ) => { + + entries.forEach( entry => { + + isBodyOnScreen = entry.isIntersecting; + + } ); + if ( isBodyOnScreen ) { + + startRAFIfIntersectingAndNeeded(); + + } else { + + stopRAF(); + + } + + } ); + intersectionObserver.observe( document.body ); + + } + + function betterRAF( callback ) { + + const fakeRAFId = nextFakeRAFId ++; + fakeRAFIdToCallbackMap.set( fakeRAFId, callback ); + startRAFIfIntersectingAndNeeded(); + return fakeRAFId; + + } + + function betterCancelRAF( id ) { + + fakeRAFIdToCallbackMap.delete( id ); + + } + + topWindow.cancelAnimationFrame = betterCancelRAF; + + return function ( callback ) { + + // we need to lazy init this because this code gets parsed + // before body exists. We could fix it by moving lesson-helper.js + // after but that would require changing 100s of examples + initIntersectionObserver(); + topWindow.requestAnimationFrame = betterRAF; + return betterRAF( callback ); + + }; + + }( topWindow.requestAnimationFrame, topWindow.cancelAnimationFrame ) ); + + } + + updateCSSIfInIFrame(); + + function captureJSErrors() { + + // capture JavaScript Errors + window.addEventListener( 'error', function ( e ) { + + const msg = e.message || e.error; + const url = e.filename; + const lineNo = e.lineno || 1; + const colNo = e.colno || 1; + reportJSError( url, lineNo, colNo, msg ); + origConsole.error( e.error ); + + } ); + + } + + // adapted from http://stackoverflow.com/a/2401861/128511 + function getBrowser() { + + const userAgent = navigator.userAgent; + let m = userAgent.match( /(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i ) || []; + if ( /trident/i.test( m[ 1 ] ) ) { + + m = /\brv[ :]+(\d+)/g.exec( userAgent ) || []; + return { + name: 'IE', + version: m[ 1 ], + }; + + } + + if ( m[ 1 ] === 'Chrome' ) { + + const temp = userAgent.match( /\b(OPR|Edge)\/(\d+)/ ); + if ( temp ) { + + return { + name: temp[ 1 ].replace( 'OPR', 'Opera' ), + version: temp[ 2 ], + }; + + } + + } + + m = m[ 2 ] ? [ m[ 1 ], m[ 2 ] ] : [ navigator.appName, navigator.appVersion, '-?' ]; + const version = userAgent.match( /version\/(\d+)/i ); + if ( version ) { + + m.splice( 1, 1, version[ 1 ] ); + + } + + return { + name: m[ 0 ], + version: m[ 1 ], + }; + + } + + const canvasesToTimeoutMap = new Map(); + const isWebGLRE = /^(webgl|webgl2|experimental-webgl)$/i; + const isWebGL2RE = /^webgl2$/i; + function installWebGLLessonSetup() { + + HTMLCanvasElement.prototype.getContext = ( function ( oldFn ) { + + return function () { + + const timeoutId = canvasesToTimeoutMap.get( this ); + if ( timeoutId ) { + + clearTimeout( timeoutId ); + + } + + const type = arguments[ 0 ]; + const isWebGL1or2 = isWebGLRE.test( type ); + const isWebGL2 = isWebGL2RE.test( type ); + if ( isWebGL1or2 ) { + + setupLesson( this ); + + } + + const args = [].slice.apply( arguments ); + args[ 1 ] = { + powerPreference: 'low-power', + ...args[ 1 ], + }; + const ctx = oldFn.apply( this, args ); + if ( ! ctx ) { + + if ( isWebGL2 ) { + + // three tries webgl2 then webgl1 + // so wait 1/2 a second before showing the failure + // message. If we get success on the same canvas + // we'll cancel this. + canvasesToTimeoutMap.set( this, setTimeout( () => { + + canvasesToTimeoutMap.delete( this ); + showNeedWebGL( this ); + + }, 500 ) ); + + } else { + + showNeedWebGL( this ); + + } + + } + + return ctx; + + }; + + }( HTMLCanvasElement.prototype.getContext ) ); + + } + + function installWebGLDebugContextCreator() { + + if ( ! self.webglDebugHelper ) { + + return; + + } + + const { + makeDebugContext, + glFunctionArgToString, + glEnumToString, + } = self.webglDebugHelper; + + // capture GL errors + HTMLCanvasElement.prototype.getContext = ( function ( oldFn ) { + + return function () { + + let ctx = oldFn.apply( this, arguments ); + // Using bindTexture to see if it's WebGL. Could check for instanceof WebGLRenderingContext + // but that might fail if wrapped by debugging extension + if ( ctx && ctx.bindTexture ) { + + ctx = makeDebugContext( ctx, { + maxDrawCalls: 100, + errorFunc: function ( err, funcName, args ) { + + const numArgs = args.length; + const enumedArgs = [].map.call( args, function ( arg, ndx ) { + + let str = glFunctionArgToString( funcName, numArgs, ndx, arg ); + // shorten because of long arrays + if ( str.length > 200 ) { + + str = str.substring( 0, 200 ) + '...'; + + } + + return str; + + } ); + const errorMsg = `WebGL error ${glEnumToString( err )} in ${funcName}(${enumedArgs.join( ', ' )})`; + const errorInfo = parseStack( ( new Error() ).stack ); + if ( errorInfo ) { + + reportJSError( errorInfo.url, errorInfo.lineNo, errorInfo.colNo, errorMsg ); + + } else { - const { - makeDebugContext, - glFunctionArgToString, - glEnumToString, - } = self.webglDebugHelper; - - // capture GL errors - HTMLCanvasElement.prototype.getContext = (function(oldFn) { - return function() { - let ctx = oldFn.apply(this, arguments); - // Using bindTexture to see if it's WebGL. Could check for instanceof WebGLRenderingContext - // but that might fail if wrapped by debugging extension - if (ctx && ctx.bindTexture) { - ctx = makeDebugContext(ctx, { - maxDrawCalls: 100, - errorFunc: function(err, funcName, args) { - const numArgs = args.length; - const enumedArgs = [].map.call(args, function(arg, ndx) { - let str = glFunctionArgToString(funcName, numArgs, ndx, arg); - // shorten because of long arrays - if (str.length > 200) { - str = str.substring(0, 200) + '...'; - } - return str; - }); - const errorMsg = `WebGL error ${glEnumToString(err)} in ${funcName}(${enumedArgs.join(', ')})`; - const errorInfo = parseStack((new Error()).stack); - if (errorInfo) { - reportJSError(errorInfo.url, errorInfo.lineNo, errorInfo.colNo, errorMsg); - } else { console.error(errorMsg) // eslint-disable-line - } - }, - }); - } - return ctx; - }; - }(HTMLCanvasElement.prototype.getContext)); - } - - installWebGLLessonSetup(); - - if (isInEditor()) { - setupWorkerSupport(); - setupConsole(); - captureJSErrors(); - if (lessonSettings.glDebug !== false) { - installWebGLDebugContextCreator(); - } - } + } + + }, + } ); + + } + + return ctx; + + }; + + }( HTMLCanvasElement.prototype.getContext ) ); + + } + + installWebGLLessonSetup(); + + if ( isInEditor() ) { + + setupWorkerSupport(); + setupConsole(); + captureJSErrors(); + if ( lessonSettings.glDebug !== false ) { + + installWebGLDebugContextCreator(); + + } + + } - return { - setupLesson: setupLesson, - showNeedWebGL: showNeedWebGL, - }; + return { + setupLesson: setupLesson, + showNeedWebGL: showNeedWebGL, + }; -})); +} ) ); diff --git a/manual/examples/resources/lessons-worker-helper.js b/manual/examples/resources/lessons-worker-helper.js index 82dd40e731c2b5..15ea1dc2b894ae 100644 --- a/manual/examples/resources/lessons-worker-helper.js +++ b/manual/examples/resources/lessons-worker-helper.js @@ -33,157 +33,210 @@ 'use strict'; // eslint-disable-line -(function() { - - const lessonSettings = self.lessonSettings || {}; - - function isInEditor() { - return self.location.href.substring(0, 4) === 'blob'; - } - - function sendMessage(data) { - self.postMessage({ - type: '__editor__', - data, - }); - } - - const origConsole = {}; - - function setupConsole() { - function wrapFunc(obj, logType) { - const origFunc = obj[logType].bind(obj); - origConsole[logType] = origFunc; - return function(...args) { - origFunc(...args); - sendMessage({ - type: 'log', - logType, - msg: [...args].join(' '), - }); - }; - } - self.console.log = wrapFunc(self.console, 'log'); - self.console.warn = wrapFunc(self.console, 'warn'); - self.console.error = wrapFunc(self.console, 'error'); - } - - /** +( function () { + + const lessonSettings = self.lessonSettings || {}; + + function isInEditor() { + + return self.location.href.substring( 0, 4 ) === 'blob'; + + } + + function sendMessage( data ) { + + self.postMessage( { + type: '__editor__', + data, + } ); + + } + + const origConsole = {}; + + function setupConsole() { + + function wrapFunc( obj, logType ) { + + const origFunc = obj[ logType ].bind( obj ); + origConsole[ logType ] = origFunc; + return function ( ...args ) { + + origFunc( ...args ); + sendMessage( { + type: 'log', + logType, + msg: [ ...args ].join( ' ' ), + } ); + + }; + + } + + self.console.log = wrapFunc( self.console, 'log' ); + self.console.warn = wrapFunc( self.console, 'warn' ); + self.console.error = wrapFunc( self.console, 'error' ); + + } + + /** * Gets a WebGL context. * makes its backing store the size it is displayed. * @param {OffscreenCanvas} canvas a canvas element. * @memberOf module:webgl-utils */ - let setupLesson = function(canvas) { - // only once - setupLesson = function() {}; - - if (canvas) { - canvas.addEventListener('webglcontextlost', function() { - // the default is to do nothing. Preventing the default - // means allowing context to be restored - // e.preventDefault(); // can't do this because firefox bug - https://bugzilla.mozilla.org/show_bug.cgi?id=1633280 - sendMessage({ - type: 'lostContext', - }); - }); - } - - }; - - function captureJSErrors() { - // capture JavaScript Errors - self.addEventListener('error', function(e) { - const msg = e.message || e.error; - const url = e.filename; - const lineNo = e.lineno || 1; - const colNo = e.colno || 1; - sendMessage({ - type: 'jsError', - lineNo, - colNo, - url, - msg, - }); - }); - } - - - const isWebGLRE = /^(webgl|webgl2|experimental-webgl)$/i; - function installWebGLLessonSetup() { - OffscreenCanvas.prototype.getContext = (function(oldFn) { - return function() { - const type = arguments[0]; - const isWebGL = isWebGLRE.test(type); - if (isWebGL) { - setupLesson(this); - } - const args = [].slice.apply(arguments); - args[1] = { - powerPreference: 'low-power', - ...args[1], - }; - return oldFn.apply(this, args); - }; - }(OffscreenCanvas.prototype.getContext)); - } - - function installWebGLDebugContextCreator() { - if (!self.webglDebugHelper) { - return; - } - - const { - makeDebugContext, - glFunctionArgToString, - glEnumToString, - } = self.webglDebugHelper; - - // capture GL errors - OffscreenCanvas.prototype.getContext = (function(oldFn) { - return function() { - let ctx = oldFn.apply(this, arguments); - // Using bindTexture to see if it's WebGL. Could check for instanceof WebGLRenderingContext - // but that might fail if wrapped by debugging extension - if (ctx && ctx.bindTexture) { - ctx = makeDebugContext(ctx, { - maxDrawCalls: 100, - errorFunc: function(err, funcName, args) { - const numArgs = args.length; - const enumedArgs = [].map.call(args, function(arg, ndx) { - let str = glFunctionArgToString(funcName, numArgs, ndx, arg); - // shorten because of long arrays - if (str.length > 200) { - str = str.substring(0, 200) + '...'; - } - return str; - }); - - { - const error = new Error(); - sendMessage({ - type: 'jsErrorWithStack', - stack: error.stack, - msg: `${glEnumToString(err)} in ${funcName}(${enumedArgs.join(', ')})`, - }); - } - }, - }); - } - return ctx; - }; - }(OffscreenCanvas.prototype.getContext)); - } - - installWebGLLessonSetup(); - - if (isInEditor()) { - setupConsole(); - captureJSErrors(); - if (lessonSettings.glDebug !== false) { - installWebGLDebugContextCreator(); - } - } - -}()); + let setupLesson = function ( canvas ) { + + // only once + setupLesson = function () {}; + + if ( canvas ) { + + canvas.addEventListener( 'webglcontextlost', function () { + + // the default is to do nothing. Preventing the default + // means allowing context to be restored + // e.preventDefault(); // can't do this because firefox bug - https://bugzilla.mozilla.org/show_bug.cgi?id=1633280 + sendMessage( { + type: 'lostContext', + } ); + + } ); + + } + + }; + + function captureJSErrors() { + + // capture JavaScript Errors + self.addEventListener( 'error', function ( e ) { + + const msg = e.message || e.error; + const url = e.filename; + const lineNo = e.lineno || 1; + const colNo = e.colno || 1; + sendMessage( { + type: 'jsError', + lineNo, + colNo, + url, + msg, + } ); + + } ); + + } + + + const isWebGLRE = /^(webgl|webgl2|experimental-webgl)$/i; + function installWebGLLessonSetup() { + + OffscreenCanvas.prototype.getContext = ( function ( oldFn ) { // eslint-disable-line compat/compat + + return function () { + + const type = arguments[ 0 ]; + const isWebGL = isWebGLRE.test( type ); + if ( isWebGL ) { + + setupLesson( this ); + + } + + const args = [].slice.apply( arguments ); + args[ 1 ] = { + powerPreference: 'low-power', + ...args[ 1 ], + }; + return oldFn.apply( this, args ); + + }; + + }( OffscreenCanvas.prototype.getContext ) ); // eslint-disable-line compat/compat + + } + + function installWebGLDebugContextCreator() { + + if ( ! self.webglDebugHelper ) { + + return; + + } + + const { + makeDebugContext, + glFunctionArgToString, + glEnumToString, + } = self.webglDebugHelper; + + // capture GL errors + OffscreenCanvas.prototype.getContext = ( function ( oldFn ) { // eslint-disable-line compat/compat + + return function () { + + let ctx = oldFn.apply( this, arguments ); + // Using bindTexture to see if it's WebGL. Could check for instanceof WebGLRenderingContext + // but that might fail if wrapped by debugging extension + if ( ctx && ctx.bindTexture ) { + + ctx = makeDebugContext( ctx, { + maxDrawCalls: 100, + errorFunc: function ( err, funcName, args ) { + + const numArgs = args.length; + const enumedArgs = [].map.call( args, function ( arg, ndx ) { + + let str = glFunctionArgToString( funcName, numArgs, ndx, arg ); + // shorten because of long arrays + if ( str.length > 200 ) { + + str = str.substring( 0, 200 ) + '...'; + + } + + return str; + + } ); + + { + + const error = new Error(); + sendMessage( { + type: 'jsErrorWithStack', + stack: error.stack, + msg: `${glEnumToString( err )} in ${funcName}(${enumedArgs.join( ', ' )})`, + } ); + + } + + }, + } ); + + } + + return ctx; + + }; + + }( OffscreenCanvas.prototype.getContext ) ); // eslint-disable-line compat/compat + + } + + installWebGLLessonSetup(); + + if ( isInEditor() ) { + + setupConsole(); + captureJSErrors(); + if ( lessonSettings.glDebug !== false ) { + + installWebGLDebugContextCreator(); + + } + + } + +}() ); diff --git a/manual/examples/resources/lut-reader.js b/manual/examples/resources/lut-reader.js index e8a38d17ea086f..225502317ad264 100644 --- a/manual/examples/resources/lut-reader.js +++ b/manual/examples/resources/lut-reader.js @@ -1,244 +1,351 @@ -function splitOnSpaceHandleQuotesWithEscapes(str, splits = ' \t\n\r') { - const strings = []; - let quoteType; - let escape; - let s = []; - for (let i = 0; i < str.length; ++i) { - const c = str[i]; - if (escape) { - escape = false; - s.push(c); - } else { - if (quoteType) { // we're inside quotes - if (c === quoteType) { - quoteType = undefined; - strings.push(s.join('')); - s = []; - } else if (c === '\\') { - escape = true; - } else { - s.push(c); - } - } else { // we're not in quotes - if (splits.indexOf(c) >= 0) { - if (s.length) { - strings.push(s.join('')); - s = []; - } - } else if (c === '"' || c === '\'') { - if (s.length) { // its in th middle of a word - s.push(c); - } else { - quoteType = c; - } - } else { - s.push(c); - } - } - } - } - if (s.length || strings.length === 0) { - strings.push(s.join('')); - } - return strings; +function splitOnSpaceHandleQuotesWithEscapes( str, splits = ' \t\n\r' ) { + + const strings = []; + let quoteType; + let escape; + let s = []; + for ( let i = 0; i < str.length; ++ i ) { + + const c = str[ i ]; + if ( escape ) { + + escape = false; + s.push( c ); + + } else { + + if ( quoteType ) { // we're inside quotes + + if ( c === quoteType ) { + + quoteType = undefined; + strings.push( s.join( '' ) ); + s = []; + + } else if ( c === '\\' ) { + + escape = true; + + } else { + + s.push( c ); + + } + + } else { // we're not in quotes + + if ( splits.indexOf( c ) >= 0 ) { + + if ( s.length ) { + + strings.push( s.join( '' ) ); + s = []; + + } + + } else if ( c === '"' || c === '\'' ) { + + if ( s.length ) { // its in th middle of a word + + s.push( c ); + + } else { + + quoteType = c; + + } + + } else { + + s.push( c ); + + } + + } + + } + + } + + if ( s.length || strings.length === 0 ) { + + strings.push( s.join( '' ) ); + + } + + return strings; + } const startWhitespaceRE = /^\s/; const intRE = /^\d+$/; -const isNum = s => intRE.test(s); +const isNum = s => intRE.test( s ); const quotesRE = /^".*"$/; -function trimQuotes(s) { - return quotesRE.test(s) ? s.slice(1, -1) : s; +function trimQuotes( s ) { + + return quotesRE.test( s ) ? s.slice( 1, - 1 ) : s; + } -const splitToNumbers = s => s.split(' ').map(parseFloat); - -export function parseCSP(str) { - const data = []; - const lut = { - name: 'unknown', - type: '1D', - size: 0, - data, - min: [0, 0, 0], - max: [1, 1, 1], - }; - - const lines = str.split('\n').map(s => s.trim()).filter(s => s.length > 0 && !startWhitespaceRE.test(s)); - - // check header - lut.type = lines[1]; - if (lines[0] !== 'CSPLUTV100' || - (lut.type !== '1D' && lut.type !== '3D')) { - throw new Error('not CSP'); - } - - // skip meta (read to first number) - let lineNdx = 2; - for (; lineNdx < lines.length; ++lineNdx) { - const line = lines[lineNdx]; - if (isNum(line)) { - break; - } - if (line.startsWith('TITLE ')) { - lut.name = trimQuotes(line.slice(6).trim()); - } - } - - // read ranges - for (let i = 0; i < 3; ++i) { - ++lineNdx; - const input = splitToNumbers(lines[lineNdx++]); - const output = splitToNumbers(lines[lineNdx++]); - if (input.length !== 2 || output.length !== 2 || - input[0] !== 0 || input[1] !== 1 || - output[0] !== 0 || output[1] !== 1) { - throw new Error('mapped ranges not support'); - } - } - - // read sizes - const sizes = splitToNumbers(lines[lineNdx++]); - if (sizes[0] !== sizes[1] || sizes[0] !== sizes[2]) { - throw new Error('only cubic sizes supported'); - } - lut.size = sizes[0]; - - // read data - for (; lineNdx < lines.length; ++lineNdx) { - const parts = splitToNumbers(lines[lineNdx]); - if (parts.length !== 3) { - throw new Error('malformed file'); - } - data.push(...parts); - } - - return lut; +const splitToNumbers = s => s.split( ' ' ).map( parseFloat ); + +export function parseCSP( str ) { + + const data = []; + const lut = { + name: 'unknown', + type: '1D', + size: 0, + data, + min: [ 0, 0, 0 ], + max: [ 1, 1, 1 ], + }; + + const lines = str.split( '\n' ).map( s => s.trim() ).filter( s => s.length > 0 && ! startWhitespaceRE.test( s ) ); + + // check header + lut.type = lines[ 1 ]; + if ( lines[ 0 ] !== 'CSPLUTV100' || + ( lut.type !== '1D' && lut.type !== '3D' ) ) { + + throw new Error( 'not CSP' ); + + } + + // skip meta (read to first number) + let lineNdx = 2; + for ( ; lineNdx < lines.length; ++ lineNdx ) { + + const line = lines[ lineNdx ]; + if ( isNum( line ) ) { + + break; + + } + + if ( line.startsWith( 'TITLE ' ) ) { + + lut.name = trimQuotes( line.slice( 6 ).trim() ); + + } + + } + + // read ranges + for ( let i = 0; i < 3; ++ i ) { + + ++ lineNdx; + const input = splitToNumbers( lines[ lineNdx ++ ] ); + const output = splitToNumbers( lines[ lineNdx ++ ] ); + if ( input.length !== 2 || output.length !== 2 || + input[ 0 ] !== 0 || input[ 1 ] !== 1 || + output[ 0 ] !== 0 || output[ 1 ] !== 1 ) { + + throw new Error( 'mapped ranges not support' ); + + } + + } + + // read sizes + const sizes = splitToNumbers( lines[ lineNdx ++ ] ); + if ( sizes[ 0 ] !== sizes[ 1 ] || sizes[ 0 ] !== sizes[ 2 ] ) { + + throw new Error( 'only cubic sizes supported' ); + + } + + lut.size = sizes[ 0 ]; + + // read data + for ( ; lineNdx < lines.length; ++ lineNdx ) { + + const parts = splitToNumbers( lines[ lineNdx ] ); + if ( parts.length !== 3 ) { + + throw new Error( 'malformed file' ); + + } + + data.push( ...parts ); + + } + + return lut; + } -export function parseCUBE(str) { - const data = []; - const lut = { - name: 'unknown', - type: '1D', - size: 0, - data, - min: [0, 0, 0], - max: [1, 1, 1], - }; - - const lines = str.split('\n'); - for (const origLine of lines) { - const hashNdx = origLine.indexOf('#'); - const line = hashNdx >= 0 ? origLine.substring(0, hashNdx) : origLine; - const parts = splitOnSpaceHandleQuotesWithEscapes(line); - switch (parts[0].toUpperCase()) { - case 'TITLE': - lut.name = parts[1]; - break; - case 'LUT_1D_SIZE': - lut.size = parseInt(parts[1]); - lut.type = '1D'; - break; - case 'LUT_3D_SIZE': - lut.size = parseInt(parts[1]); - lut.type = '3D'; - break; - case 'DOMAIN_MIN': - lut.min = parts.slice(1).map(parseFloat); - break; - case 'DOMAIN_MAX': - lut.max = parts.slice(1).map(parseFloat); - break; - default: - if (parts.length === 3) { - data.push(...parts.map(parseFloat)); - } - break; - } - } - - if (!lut.size) { - lut.size = lut.type === '1D' - ? (data.length / 3) - : Math.cbrt(data.length / 3); - } - - return lut; +export function parseCUBE( str ) { + + const data = []; + const lut = { + name: 'unknown', + type: '1D', + size: 0, + data, + min: [ 0, 0, 0 ], + max: [ 1, 1, 1 ], + }; + + const lines = str.split( '\n' ); + for ( const origLine of lines ) { + + const hashNdx = origLine.indexOf( '#' ); + const line = hashNdx >= 0 ? origLine.substring( 0, hashNdx ) : origLine; + const parts = splitOnSpaceHandleQuotesWithEscapes( line ); + switch ( parts[ 0 ].toUpperCase() ) { + + case 'TITLE': + lut.name = parts[ 1 ]; + break; + case 'LUT_1D_SIZE': + lut.size = parseInt( parts[ 1 ] ); + lut.type = '1D'; + break; + case 'LUT_3D_SIZE': + lut.size = parseInt( parts[ 1 ] ); + lut.type = '3D'; + break; + case 'DOMAIN_MIN': + lut.min = parts.slice( 1 ).map( parseFloat ); + break; + case 'DOMAIN_MAX': + lut.max = parts.slice( 1 ).map( parseFloat ); + break; + default: + if ( parts.length === 3 ) { + + data.push( ...parts.map( parseFloat ) ); + + } + + break; + + } + + } + + if ( ! lut.size ) { + + lut.size = lut.type === '1D' + ? ( data.length / 3 ) + : Math.cbrt( data.length / 3 ); + + } + + return lut; + } -function lerp(a, b, t) { - return a + (b - a) * t; +function lerp( a, b, t ) { + + return a + ( b - a ) * t; + } -function lut1Dto3D(lut) { - let src = lut.data; - if (src.length / 3 !== lut.size) { - src = []; - for (let i = 0; i < lut.size; ++i) { - const u = i / lut.size * lut.data.length; - const i0 = (u | 0) * 3; - const i1 = i0 + 3; - const t = u % 1; - src.push( - lerp(lut.data[i0 + 0], lut.data[i1 + 0], t), - lerp(lut.data[i0 + 0], lut.data[i1 + 1], t), - lerp(lut.data[i0 + 0], lut.data[i1 + 2], t), - ); - } - } - const data = []; - for (let i = 0; i < lut.size * lut.size; ++i) { - data.push(...src); - } - return {...lut, data}; +function lut1Dto3D( lut ) { + + let src = lut.data; + if ( src.length / 3 !== lut.size ) { + + src = []; + for ( let i = 0; i < lut.size; ++ i ) { + + const u = i / lut.size * lut.data.length; + const i0 = ( u | 0 ) * 3; + const i1 = i0 + 3; + const t = u % 1; + src.push( + lerp( lut.data[ i0 + 0 ], lut.data[ i1 + 0 ], t ), + lerp( lut.data[ i0 + 0 ], lut.data[ i1 + 1 ], t ), + lerp( lut.data[ i0 + 0 ], lut.data[ i1 + 2 ], t ), + ); + + } + + } + + const data = []; + for ( let i = 0; i < lut.size * lut.size; ++ i ) { + + data.push( ...src ); + + } + + return { ...lut, data }; + } const parsers = { - 'cube': parseCUBE, - 'csp': parseCSP, + 'cube': parseCUBE, + 'csp': parseCSP, }; // for backward compatibility -export function parse(str, format = 'cube') { - const parser = parsers[format.toLowerCase()]; - if (!parser) { - throw new Error(`no parser for format: ${format}`); - } - return parser(str); +export function parse( str, format = 'cube' ) { + + const parser = parsers[ format.toLowerCase() ]; + if ( ! parser ) { + + throw new Error( `no parser for format: ${format}` ); + + } + + return parser( str ); + } -export function lutTo2D3Drgba8(lut) { - if (lut.type === '1D') { - lut = lut1Dto3D(lut); - } - const {min, max, size} = lut; - const range = min.map((min, ndx) => { - return max[ndx] - min; - }); - const src = lut.data; - const data = new Uint8Array(size*size*size * 4); - const srcOffset = (offX, offY, offZ) => { - return (offX + offY * size + offZ * size * size) * 3; - }; - const dOffset = (offX, offY, offZ) => { - return (offX + offY * size + offZ * size * size) * 4; - }; - for (let dz = 0; dz < size; ++dz) { - for (let dy = 0; dy < size; ++dy) { - for (let dx = 0; dx < size; ++dx) { - const sx = dx; - const sy = dz; - const sz = dy; - const sOff = srcOffset(sx, sy, sz); - const dOff = dOffset(dx, dy, dz); - data[dOff + 0] = (src[sOff + 0] - min[0]) / range[0] * 255; - data[dOff + 1] = (src[sOff + 1] - min[1]) / range[1] * 255; - data[dOff + 2] = (src[sOff + 2] - min[2]) / range[2] * 255; - data[dOff + 3] = 255; - } - } - } - return {...lut, data}; +export function lutTo2D3Drgba8( lut ) { + + if ( lut.type === '1D' ) { + + lut = lut1Dto3D( lut ); + + } + + const { min, max, size } = lut; + const range = min.map( ( min, ndx ) => { + + return max[ ndx ] - min; + + } ); + const src = lut.data; + const data = new Uint8Array( size * size * size * 4 ); + const srcOffset = ( offX, offY, offZ ) => { + + return ( offX + offY * size + offZ * size * size ) * 3; + + }; + + const dOffset = ( offX, offY, offZ ) => { + + return ( offX + offY * size + offZ * size * size ) * 4; + + }; + + for ( let dz = 0; dz < size; ++ dz ) { + + for ( let dy = 0; dy < size; ++ dy ) { + + for ( let dx = 0; dx < size; ++ dx ) { + + const sx = dx; + const sy = dz; + const sz = dy; + const sOff = srcOffset( sx, sy, sz ); + const dOff = dOffset( dx, dy, dz ); + data[ dOff + 0 ] = ( src[ sOff + 0 ] - min[ 0 ] ) / range[ 0 ] * 255; + data[ dOff + 1 ] = ( src[ sOff + 1 ] - min[ 1 ] ) / range[ 1 ] * 255; + data[ dOff + 2 ] = ( src[ sOff + 2 ] - min[ 2 ] ) / range[ 2 ] * 255; + data[ dOff + 3 ] = 255; + + } + + } + + } + + return { ...lut, data }; + } diff --git a/manual/examples/resources/threejs-utils.js b/manual/examples/resources/threejs-utils.js index bf81ecf77ace9a..d2ade3526bfa85 100644 --- a/manual/examples/resources/threejs-utils.js +++ b/manual/examples/resources/threejs-utils.js @@ -32,21 +32,29 @@ /* global define */ (function(root, factory) { // eslint-disable-line - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define([], function() { - return factory.call(root); - }); - } else { - // Browser globals - root.threejsUtils = factory.call(root); - } -}(this, function() { + if ( typeof define === 'function' && define.amd ) { + + // AMD. Register as an anonymous module. + define( [], function () { + + return factory.call( root ); + + } ); + + } else { + + // Browser globals + root.threejsUtils = factory.call( root ); + + } + +}( this, function () { + 'use strict'; // eslint-disable-line - /** @module threejs-utils */ + /** @module threejs-utils */ - /** + /** * Resize a canvas to match the size its displayed. * @param {HTMLCanvasElement} canvas The canvas to resize. * @param {number} [multiplier] amount to multiply by. @@ -54,21 +62,26 @@ * @return {boolean} true if the canvas was resized. * @memberOf module:webgl-utils */ - function resizeCanvasToDisplaySize(canvas, multiplier) { - multiplier = multiplier || 1; - const width = canvas.clientWidth * multiplier | 0; - const height = canvas.clientHeight * multiplier | 0; - if (canvas.width !== width || canvas.height !== height) { - canvas.width = width; - canvas.height = height; - return true; - } - return false; - } - - return { - resizeCanvasToDisplaySize: resizeCanvasToDisplaySize, - }; - -})); + function resizeCanvasToDisplaySize( canvas, multiplier ) { + + multiplier = multiplier || 1; + const width = canvas.clientWidth * multiplier | 0; + const height = canvas.clientHeight * multiplier | 0; + if ( canvas.width !== width || canvas.height !== height ) { + + canvas.width = width; + canvas.height = height; + return true; + + } + + return false; + + } + + return { + resizeCanvasToDisplaySize: resizeCanvasToDisplaySize, + }; + +} ) ); diff --git a/manual/examples/resources/webgl-debug-helper.js b/manual/examples/resources/webgl-debug-helper.js index 43ed93bcd19fcb..9aa0d7764096bd 100644 --- a/manual/examples/resources/webgl-debug-helper.js +++ b/manual/examples/resources/webgl-debug-helper.js @@ -32,21 +32,29 @@ /* global define, globalThis */ (function(root, factory) { // eslint-disable-line - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define([], function() { - return factory.call(root); - }); - } else { - // Browser globals - root.webglDebugHelper = factory.call(root); - } -}(this || globalThis, function() { + if ( typeof define === 'function' && define.amd ) { + + // AMD. Register as an anonymous module. + define( [], function () { + + return factory.call( root ); + + } ); + + } else { + + // Browser globals + root.webglDebugHelper = factory.call( root ); + + } + +}( this || globalThis, function () { + 'use strict'; // eslint-disable-line - //------------ [ from https://github.com/KhronosGroup/WebGLDeveloperTools ] + //------------ [ from https://github.com/KhronosGroup/WebGLDeveloperTools ] - /* + /* ** Copyright (c) 2012 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a @@ -69,78 +77,104 @@ ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ - /** + /** * Types of contexts we have added to map */ - const mappedContextTypes = {}; + const mappedContextTypes = {}; - /** + /** * Map of numbers to names. * @type {Object} */ - const glEnums = {}; + const glEnums = {}; - /** + /** * Map of names to numbers. * @type {Object} */ - const enumStringToValue = {}; + const enumStringToValue = {}; - /** + /** * Initializes this module. Safe to call more than once. * @param {!WebGLRenderingContext} ctx A WebGL context. If * you have more than one context it doesn't matter which one * you pass in, it is only used to pull out constants. */ - function addEnumsForContext(ctx, type) { - if (!mappedContextTypes[type]) { - mappedContextTypes[type] = true; - for (const propertyName in ctx) { - if (typeof ctx[propertyName] === 'number') { - glEnums[ctx[propertyName]] = propertyName; - enumStringToValue[propertyName] = ctx[propertyName]; - } - } - } - } - - function enumArrayToString(enums) { - const enumStrings = []; - if (enums.length) { - for (let i = 0; i < enums.length; ++i) { + function addEnumsForContext( ctx, type ) { + + if ( ! mappedContextTypes[ type ] ) { + + mappedContextTypes[ type ] = true; + for ( const propertyName in ctx ) { + + if ( typeof ctx[ propertyName ] === 'number' ) { + + glEnums[ ctx[ propertyName ] ] = propertyName; + enumStringToValue[ propertyName ] = ctx[ propertyName ]; + + } + + } + + } + + } + + function enumArrayToString( enums ) { + + const enumStrings = []; + if ( enums.length ) { + + for ( let i = 0; i < enums.length; ++ i ) { + enums.push(glEnumToString(enums[i])); // eslint-disable-line - } - return '[' + enumStrings.join(', ') + ']'; - } - return enumStrings.toString(); - } - - function makeBitFieldToStringFunc(enums) { - return function(value) { - let orResult = 0; - const orEnums = []; - for (let i = 0; i < enums.length; ++i) { - const enumValue = enumStringToValue[enums[i]]; - if ((value & enumValue) !== 0) { - orResult |= enumValue; + } + + return '[' + enumStrings.join( ', ' ) + ']'; + + } + + return enumStrings.toString(); + + } + + function makeBitFieldToStringFunc( enums ) { + + return function ( value ) { + + let orResult = 0; + const orEnums = []; + for ( let i = 0; i < enums.length; ++ i ) { + + const enumValue = enumStringToValue[ enums[ i ] ]; + if ( ( value & enumValue ) !== 0 ) { + + orResult |= enumValue; orEnums.push(glEnumToString(enumValue)); // eslint-disable-line - } - } - if (orResult === value) { - return orEnums.join(' | '); - } else { + } + + } + + if ( orResult === value ) { + + return orEnums.join( ' | ' ); + + } else { + return glEnumToString(value); // eslint-disable-line - } - }; - } + } + + }; - const destBufferBitFieldToString = makeBitFieldToStringFunc([ - 'COLOR_BUFFER_BIT', - 'DEPTH_BUFFER_BIT', - 'STENCIL_BUFFER_BIT', - ]); + } - /** + const destBufferBitFieldToString = makeBitFieldToStringFunc( [ + 'COLOR_BUFFER_BIT', + 'DEPTH_BUFFER_BIT', + 'STENCIL_BUFFER_BIT', + ] ); + + /** * Which arguments are enums based on the number of arguments to the function. * So * 'texImage2D': { @@ -154,207 +188,207 @@ * * @type {!Object.|function)} */ - const glValidEnumContexts = { - // Generic setters and getters - - 'enable': {1: { 0:true }}, - 'disable': {1: { 0:true }}, - 'getParameter': {1: { 0:true }}, - - // Rendering - - 'drawArrays': {3:{ 0:true }}, - 'drawElements': {4:{ 0:true, 2:true }}, - 'drawArraysInstanced': {4: { 0:true }}, - 'drawElementsInstanced': {5: {0:true, 2: true }}, - 'drawRangeElements': {6: {0:true, 4: true }}, - - // Shaders - - 'createShader': {1: { 0:true }}, - 'getShaderParameter': {2: { 1:true }}, - 'getProgramParameter': {2: { 1:true }}, - 'getShaderPrecisionFormat': {2: { 0: true, 1:true }}, - - // Vertex attributes - - 'getVertexAttrib': {2: { 1:true }}, - 'vertexAttribPointer': {6: { 2:true }}, - 'vertexAttribIPointer': {5: { 2:true }}, // WebGL2 - - // Textures - - 'bindTexture': {2: { 0:true }}, - 'activeTexture': {1: { 0:true }}, - 'getTexParameter': {2: { 0:true, 1:true }}, - 'texParameterf': {3: { 0:true, 1:true }}, - 'texParameteri': {3: { 0:true, 1:true, 2:true }}, - 'texImage2D': { - 9: { 0:true, 2:true, 6:true, 7:true }, - 6: { 0:true, 2:true, 3:true, 4:true }, - 10: { 0:true, 2:true, 6:true, 7:true }, // WebGL2 - }, - 'texImage3D': { - 10: { 0:true, 2:true, 7:true, 8:true }, // WebGL2 - 11: { 0:true, 2:true, 7:true, 8:true }, // WebGL2 - }, - 'texSubImage2D': { - 9: { 0:true, 6:true, 7:true }, - 7: { 0:true, 4:true, 5:true }, - 10: { 0:true, 6:true, 7:true }, // WebGL2 - }, - 'texSubImage3D': { - 11: { 0:true, 8:true, 9:true }, // WebGL2 - 12: { 0:true, 8:true, 9:true }, // WebGL2 - }, - 'texStorage2D': { 5: { 0:true, 2:true }}, // WebGL2 - 'texStorage3D': { 6: { 0:true, 2:true }}, // WebGL2 - 'copyTexImage2D': {8: { 0:true, 2:true }}, - 'copyTexSubImage2D': {8: { 0:true }}, - 'copyTexSubImage3D': {9: { 0:true }}, // WebGL2 - 'generateMipmap': {1: { 0:true }}, - 'compressedTexImage2D': { - 7: { 0: true, 2:true }, - 8: { 0: true, 2:true }, // WebGL2 - }, - 'compressedTexSubImage2D': { - 8: { 0: true, 6:true }, - 9: { 0: true, 6:true }, // WebGL2 - }, - 'compressedTexImage3D': { - 8: { 0: true, 2: true, }, // WebGL2 - 9: { 0: true, 2: true, }, // WebGL2 - }, - 'compressedTexSubImage3D': { - 9: { 0: true, 8: true, }, // WebGL2 - 10: { 0: true, 8: true, }, // WebGL2 - }, - - // Buffer objects - - 'bindBuffer': {2: { 0:true }}, - 'bufferData': { - 3: { 0:true, 2:true }, - 4: { 0:true, 2:true }, // WebGL2 - 5: { 0:true, 2:true }, // WebGL2 - }, - 'bufferSubData': { - 3: { 0:true }, - 4: { 0:true }, // WebGL2 - 5: { 0:true }, // WebGL2 - }, - 'copyBufferSubData': { - 5: { 0:true }, // WeBGL2 - }, - 'getBufferParameter': {2: { 0:true, 1:true }}, - 'getBufferSubData': { - 3: { 0: true, }, // WebGL2 - 4: { 0: true, }, // WebGL2 - 5: { 0: true, }, // WebGL2 - }, - - // Renderbuffers and framebuffers - - 'pixelStorei': {2: { 0:true, 1:true }}, - 'readPixels': { - 7: { 4:true, 5:true }, - 8: { 4:true, 5:true }, // WebGL2 - }, - 'bindRenderbuffer': {2: { 0:true }}, - 'bindFramebuffer': {2: { 0:true }}, - 'blitFramebuffer': {10: { 8: destBufferBitFieldToString, 9:true }}, // WebGL2 - 'checkFramebufferStatus': {1: { 0:true }}, - 'framebufferRenderbuffer': {4: { 0:true, 1:true, 2:true }}, - 'framebufferTexture2D': {5: { 0:true, 1:true, 2:true }}, - 'framebufferTextureLayer': {5: {0:true, 1:true }}, // WebGL2 - 'getFramebufferAttachmentParameter': {3: { 0:true, 1:true, 2:true }}, - 'getInternalformatParameter': {3: {0:true, 1:true, 2:true }}, // WebGL2 - 'getRenderbufferParameter': {2: { 0:true, 1:true }}, - 'invalidateFramebuffer': {2: { 0:true, 1: enumArrayToString, }}, // WebGL2 - 'invalidateSubFramebuffer': {6: {0: true, 1: enumArrayToString, }}, // WebGL2 - 'readBuffer': {1: {0: true}}, // WebGL2 - 'renderbufferStorage': {4: { 0:true, 1:true }}, - 'renderbufferStorageMultisample': {5: { 0: true, 2: true }}, // WebGL2 - - // Frame buffer operations (clear, blend, depth test, stencil) - - 'clear': {1: { 0: destBufferBitFieldToString }}, - 'depthFunc': {1: { 0:true }}, - 'blendFunc': {2: { 0:true, 1:true }}, - 'blendFuncSeparate': {4: { 0:true, 1:true, 2:true, 3:true }}, - 'blendEquation': {1: { 0:true }}, - 'blendEquationSeparate': {2: { 0:true, 1:true }}, - 'stencilFunc': {3: { 0:true }}, - 'stencilFuncSeparate': {4: { 0:true, 1:true }}, - 'stencilMaskSeparate': {2: { 0:true }}, - 'stencilOp': {3: { 0:true, 1:true, 2:true }}, - 'stencilOpSeparate': {4: { 0:true, 1:true, 2:true, 3:true }}, - - // Culling - - 'cullFace': {1: { 0:true }}, - 'frontFace': {1: { 0:true }}, - - // ANGLE_instanced_arrays extension - - 'drawArraysInstancedANGLE': {4: { 0:true }}, - 'drawElementsInstancedANGLE': {5: { 0:true, 2:true }}, - - // EXT_blend_minmax extension - - 'blendEquationEXT': {1: { 0:true }}, - - // Multiple Render Targets - - 'drawBuffersWebGL': {1: {0: enumArrayToString, }}, // WEBGL_draw_bufers - 'drawBuffers': {1: {0: enumArrayToString, }}, // WebGL2 - 'clearBufferfv': { - 4: {0: true }, // WebGL2 - 5: {0: true }, // WebGL2 - }, - 'clearBufferiv': { - 4: {0: true }, // WebGL2 - 5: {0: true }, // WebGL2 - }, - 'clearBufferuiv': { - 4: {0: true }, // WebGL2 - 5: {0: true }, // WebGL2 - }, - 'clearBufferfi': { 4: {0: true}}, // WebGL2 - - // QueryObjects - - 'beginQuery': { 2: { 0: true }}, // WebGL2 - 'endQuery': { 1: { 0: true }}, // WebGL2 - 'getQuery': { 2: { 0: true, 1: true }}, // WebGL2 - 'getQueryParameter': { 2: { 1: true }}, // WebGL2 - - // Sampler Objects - - 'samplerParameteri': { 3: { 1: true }}, // WebGL2 - 'samplerParameterf': { 3: { 1: true }}, // WebGL2 - 'getSamplerParameter': { 2: { 1: true }}, // WebGL2 - - // Sync objects - - 'clientWaitSync': { 3: { 1: makeBitFieldToStringFunc(['SYNC_FLUSH_COMMANDS_BIT']) }}, // WebGL2 - 'fenceSync': { 2: { 0: true }}, // WebGL2 - 'getSyncParameter': { 2: { 1: true }}, // WebGL2 - - // Transform Feedback - - 'bindTransformFeedback': { 2: { 0: true }}, // WebGL2 - 'beginTransformFeedback': { 1: { 0: true }}, // WebGL2 - - // Uniform Buffer Objects and Transform Feedback Buffers - 'bindBufferBase': { 3: { 0: true }}, // WebGL2 - 'bindBufferRange': { 5: { 0: true }}, // WebGL2 - 'getIndexedParameter': { 2: { 0: true }}, // WebGL2 - 'getActiveUniforms': { 3: { 2: true }}, // WebGL2 - 'getActiveUniformBlockParameter': { 3: { 2: true }}, // WebGL2 - }; - - /** + const glValidEnumContexts = { + // Generic setters and getters + + 'enable': { 1: { 0: true } }, + 'disable': { 1: { 0: true } }, + 'getParameter': { 1: { 0: true } }, + + // Rendering + + 'drawArrays': { 3: { 0: true } }, + 'drawElements': { 4: { 0: true, 2: true } }, + 'drawArraysInstanced': { 4: { 0: true } }, + 'drawElementsInstanced': { 5: { 0: true, 2: true } }, + 'drawRangeElements': { 6: { 0: true, 4: true } }, + + // Shaders + + 'createShader': { 1: { 0: true } }, + 'getShaderParameter': { 2: { 1: true } }, + 'getProgramParameter': { 2: { 1: true } }, + 'getShaderPrecisionFormat': { 2: { 0: true, 1: true } }, + + // Vertex attributes + + 'getVertexAttrib': { 2: { 1: true } }, + 'vertexAttribPointer': { 6: { 2: true } }, + 'vertexAttribIPointer': { 5: { 2: true } }, // WebGL2 + + // Textures + + 'bindTexture': { 2: { 0: true } }, + 'activeTexture': { 1: { 0: true } }, + 'getTexParameter': { 2: { 0: true, 1: true } }, + 'texParameterf': { 3: { 0: true, 1: true } }, + 'texParameteri': { 3: { 0: true, 1: true, 2: true } }, + 'texImage2D': { + 9: { 0: true, 2: true, 6: true, 7: true }, + 6: { 0: true, 2: true, 3: true, 4: true }, + 10: { 0: true, 2: true, 6: true, 7: true }, // WebGL2 + }, + 'texImage3D': { + 10: { 0: true, 2: true, 7: true, 8: true }, // WebGL2 + 11: { 0: true, 2: true, 7: true, 8: true }, // WebGL2 + }, + 'texSubImage2D': { + 9: { 0: true, 6: true, 7: true }, + 7: { 0: true, 4: true, 5: true }, + 10: { 0: true, 6: true, 7: true }, // WebGL2 + }, + 'texSubImage3D': { + 11: { 0: true, 8: true, 9: true }, // WebGL2 + 12: { 0: true, 8: true, 9: true }, // WebGL2 + }, + 'texStorage2D': { 5: { 0: true, 2: true } }, // WebGL2 + 'texStorage3D': { 6: { 0: true, 2: true } }, // WebGL2 + 'copyTexImage2D': { 8: { 0: true, 2: true } }, + 'copyTexSubImage2D': { 8: { 0: true } }, + 'copyTexSubImage3D': { 9: { 0: true } }, // WebGL2 + 'generateMipmap': { 1: { 0: true } }, + 'compressedTexImage2D': { + 7: { 0: true, 2: true }, + 8: { 0: true, 2: true }, // WebGL2 + }, + 'compressedTexSubImage2D': { + 8: { 0: true, 6: true }, + 9: { 0: true, 6: true }, // WebGL2 + }, + 'compressedTexImage3D': { + 8: { 0: true, 2: true, }, // WebGL2 + 9: { 0: true, 2: true, }, // WebGL2 + }, + 'compressedTexSubImage3D': { + 9: { 0: true, 8: true, }, // WebGL2 + 10: { 0: true, 8: true, }, // WebGL2 + }, + + // Buffer objects + + 'bindBuffer': { 2: { 0: true } }, + 'bufferData': { + 3: { 0: true, 2: true }, + 4: { 0: true, 2: true }, // WebGL2 + 5: { 0: true, 2: true }, // WebGL2 + }, + 'bufferSubData': { + 3: { 0: true }, + 4: { 0: true }, // WebGL2 + 5: { 0: true }, // WebGL2 + }, + 'copyBufferSubData': { + 5: { 0: true }, // WeBGL2 + }, + 'getBufferParameter': { 2: { 0: true, 1: true } }, + 'getBufferSubData': { + 3: { 0: true, }, // WebGL2 + 4: { 0: true, }, // WebGL2 + 5: { 0: true, }, // WebGL2 + }, + + // Renderbuffers and framebuffers + + 'pixelStorei': { 2: { 0: true, 1: true } }, + 'readPixels': { + 7: { 4: true, 5: true }, + 8: { 4: true, 5: true }, // WebGL2 + }, + 'bindRenderbuffer': { 2: { 0: true } }, + 'bindFramebuffer': { 2: { 0: true } }, + 'blitFramebuffer': { 10: { 8: destBufferBitFieldToString, 9: true } }, // WebGL2 + 'checkFramebufferStatus': { 1: { 0: true } }, + 'framebufferRenderbuffer': { 4: { 0: true, 1: true, 2: true } }, + 'framebufferTexture2D': { 5: { 0: true, 1: true, 2: true } }, + 'framebufferTextureLayer': { 5: { 0: true, 1: true } }, // WebGL2 + 'getFramebufferAttachmentParameter': { 3: { 0: true, 1: true, 2: true } }, + 'getInternalformatParameter': { 3: { 0: true, 1: true, 2: true } }, // WebGL2 + 'getRenderbufferParameter': { 2: { 0: true, 1: true } }, + 'invalidateFramebuffer': { 2: { 0: true, 1: enumArrayToString, } }, // WebGL2 + 'invalidateSubFramebuffer': { 6: { 0: true, 1: enumArrayToString, } }, // WebGL2 + 'readBuffer': { 1: { 0: true } }, // WebGL2 + 'renderbufferStorage': { 4: { 0: true, 1: true } }, + 'renderbufferStorageMultisample': { 5: { 0: true, 2: true } }, // WebGL2 + + // Frame buffer operations (clear, blend, depth test, stencil) + + 'clear': { 1: { 0: destBufferBitFieldToString } }, + 'depthFunc': { 1: { 0: true } }, + 'blendFunc': { 2: { 0: true, 1: true } }, + 'blendFuncSeparate': { 4: { 0: true, 1: true, 2: true, 3: true } }, + 'blendEquation': { 1: { 0: true } }, + 'blendEquationSeparate': { 2: { 0: true, 1: true } }, + 'stencilFunc': { 3: { 0: true } }, + 'stencilFuncSeparate': { 4: { 0: true, 1: true } }, + 'stencilMaskSeparate': { 2: { 0: true } }, + 'stencilOp': { 3: { 0: true, 1: true, 2: true } }, + 'stencilOpSeparate': { 4: { 0: true, 1: true, 2: true, 3: true } }, + + // Culling + + 'cullFace': { 1: { 0: true } }, + 'frontFace': { 1: { 0: true } }, + + // ANGLE_instanced_arrays extension + + 'drawArraysInstancedANGLE': { 4: { 0: true } }, + 'drawElementsInstancedANGLE': { 5: { 0: true, 2: true } }, + + // EXT_blend_minmax extension + + 'blendEquationEXT': { 1: { 0: true } }, + + // Multiple Render Targets + + 'drawBuffersWebGL': { 1: { 0: enumArrayToString, } }, // WEBGL_draw_bufers + 'drawBuffers': { 1: { 0: enumArrayToString, } }, // WebGL2 + 'clearBufferfv': { + 4: { 0: true }, // WebGL2 + 5: { 0: true }, // WebGL2 + }, + 'clearBufferiv': { + 4: { 0: true }, // WebGL2 + 5: { 0: true }, // WebGL2 + }, + 'clearBufferuiv': { + 4: { 0: true }, // WebGL2 + 5: { 0: true }, // WebGL2 + }, + 'clearBufferfi': { 4: { 0: true } }, // WebGL2 + + // QueryObjects + + 'beginQuery': { 2: { 0: true } }, // WebGL2 + 'endQuery': { 1: { 0: true } }, // WebGL2 + 'getQuery': { 2: { 0: true, 1: true } }, // WebGL2 + 'getQueryParameter': { 2: { 1: true } }, // WebGL2 + + // Sampler Objects + + 'samplerParameteri': { 3: { 1: true } }, // WebGL2 + 'samplerParameterf': { 3: { 1: true } }, // WebGL2 + 'getSamplerParameter': { 2: { 1: true } }, // WebGL2 + + // Sync objects + + 'clientWaitSync': { 3: { 1: makeBitFieldToStringFunc( [ 'SYNC_FLUSH_COMMANDS_BIT' ] ) } }, // WebGL2 + 'fenceSync': { 2: { 0: true } }, // WebGL2 + 'getSyncParameter': { 2: { 1: true } }, // WebGL2 + + // Transform Feedback + + 'bindTransformFeedback': { 2: { 0: true } }, // WebGL2 + 'beginTransformFeedback': { 1: { 0: true } }, // WebGL2 + + // Uniform Buffer Objects and Transform Feedback Buffers + 'bindBufferBase': { 3: { 0: true } }, // WebGL2 + 'bindBufferRange': { 5: { 0: true } }, // WebGL2 + 'getIndexedParameter': { 2: { 0: true } }, // WebGL2 + 'getActiveUniforms': { 3: { 2: true } }, // WebGL2 + 'getActiveUniformBlockParameter': { 3: { 2: true } }, // WebGL2 + }; + + /** * Gets an string version of an WebGL enum. * * Example: @@ -363,14 +397,16 @@ * @param {number} value Value to return an enum for * @return {string} The string version of the enum. */ - function glEnumToString(value) { - const name = glEnums[value]; - return (name !== undefined) - ? `gl.${name}` - : `/*UNKNOWN WebGL ENUM*/ 0x${value.toString(16)}`; - } - - /** + function glEnumToString( value ) { + + const name = glEnums[ value ]; + return ( name !== undefined ) + ? `gl.${name}` + : `/*UNKNOWN WebGL ENUM*/ 0x${value.toString( 16 )}`; + + } + + /** * Returns the string version of a WebGL argument. * Attempts to convert enum arguments to strings. * @param {string} functionName the name of the WebGL function. @@ -379,31 +415,50 @@ * @param {*} value The value of the argument. * @return {string} The value as a string. */ - function glFunctionArgToString(functionName, numArgs, argumentIndex, value) { - const funcInfos = glValidEnumContexts[functionName]; - if (funcInfos !== undefined) { - const funcInfo = funcInfos[numArgs]; - if (funcInfo !== undefined) { - const argType = funcInfo[argumentIndex]; - if (argType) { - if (typeof argType === 'function') { - return argType(value); - } else { - return glEnumToString(value); - } - } - } - } - if (value === null) { - return 'null'; - } else if (value === undefined) { - return 'undefined'; - } else { - return value.toString(); - } - } - - /** + function glFunctionArgToString( functionName, numArgs, argumentIndex, value ) { + + const funcInfos = glValidEnumContexts[ functionName ]; + if ( funcInfos !== undefined ) { + + const funcInfo = funcInfos[ numArgs ]; + if ( funcInfo !== undefined ) { + + const argType = funcInfo[ argumentIndex ]; + if ( argType ) { + + if ( typeof argType === 'function' ) { + + return argType( value ); + + } else { + + return glEnumToString( value ); + + } + + } + + } + + } + + if ( value === null ) { + + return 'null'; + + } else if ( value === undefined ) { + + return 'undefined'; + + } else { + + return value.toString(); + + } + + } + + /** * Converts the arguments of a WebGL function to a string. * Attempts to convert enum arguments to strings. * @@ -411,28 +466,37 @@ * @param {number} args The arguments. * @return {string} The arguments as a string. */ - function glFunctionArgsToString(functionName, args) { - // apparently we can't do args.join(","); - const argStrs = []; - const numArgs = args.length; - for (let ii = 0; ii < numArgs; ++ii) { - argStrs.push(glFunctionArgToString(functionName, numArgs, ii, args[ii])); - } - return argStrs.join(', '); - } - - function makePropertyWrapper(wrapper, original, propertyName) { + function glFunctionArgsToString( functionName, args ) { + + // apparently we can't do args.join(","); + const argStrs = []; + const numArgs = args.length; + for ( let ii = 0; ii < numArgs; ++ ii ) { + + argStrs.push( glFunctionArgToString( functionName, numArgs, ii, args[ ii ] ) ); + + } + + return argStrs.join( ', ' ); + + } + + function makePropertyWrapper( wrapper, original, propertyName ) { + wrapper.__defineGetter__(propertyName, function() { // eslint-disable-line - return original[propertyName]; - }); - // TODO(gmane): this needs to handle properties that take more than - // one value? + return original[ propertyName ]; + + } ); + // TODO(gmane): this needs to handle properties that take more than + // one value? wrapper.__defineSetter__(propertyName, function(value) { // eslint-disable-line - original[propertyName] = value; - }); - } + original[ propertyName ] = value; + + } ); - /** + } + + /** * Given a WebGL context returns a wrapped context that calls * gl.getError after every command and calls a function if the * result is not gl.NO_ERROR. @@ -449,125 +513,182 @@ * @param {!WebGLRenderingContext} opt_err_ctx The webgl context * to call getError on if different than ctx. */ - function makeDebugContext(ctx, options) { - options = options || {}; - const errCtx = options.errCtx || ctx; - const onFunc = options.funcFunc; - const sharedState = options.sharedState || { - numDrawCallsRemaining: options.maxDrawCalls || -1, - wrappers: {}, - }; - options.sharedState = sharedState; - - const errorFunc = options.errorFunc || function(err, functionName, args) { - console.error(`WebGL error ${glEnumToString(err)} in ${functionName}(${glFunctionArgsToString(functionName, args)})`); /* eslint-disable-line no-console */ - }; - - // Holds booleans for each GL error so after we get the error ourselves - // we can still return it to the client app. - const glErrorShadow = { }; - const wrapper = {}; - - function removeChecks() { - Object.keys(sharedState.wrappers).forEach(function(name) { - const pair = sharedState.wrappers[name]; - const wrapper = pair.wrapper; - const orig = pair.orig; - for (const propertyName in wrapper) { - if (typeof wrapper[propertyName] === 'function') { - wrapper[propertyName] = orig[propertyName].bind(orig); - } - } - }); - } - - function checkMaxDrawCalls() { - if (sharedState.numDrawCallsRemaining === 0) { - removeChecks(); - } - --sharedState.numDrawCallsRemaining; - } - - function noop() { - } - - // Makes a function that calls a WebGL function and then calls getError. - function makeErrorWrapper(ctx, functionName) { - const check = functionName.substring(0, 4) === 'draw' ? checkMaxDrawCalls : noop; - return function() { - if (onFunc) { - onFunc(functionName, arguments); - } - const result = ctx[functionName].apply(ctx, arguments); - const err = errCtx.getError(); - if (err !== 0) { - glErrorShadow[err] = true; - errorFunc(err, functionName, arguments); - } - check(); - return result; - }; - } - - function makeGetExtensionWrapper(ctx, wrapped) { - return function() { - const extensionName = arguments[0]; - let ext = sharedState.wrappers[extensionName]; - if (!ext) { - ext = wrapped.apply(ctx, arguments); - if (ext) { - const origExt = ext; - ext = makeDebugContext(ext, {...options, errCtx: ctx}); - sharedState.wrappers[extensionName] = { wrapper: ext, orig: origExt }; - addEnumsForContext(origExt, extensionName); - } - } - return ext; - }; - } - - // Make a an object that has a copy of every property of the WebGL context - // but wraps all functions. - for (const propertyName in ctx) { - if (typeof ctx[propertyName] === 'function') { - if (propertyName !== 'getExtension') { - wrapper[propertyName] = makeErrorWrapper(ctx, propertyName); - } else { - const wrapped = makeErrorWrapper(ctx, propertyName); - wrapper[propertyName] = makeGetExtensionWrapper(ctx, wrapped); - } - } else { - makePropertyWrapper(wrapper, ctx, propertyName); - } - } - - // Override the getError function with one that returns our saved results. - if (wrapper.getError) { - wrapper.getError = function() { - for (const err of Object.keys(glErrorShadow)) { - if (glErrorShadow[err]) { - glErrorShadow[err] = false; - return err; - } - } - return ctx.NO_ERROR; - }; - } - - if (wrapper.bindBuffer) { - sharedState.wrappers['webgl'] = { wrapper: wrapper, orig: ctx }; - addEnumsForContext(ctx, ctx.bindBufferBase ? 'WebGL2' : 'WebGL'); - } - - return wrapper; - } - - return { - makeDebugContext, - glFunctionArgsToString, - glFunctionArgToString, - glEnumToString, - }; - -})); + function makeDebugContext( ctx, options ) { + + options = options || {}; + const errCtx = options.errCtx || ctx; + const onFunc = options.funcFunc; + const sharedState = options.sharedState || { + numDrawCallsRemaining: options.maxDrawCalls || - 1, + wrappers: {}, + }; + options.sharedState = sharedState; + + const errorFunc = options.errorFunc || function ( err, functionName, args ) { + + console.error( `WebGL error ${glEnumToString( err )} in ${functionName}(${glFunctionArgsToString( functionName, args )})` ); /* eslint-disable-line no-console */ + + }; + + // Holds booleans for each GL error so after we get the error ourselves + // we can still return it to the client app. + const glErrorShadow = { }; + const wrapper = {}; + + function removeChecks() { + + Object.keys( sharedState.wrappers ).forEach( function ( name ) { + + const pair = sharedState.wrappers[ name ]; + const wrapper = pair.wrapper; + const orig = pair.orig; + for ( const propertyName in wrapper ) { + + if ( typeof wrapper[ propertyName ] === 'function' ) { + + wrapper[ propertyName ] = orig[ propertyName ].bind( orig ); + + } + + } + + } ); + + } + + function checkMaxDrawCalls() { + + if ( sharedState.numDrawCallsRemaining === 0 ) { + + removeChecks(); + + } + + -- sharedState.numDrawCallsRemaining; + + } + + function noop() { + } + + // Makes a function that calls a WebGL function and then calls getError. + function makeErrorWrapper( ctx, functionName ) { + + const check = functionName.substring( 0, 4 ) === 'draw' ? checkMaxDrawCalls : noop; + return function () { + + if ( onFunc ) { + + onFunc( functionName, arguments ); + + } + + const result = ctx[ functionName ].apply( ctx, arguments ); + const err = errCtx.getError(); + if ( err !== 0 ) { + + glErrorShadow[ err ] = true; + errorFunc( err, functionName, arguments ); + + } + + check(); + return result; + + }; + + } + + function makeGetExtensionWrapper( ctx, wrapped ) { + + return function () { + + const extensionName = arguments[ 0 ]; + let ext = sharedState.wrappers[ extensionName ]; + if ( ! ext ) { + + ext = wrapped.apply( ctx, arguments ); + if ( ext ) { + + const origExt = ext; + ext = makeDebugContext( ext, { ...options, errCtx: ctx } ); + sharedState.wrappers[ extensionName ] = { wrapper: ext, orig: origExt }; + addEnumsForContext( origExt, extensionName ); + + } + + } + + return ext; + + }; + + } + + // Make a an object that has a copy of every property of the WebGL context + // but wraps all functions. + for ( const propertyName in ctx ) { + + if ( typeof ctx[ propertyName ] === 'function' ) { + + if ( propertyName !== 'getExtension' ) { + + wrapper[ propertyName ] = makeErrorWrapper( ctx, propertyName ); + + } else { + + const wrapped = makeErrorWrapper( ctx, propertyName ); + wrapper[ propertyName ] = makeGetExtensionWrapper( ctx, wrapped ); + + } + + } else { + + makePropertyWrapper( wrapper, ctx, propertyName ); + + } + + } + + // Override the getError function with one that returns our saved results. + if ( wrapper.getError ) { + + wrapper.getError = function () { + + for ( const err of Object.keys( glErrorShadow ) ) { + + if ( glErrorShadow[ err ] ) { + + glErrorShadow[ err ] = false; + return err; + + } + + } + + return ctx.NO_ERROR; + + }; + + } + + if ( wrapper.bindBuffer ) { + + sharedState.wrappers[ 'webgl' ] = { wrapper: wrapper, orig: ctx }; + addEnumsForContext( ctx, ctx.bindBufferBase ? 'WebGL2' : 'WebGL' ); + + } + + return wrapper; + + } + + return { + makeDebugContext, + glFunctionArgsToString, + glFunctionArgToString, + glEnumToString, + }; + +} ) ); diff --git a/manual/examples/scenegraph-sun-earth-moon-axes-grids.html b/manual/examples/scenegraph-sun-earth-moon-axes-grids.html index fc3afb236a76f3..a45686c969e573 100644 --- a/manual/examples/scenegraph-sun-earth-moon-axes-grids.html +++ b/manual/examples/scenegraph-sun-earth-moon-axes-grids.html @@ -53,14 +53,20 @@ @@ -37,8 +37,8 @@

            Aligning HTML Elements to 3D

            - - + + diff --git a/manual/fr/backgrounds.html b/manual/fr/backgrounds.html index 82cd9eaa603f00..8198803ce5c45c 100644 --- a/manual/fr/backgrounds.html +++ b/manual/fr/backgrounds.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Backgrounds and Skyboxes

            - - + + diff --git a/manual/fr/billboards.html b/manual/fr/billboards.html index fbc3ab5d6d971f..e51e6104db69cd 100644 --- a/manual/fr/billboards.html +++ b/manual/fr/billboards.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Billboards

            - - + + diff --git a/manual/fr/cameras.html b/manual/fr/cameras.html index 268c287b85623d..fddfc451199035 100644 --- a/manual/fr/cameras.html +++ b/manual/fr/cameras.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -476,8 +476,8 @@

            Caméras dans

            - - + + diff --git a/manual/fr/canvas-textures.html b/manual/fr/canvas-textures.html index 1ee64752681bd0..d933bba4930bfd 100644 --- a/manual/fr/canvas-textures.html +++ b/manual/fr/canvas-textures.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Canvas Textures

            - - + + diff --git a/manual/fr/cleanup.html b/manual/fr/cleanup.html index ba3b1926e1ef3c..58a2da0a98d475 100644 --- a/manual/fr/cleanup.html +++ b/manual/fr/cleanup.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Cleanup

            - - + + diff --git a/manual/fr/custom-buffergeometry.html b/manual/fr/custom-buffergeometry.html index 622c4c73fc1e2a..b93f1222c77dd6 100644 --- a/manual/fr/custom-buffergeometry.html +++ b/manual/fr/custom-buffergeometry.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -446,8 +446,8 @@

            Custom BufferGeometry

            - - + + diff --git a/manual/fr/custom-geometry.html b/manual/fr/custom-geometry.html deleted file mode 100644 index 57f02ae1006685..00000000000000 --- a/manual/fr/custom-geometry.html +++ /dev/null @@ -1,46 +0,0 @@ - - - Custom Geometry - - - - - - - - - - - - - - - - - -
            -
            -

            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/debugging-glsl.html b/manual/fr/debugging-glsl.html index d921269863dedf..b480bbd7454c38 100644 --- a/manual/fr/debugging-glsl.html +++ b/manual/fr/debugging-glsl.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Debugging - GLSL

            - - + + diff --git a/manual/fr/debugging-javascript.html b/manual/fr/debugging-javascript.html index d1ace351449efa..c488f8d36f6dfe 100644 --- a/manual/fr/debugging-javascript.html +++ b/manual/fr/debugging-javascript.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Debugging JavaScript

            - - + + diff --git a/manual/fr/fog.html b/manual/fr/fog.html index 452340b77ca005..3ac333a0cd6fee 100644 --- a/manual/fr/fog.html +++ b/manual/fr/fog.html @@ -1,16 +1,16 @@ - Brouillard dans + Le brouillard - + - - + + - - + + @@ -26,18 +26,17 @@
            -

            Brouillard dans

            +

            Le brouillard

            -

            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à. Si vous n'avez pas lu l'artcile concernant les caméras lisez-le avant celui-ci.

            -

            Le brouillard dans un moteur 3D est généralement un moyen de passer à une couleur spécifique en fonction de la distance par rapport à la caméra. Dans Three.js, vous ajoutez du brouillard en créant un objet Fog ou FogExp2 et en le définissant sur la propriété `fog de la scène.

            +

            Cet article fait partie d'une série consacrée à Three.js dont le premier article s'intitule Principes de base. +Si vous ne l'avez pas encore lu, vous devriez commencer par lui. Si, également, vous n'avez pas lu l'article concernant les caméras, lisez-le avant de poursuivre.

            +

            Le brouillard dans un moteur 3D est généralement un moyen d'atténuer les couleurs de la scène vers une couleur désirée en fonction de la distance par rapport à la caméra. Dans Three.js, vous pouvez ajouter du brouillard en crééant dans la propriété fog de votre scène, soit un objet Fog soit un objet FogExp2.

            Fog permet de définir les paramètres near et far en tant que distance par rapport à la caméra. Ce qui se trouve entre la caméra et near n'est pas affecté par le brouillard. Ce qui est au-delà de far est complètement dans le brouillard. Ce qui se trouve entre les deux, est altéré par le brouillard.

            -

            Il y a aussi FogExp2 qui croît de façon exponentielle avec la distance par rapport à la caméra.

            -

            Pour utiliser Fog, suivez cet exemple.

            +

            Il y a aussi FogExp2 qui croît de façon exponentielle en fonction de la distance de la caméra.

            +

            Pour utiliser Fog, suivez cet exemple :

            const scene = new THREE.Scene();
             {
               const color = 0xFFFFFF;  // white
            @@ -46,7 +45,7 @@ 

            Brouillard dans

            scene.fog = new THREE.Fog(color, near, far); }
            -

            ou pour FogExp2, celui-ci.

            +

            Pour utiliser FogExp2, suivez cet exemple :

            const scene = new THREE.Scene();
             {
               const color = 0xFFFFFF;
            @@ -54,7 +53,7 @@ 

            Brouillard dans

            scene.fog = new THREE.FogExp2(color, density); }
            -

            FogExp2 est plus proche de la réalité mais Fog est plus souvent utilisé car il permet de choisir un endroit où appliquer le brouillard, ce faisant on peut choisir de montrer une scène bien clair et du brouillard qu'au-delà.

            +

            FogExp2 est le plus proche de la réalité, mais Fog est le plus souvent utilisé car il permet de choisir un endroit où appliquer le brouillard, afin de vous permettre d'afficher une scène claire jusqu'à une certaine distance, puis de passer à une autre couleur au-delà de cette distance.

            @@ -66,21 +65,21 @@

            Brouillard dans

            -

            Il est important de noter que le brouillard est appliqué aux choses qui sont rendues. Il fait partie du calcul de chaque pixel de la couleur de l'objet. Cela signifie que si vous voulez que votre scène s'estompe avec une certaine couleur, vous devez définir le brouillard et la couleur d'arrière-plan sur la même couleur. La couleur d'arrière-plan est définie à l'aide de la propriété scene.background. Pour choisir une couleur d'arrière-plan, vous lui attachez une THREE.Color. Comme ceci :

            +

            Il est important de noter que le brouillard s'applique aux objets rendus lors du calcul sur chaque pixel de la couleur des objets. Cela signifie que si vous voulez que votre scène s'estompe avec une certaine couleur, vous devez définir le brouillard ainsi que la couleur d'arrière-plan avec la même couleur. La couleur d'arrière-plan est définie à l'aide de la propriété scene.background. Pour choisir une couleur d'arrière-plan, vous lui attachez une THREE.Color. Comme ceci :

            scene.background = new THREE.Color('#F00');  // red
             
            -
            fog blue, background red
            +
            Brouillard bleu, arrière-plan rouge
            -
            fog blue, background blue
            +
            Brouillard bleu, arrière-plan bleu
            -

            Voici l'un de nos exemples précédents avec du brouillard. Juste après la configuration de la scène, nous ajoutons le brouillard et définissons la couleur d'arrière-plan de la scène.

            +

            Voici l'un de nos exemples précédents mais avec du brouillard activé. L'unique ajout se fait juste après avoir configuré la scène : nous ajoutons le brouillard et définissons la couleur d'arrière-plan de la scène.

            const scene = new THREE.Scene();
             
             +{
            @@ -91,18 +90,18 @@ 

            Brouillard dans

            + scene.background = new THREE.Color(color); +}
            -

            Dans l'exemple ci-dessous, le 'near' de la caméra est à 0,1 et le far à 5. La position z de la caméra est à 2. Les cubes mesurent 1 unité de large et à Z = 0. Les réglages du brouillard, near = 1 et far = 2. Ainsi, les cubes s'estompent juste autour de leur centre.

            +

            Dans l'exemple ci-dessous, le near de la caméra est à 0,1 et le far à 5. La position z de la caméra est à 2. Les cubes mesurent 1 unité de large et à Z = 0. Les réglages du brouillard, near = 1 et far = 2. Ainsi, les cubes s'estompent juste autour de leur centre.

            -

            Mettons à jour notre lil-gui pour jouer avec le brouillard. -lil-gui prend un objet et une propriété et crée automatiquement une interface de contrôle pour cette propriété. Nous pourrions simplement le laisser manipuler les propriétés near et far du brouillard, mais il est impossible que near soit supérieur à far. Assurons-nous de cela.

            -
            // On utilise cette classe pour passer à lil-gui
            -// donc quand il manipule near ou far
            -// near n'est jamais > far et far n'est jamais < near
            +

            Mettons à jour notre lil-gui pour jouer avec le brouillard. Lil-gui prend un objet et une propriété et crée automatiquement une interface de contrôle pour cette propriété. Nous pourrions simplement le laisser modifier les propriétés near et far du brouillard, mais il est impossible que near soit supérieur à far. Assurons-nous de cela.

            +
            // On utilise cette classe pour passer à lil-gui.
            +// Quand lil-gui modifie near ou far :
            +//  - near n'est jamais strictement supérieur à far
            +//  - far n'est jamais strictement inférieur à near
             class FogGUIHelper {
               constructor(fog) {
                 this.fog = fog;
            @@ -123,7 +122,7 @@ 

            Brouillard dans

            } }
            -

            On peut l'ajouter comme ceci.

            +

            On peut l'ajouter comme ceci :

            {
               const near = 1;
               const far = 2;
            @@ -140,13 +139,13 @@ 

            Brouillard dans

            Le .listen() à la fin des 2 lignes, dit à lil-gui d'écouter les changements. Ainsi, que nous changions near ou far, lil-gui mettra automatiquement à jour les deux propriétés pour nous.

            Il peut également être agréable de pouvoir changer la couleur du brouillard, mais comme mentionné ci-dessus, nous devons synchroniser la couleur du brouillard et la couleur de l'arrière-plan. Ajoutons donc une autre propriété virtuelle à notre helper qui définira les deux couleurs lorsque lil-gui la manipule.

            -

            lil-gui peut manipuler les couleurs de 4 façons différentes. Sous la forme d'une chaîne hexadécimale à 6 chiffres (ex : #112233). Sous la forme HSL (ex : {h: 60, s: 1, v: }). -En tant que tableau RGB (ex : [255, 128, 64]). Ou, comme un tableau RGBA (ex : [127, 200, 75, 0.3]).

            -

            Il est plus simple d'utiliser la première solution, la version chaîne hexadécimale, ainsi -lil-gui nemanipule qu'une seule valeur. Heureusement, THREE.Color +

            lil-gui peut manipuler les couleurs de 4 façons différentes : - Sous la forme d'une chaîne hexadécimale à 6 chiffres (ex : #112233); - Sous la forme HSL (ex : {h: 60, s: 1, v: }); - +En tant que tableau RGB (ex : [255, 128, 64]); - Ou finalement, comme un tableau RGBA (ex : [127, 200, 75, 0.3]).

            +

            Il est plus simple d'utiliser la première solution, la version chaîne hexadécimale, ainsi +lil-gui ne manipule qu'une seule valeur. Heureusement, THREE.Color a une méthode pour cela : getHexString qui permet d'obtenir une telle chaîne, il suffit juste d'ajouter un '#' au début.

            /// On utilise cette classe pour passer à lil-gui
            -// donc quand il manipule near ou far
            +// Quand il manipule near ou far
             // near n'est jamais > far et far n'est jamais < near
             +// Aussi, lorsque lil-gui manipule la couleur, nous allons
             +// mettre à jour les couleurs du brouillard et de l'arrière-plan.
            @@ -178,7 +177,7 @@ 

            Brouillard dans

            + } }
            -

            Ensuite, nous appelons gui.addColor pour ajouter une couleur à notre propriété virtuelle.

            +

            Ensuite, nous appelons gui.addColor pour ajouter une couleur à notre propriété virtuelle :

            {
               const near = 1;
               const far = 2;
            @@ -194,25 +193,24 @@ 

            Brouillard dans

            -

            Vous pouvez voir qu'un réglage near à 1.9 et far à 2,0 donne une transition très nette entre non embué et complètement dans le brouillard. near = 1,1 et far = 2,9 devrait être la meilleure configuration étant donné que nos cubes tournent à 2 unités de la caméra.

            -

            Une dernière chose, il existe une propriété les matériaux pour savoir si les objets rendus avec ce matériau sont affectés ou non par le brouillard. La valeur par défaut est true pour la plupart des matériaux. Pour illustrer pourquoi vous pourriez vouloir désactiver le brouillard, imaginez que vous créez un simulateur de véhicule 3D avec une vue depuis le siège du conducteur ou le cockpit. Vous voulez probablement que le brouillard se dissipe pour tout ce qui se trouve à l'intérieur du véhicule lorsque vous regardez de l'intérieur du véhicule.

            -

            Prenons un autre exemple. Une maison avec un épais brouillard à l'extérieur. Disons que pour commencer, le brouillard est réglé pour commencer à 2 mètres (near = 2) et être complet à 4 mètres (far = 4). Les pièces et la maison faisant probablement plus de 4 mètres, il faudra donc définir les matériaux utilisés à l'intérieur de la maison pour qu'il n'y est pas de brouillard. Sinon, ça donnerait ceci.

            +

            Vous pouvez voir qu'un réglage near à 1.9 et far à 2.0 donne une transition très nette entre non embué et complètement dans le brouillard. near = 1.1 et far = 2.9 devrait être la meilleure configuration étant donné que nos cubes tournent à 2 unités de la caméra.

            +

            Une dernière chose ! Il existe une propriété fog pour savoir si les objets rendus avec ce matériau sont affectés ou non par le brouillard. La valeur par défaut est true pour la plupart des matériaux. Voici deux exemples illustrant cette volonté de désactiver le brouillard : imaginez que vous créez un simulateur de véhicule 3D avec une vue depuis le siège du conducteur (cockpit). Vous ne voulez pas qu'il n'y ait de brouillard à l'intérieur du véhicule. Prenons un second exemple : une maison avec un épais brouillard à l'extérieur. Disons que pour commencer, le brouillard est réglé pour commencer à 2 mètres (near = 2) et être total à 4 mètres (far = 4). Les pièces et la maison faisant plus de 4 mètres, il vous faudra donc définir les matériaux utilisés à l'intérieur de la maison pour qu'il n'y ait pas de brouillard, sinon, cela donnerait l'aspect non désiré suivant :

            -
            fog: true, all
            +
            fog à true sur tous les objets.
            -

            Remarquez que les murs et le plafond au fond de la pièce sont dans le brouillard. En désactivant le brouillard sur les matériaux de la maison, on résoud le problème.

            +

            Remarquez que les murs et le plafond au fond de la pièce sont dans le brouillard. En désactivant le brouillard sur les matériaux de la maison, on résout ce problème.

            -
            fog: true, only outside materials
            +
            fog à true sur uniquement les matériaux extérieurs de la maison.
            @@ -222,11 +220,11 @@

            Brouillard dans

            - - - + + + - \ No newline at end of file + diff --git a/manual/fr/fundamentals.html b/manual/fr/fundamentals.html index e6a22c9820faae..333de614ab7cc6 100644 --- a/manual/fr/fundamentals.html +++ b/manual/fr/fundamentals.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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';
             
            @@ -434,8 +434,8 @@

            es6 modules, Three.js et structure de dossiers

            - - + + diff --git a/manual/fr/game.html b/manual/fr/game.html index e61b6faf3ad041..80abaaecce87a7 100644 --- a/manual/fr/game.html +++ b/manual/fr/game.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Making a Game

            - - + + diff --git a/manual/fr/indexed-textures.html b/manual/fr/indexed-textures.html index 794744572da56f..7989b45dc89a6d 100644 --- a/manual/fr/indexed-textures.html +++ b/manual/fr/indexed-textures.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Indexed Textures for Picking and Color

            - - + + diff --git a/manual/fr/lights.html b/manual/fr/lights.html index cb98a01b03818a..7815be9d5d7064 100644 --- a/manual/fr/lights.html +++ b/manual/fr/lights.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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() {
            @@ -426,8 +426,8 @@ 

            - - + + diff --git a/manual/fr/load-gltf.html b/manual/fr/load-gltf.html index d54af65cc5ace0..e8157b7ba37b2c 100644 --- a/manual/fr/load-gltf.html +++ b/manual/fr/load-gltf.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Loading a .GLTF File

            - - + + diff --git a/manual/fr/load-obj.html b/manual/fr/load-obj.html index 7bd0977bb7c65c..0ef3355eb6bedd 100644 --- a/manual/fr/load-obj.html +++ b/manual/fr/load-obj.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Loading a .OBJ File

            - - + + diff --git a/manual/fr/material-table.html b/manual/fr/material-table.html index b828788565b164..8bd1829eba804b 100644 --- a/manual/fr/material-table.html +++ b/manual/fr/material-table.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Material Feature Table

            - - + + diff --git a/manual/fr/materials.html b/manual/fr/materials.html index 64baeddd5300b2..6ae3b557b4ed84 100644 --- a/manual/fr/materials.html +++ b/manual/fr/materials.html @@ -1,16 +1,16 @@ - Les Matériaux dans + Les matériaux - + - - + + - - + + @@ -26,28 +26,26 @@
            -

            Les Matériaux dans

            +

            Les matériaux

            -

            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à.

            -

            Three.js fournit plusieurs types de matériaux. -Ils définissent comment les objets apparaîtront dans la scène. -Les matériaux que vous utilisez dépendent vraiment de ce que vous essayez d'accomplir.

            -

            Il existe 2 façons de définir la plupart des propriétés des matériaux. A la création, comme nous l'avons déjà vu.

            +

            Cet article fait partie d'une série consacrée à Three.js dont +le premier article s'intitule Principes de base. +Si vous ne l'avez pas encore lu, vous devriez commencer par lui.

            +

            Three.js fournit plusieurs types de matériaux : ils définissent comment les objets apparaîtront dans la scène et par conséquent, la sélection de vos matériaux dépend fortement dans le choix de ce que vous voulez afficher.

            +

            Il existe deux façons de définir la plupart des propriétés des matériaux. La première façon est de les définir lors de la création du matériau (constructeur), comme nous l'avons déjà vu :

            const material = new THREE.MeshPhongMaterial({
               color: 0xFF0000,    // red (can also use a CSS color string here)
               flatShading: true,
             });
             
            -

            Ou après la création.

            +

            La seconde façon se fait après le constructeur :

            const material = new THREE.MeshPhongMaterial();
             material.color.setHSL(0, 1, .5);  // red
             material.flatShading = true;
             
            -

            notez qu'il y a plusieurs façons de paramétrer la propriété THREE.Color.

            +

            Notez qu'il y a plusieurs façons de paramétrer la propriété THREE.Color :

            material.color.set(0x00FFFF);    // same as CSS's #RRGGBB style
             material.color.set(cssString);   // any CSS color, eg 'purple', '#F32',
                                              // 'rgb(255, 127, 64)',
            @@ -56,16 +54,16 @@ 

            Les Matériaux dans

            material.color.setHSL(h, s, l) // where h, s, and l are 0 to 1 material.color.setRGB(r, g, b) // where r, g, and b are 0 to 1
            -

            A la création, vous pouvez passer, soit un nombre héxadécimal ou une valeur entre guillemet comme en CSS.

            +

            Pour le constructeur, vous pouvez passer, soit un nombre hexadécimal, soit une chaine de caractères au format CSS :

            const m1 = new THREE.MeshBasicMaterial({color: 0xFF0000});         // rouge
             const m2 = new THREE.MeshBasicMaterial({color: 'red'});            // rouge
             const m3 = new THREE.MeshBasicMaterial({color: '#F00'});           // rouge
             const m4 = new THREE.MeshBasicMaterial({color: 'rgb(255,0,0)'});   // rouge
             const m5 = new THREE.MeshBasicMaterial({color: 'hsl(0,100%,50%)'}); // rouge
             
            -

            Examinons l'ensemble des materials de Three.js

            +

            Examinons l'ensemble des matériaux de Three.js

            Le MeshBasicMaterial n'est pas affecté par la lumière. -Le MeshLambertMaterial calcul la lumière uniquement pour les sommets (vertices), par contre le MeshPhongMaterial, lui, calcule la lumière pour chaque pixel. Le MeshPhongMaterial prend en charge aussi les reflets spéculaires.

            +Le MeshLambertMaterial calcule la lumière sur chaque sommets (vertices) de l'objet, alors que MeshPhongMaterial calculera la lumière sur chaque pixel des faces de l'objet et prendra également en compte les reflets spéculaires.

            @@ -91,7 +89,7 @@

            Les Matériaux dans

            -
            modèles low-poly avec les mêmes materials
            +
            modèles low-poly avec les mêmes matériaux

            Le paramètre shininess du MeshPhongMaterial détermine la brillance de la surbrillance spéculaire. La valeur par défaut est 30.

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

            Les Matériaux dans

            Notez que définir la propriété émissive sur une couleur sur un MeshLambertMaterial ou un MeshPhongMaterial et régler la couleur sur noir -(et shininess à 0 pour phong) finit par ressembler au MeshBasicMaterial.

            +(et shininess à 0 pour Phong) finit par ressembler au MeshBasicMaterial.

            @@ -139,19 +137,19 @@

            Les Matériaux dans

            -

            Pourquoi avoir les 3, si MeshPhongMaterial peut faire les mêmes choses que MeshBasicMaterial et MeshLambertMaterial ? La raison est simple. Le materials le plus sophistiqué nécessite aussi plus de puissance de la part du GPU. Sur un GPU plus lent comme par exemple sur un téléphone mobile, vous souhaiterez peut-être réduire la puissance du GPU en utilisant l'un des materials les moins complexes. Il s'ensuit également que si vous n'avez pas besoin des fonctionnalités supplémentaires, utilisez le materials le plus simple. Si vous n'avez pas besoin de l'éclairage et de la surbrillance spéculaire, utilisez le MeshBasicMaterial.

            +

            Pourquoi Three.js propose trois matérieaux similaires si au final MeshPhongMaterial peut faire les mêmes choses que MeshBasicMaterial et MeshLambertMaterial ? La raison est simple : le matériau le plus sophistiqué nécessite plus de puissance de la part du GPU. Sur un GPU plus lent comme sur un téléphone mobile, vous souhaitez peut-être améliorer les performances en utilisant un des matériaux moins gourmands calculs GPU. Il en découle que si vous n'avez pas besoin de fonctionnalités supplémentaires, alors il vaut mieux privilégier le matériau le plus simple. Si vous n'avez pas besoin d'éclairage et de la surbrillance spéculaire alors utilisez le MeshBasicMaterial.

            Le MeshToonMaterial est similaire au MeshPhongMaterial -avec une grande différence. Plutôt que d'ombrager en douceur, il utilise une carte de dégradé (une texture X par 1) pour décider comment ombrager. La valeur par défaut utilise une carte de dégradé dont la luminosité est de 70 % pour les premiers 70 % et 100 % après, mais vous pouvez fournir votre propre carte de dégradé. Cela finit par donner un look 2 tons qui ressemble à un dessin animé.

            +avec une grande différence : plutôt que d'ombrager en douceur, il utilise une carte de dégradé (une texture X par 1) pour décider comment ombrager. La valeur par défaut utilise une carte de dégradé dont la luminosité est de 70 % pour les premiers, puis entre 70 % et 100 % pour les suivants. Vous pouvez aussi fournir votre propre carte de dégradé. Cela peut même donner une allure de dessin animé (cartoon) sur deux teintes.

            -

            Ensuite, il y a 2 materials de rendu physique. Le rendu physique est souvent abrégé PBR.

            -

            Les materials ci-dessus utilisent des mathématiques simples pour créer des materials qui semblent 3D, mais ne réagissent pas comme dans le monde réel. Les 2 materials PBR utilisent des mathématiques beaucoup plus complexes pour se rapprocher de ce qui se passe réellement dans le monde réel.

            -

            Le premier est MeshStandardMaterial. La plus grande différence entre MeshPhongMaterial et MeshStandardMaterial est qu'il utilise des paramètres différents. -MeshPhongMaterial a un paramètre shininess. MeshStandardMaterial a 2 paramètres roughness (rugosité) et metalness (metalique).

            -

            Basiquement, roughness est l'opposé de shininess. -Quelque chose qui a une rugosité élevée, comme une balle de baseball, n'a pas de reflets durs alors que quelque chose qui n'est pas rugueux, comme une boule de billard, est très brillant. La rugosité va de 0 à 1.

            +

            Ensuite, il y a deux matériaux de rendu physique, souvent abrégé en PBR (Physics-Based Rendering material).

            +

            En effet, les matériaux vus précédemment utilisent des mathématiques simples pour créer des matériaux qui semblent 3D, mais ne réagissent pas comme dans le monde réel. Les deux matériaux PBR utilisent des mathématiques beaucoup plus complexes pour se rapprocher de ce qui se passe réellement dans le monde réel.

            +

            Le premier est MeshStandardMaterial. Il differt de MeshPhongMaterial et de MeshStandardMaterial en utilisant différents paramètres. +MeshPhongMaterial a un seul paramètre shininess alors que MeshStandardMaterial utilise deux paramètres roughness (rugosité) et metalness (métallique).

            +

            Pour faire simple, roughness est l'opposé de shininess. +Quelque chose qui a une rugosité élevée, comme une balle de baseball, n'a pas de reflets durs, alors que quelque chose qui n'est pas rugueux, comme une boule de billard, est très brillant. La rugosité varie de 0 à 1.

            L'autre paramètre, metalness, indique à quel point le matériau est métallique. Les métaux se comportent différemment des non-métaux. 0 pour le non-métal et 1 pour le métal.

            @@ -160,15 +158,17 @@

            Les Matériaux dans

            Le MeshPhysicalMaterial est le même que le MeshStandardMaterial mais il ajoute un paramètre clearcoat (vernis) qui va de 0 à 1 pour savoir quelle couche de brillance appliquée. Et un paramètre clearCoatRoughness qui spécifie à quel point la couche de brillance est rugueuse.

            -

            Voici la même grille que ci-dessusmais avec les paramètres clearcoat et clearCoatRoughness en plus.

            +

            Voici la même grille que ci-dessus, mais avec les paramètres clearcoat et clearCoatRoughness en plus.

            -

            Les divers matériaux standard progressent du plus rapide au plus lent +

            Voici la liste des divers matériaux standards rangés du plus rapide au plus lent : MeshBasicMaterialMeshLambertMaterialMeshPhongMaterial ➡ -MeshStandardMaterialMeshPhysicalMaterial. Les matériaux les plus lents peuvent créer des scènes plus réalistes, mais vous devrez peut-être concevoir votre code pour utiliser les matériaux les plus rapides sur des machines mobiles ou de faible puissance.

            -

            Il existe 3 matériaux qui ont des utilisations spéciales. ShadowMaterial -est utilisé pour obtenir les données créées à partir des ombres. Nous n'avons pas encore couvert les ombres. Lorsque nous le ferons, nous utiliserons ce materiau pour jeter un œil à ce qui se passe dans les coulisses.

            -

            The MeshDepthMaterial resttitue la profondeur de chaque pixel où les pixels +MeshStandardMaterialMeshPhysicalMaterial. Les matériaux les plus longs à calculer créent des scènes plus réalistes, mais vous devrez peut-être égallement concevoir votre code pour utiliser les matériaux plus rapides à calculer pour des machines mobiles ou de faible puissance.

            +

            Il existe trois matériaux qui ont des utilisations spéciales.

            + +

            ShadowMaterial +est utilisé pour obtenir les données créées à partir des ombres (sujet que nous n'avons pas encore couvert), mais nous l'utiliserons dans cet article traitant des ombres.

            +

            Le MeshDepthMaterial restitue la profondeur de chaque pixel où les pixels négatifs near sont à 0 et les négatifs far sont à 1. Certains effets spéciaux peuvent utiliser ces données que nous aborderons plus tard.

            @@ -177,12 +177,12 @@

            Les Matériaux dans

            -

            Le MeshNormalMaterial vous montrera les normals de la geéometrie. +

            Le MeshNormalMaterial vous montrera les normals de la géométrie. Les Normals sont la direction d'un triangle ou d'un pixel particulier. MeshNormalMaterial dessine les normales de l'espace de vue (les normales par rapport à la caméra).

            x rouge, y est vert, et -z est bleu donc les choses tournés vers la droite seront roses, +z est bleu donc les choses tournées vers la droite seront roses, ceux vers la gauche seront aqua, vers le haut vert clair, vers le bas violet, @@ -193,11 +193,11 @@

            Les Matériaux dans

            -

            ShaderMaterial permet de créer des matériaux personnalisés à l'aide du sytème de shader de Three.js. RawShaderMaterial permet de créer des shaders entièrement personnalisés sans l'aide de Three.js. Ces deux sujets sont vastes et seront traités plus tard.

            +

            ShaderMaterial permet de créer des matériaux personnalisés à l'aide du système de shader de Three.js. RawShaderMaterial permet de créer des shaders entièrement personnalisés sans l'aide de Three.js. Ces deux sujets sont vastes et seront traités plus tard.

            La plupart des matériaux partagent un ensemble de paramètres, tous définis par Material. -Voir la documentation pour chacun d'eux, mais passons en revue deux des propriétés les plus utilisées.

            +Voir la documentation pour chacun d'eux, mais passons, ici, en revue deux des propriétés les plus utilisées.

            flatShading: -si l'objet à l'air à facettes ou lisse. Par defaut = false.

            +si l'objet a l'air à facettes ou lisse. Par défaut = false.

            @@ -209,9 +209,9 @@

            Les Matériaux dans

            -

            side: quel côté montrer. La valeur par defaut est THREE.FrontSide. +

            side: quel côté montrer. La valeur par défaut est THREE.FrontSide. Les autres options sont THREE.BackSide et THREE.DoubleSide (des deux côtés). -La plupart des objets 3D déssinés dans Three.js sont probablement des solides opaques, il n'est donc pas nécessaire de dessiner les faces arrières (c'est-à-dire les côtés tournés vers l'intérieur du solide). La raison la plus courante de définir le côté, est pour les plans et les objets non solides où il est courant de voir leurs faces arrières.

            +La plupart des objets 3D dessinés dans Three.js sont probablement des solides opaques, il n'est donc pas nécessaire de dessiner les faces arrières (c'est-à-dire les côtés tournés vers l'intérieur du solide). La raison la plus courante de définir le côté, est pour les plans et les objets non solides où il est courant de voir leurs faces arrières.

            Voici 6 plans dessinés avec THREE.FrontSide et THREE.DoubleSide.

            @@ -224,13 +224,13 @@

            Les Matériaux dans

            -

            Il y a vraiment beaucoup de choses à considérer avec les matériaux et il nous en reste encore beaucoup à faire. En particulier, nous avons principalement ignoré les textures qui ouvrent toute une série d'options. Avant de couvrir les textures, nous devons faire une pause et couvrir la configuration de votre environnement de développement

            +

            Il y a vraiment beaucoup de choses à considérer avec les matériaux et il nous reste encore beaucoup à en dire. En particulier, nous avons jusqu'ici ignoré les textures, qui utilisent toute une série d'options. Avant de couvrir le domaine des textures, nous devons faire une pause et aborder la configuration de votre environnement de développement

            material.needsUpdate

            -Ce sujet affecte rarement la plupart des applications Three.js, mais juste pour info... -Three.js applique les paramètres de matériau lorsqu'un matériau est utilisé, où "utilisé" signifie "quelque chose est rendu qui utilise le matériau". -Certains paramètres de matériau ne sont appliqués qu'une seule fois car leur modification nécessite beaucoup de travail de la part de Three.js. +Ce sujet affecte rarement la plupart des applications Three.js, mais juste pour information +Three.js applique les paramètres de matériau lorsqu'un matériau est utilisé, où "utilisé" signifie "quelque chose est rendu qui utilise le matériau". +Certains paramètres de matériau ne sont appliqués qu'une seule fois, car leur modification nécessite beaucoup de travail de la part de Three.js. Dans ces cas, vous devez définir material.needsUpdate = true pour dire à Three.js d'appliquer vos modifications matérielles. Les paramètres les plus courants qui vous obligent à définir needsUpdate si vous modifiez les paramètres après avoir utilisé le matériau sont :

              @@ -253,11 +253,11 @@

              material.needsUpdate

            - - - + + + - \ No newline at end of file + diff --git a/manual/fr/multiple-scenes.html b/manual/fr/multiple-scenes.html index 48b0208a9d8e93..5015c3ac6916c8 100644 --- a/manual/fr/multiple-scenes.html +++ b/manual/fr/multiple-scenes.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Multiple Canvases Multiple Scenes

            - - + + diff --git a/manual/fr/offscreencanvas.html b/manual/fr/offscreencanvas.html index 124271c6540cf6..f5a774053143f2 100644 --- a/manual/fr/offscreencanvas.html +++ b/manual/fr/offscreencanvas.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            OffscreenCanvas

            - - + + diff --git a/manual/fr/optimize-lots-of-objects-animated.html b/manual/fr/optimize-lots-of-objects-animated.html index b2cea95c02e48d..2b3fa950f5d1d2 100644 --- a/manual/fr/optimize-lots-of-objects-animated.html +++ b/manual/fr/optimize-lots-of-objects-animated.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Optimize Lots of Objects Animated

            - - + + diff --git a/manual/fr/optimize-lots-of-objects.html b/manual/fr/optimize-lots-of-objects.html index dfccd6b46869b0..268d19aca329a5 100644 --- a/manual/fr/optimize-lots-of-objects.html +++ b/manual/fr/optimize-lots-of-objects.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Optimize Lots of Objects

            - - + + diff --git a/manual/fr/picking.html b/manual/fr/picking.html index 678a2d1b496f36..b7dd283c9292b2 100644 --- a/manual/fr/picking.html +++ b/manual/fr/picking.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Picking

            - - + + diff --git a/manual/fr/post-processing-3dlut.html b/manual/fr/post-processing-3dlut.html index b5949c95480713..a96b5960695de5 100644 --- a/manual/fr/post-processing-3dlut.html +++ b/manual/fr/post-processing-3dlut.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Post Processing 3DLUT

            - - + + diff --git a/manual/fr/post-processing.html b/manual/fr/post-processing.html index 4a9384953a5a1f..8c5123a7b5269c 100644 --- a/manual/fr/post-processing.html +++ b/manual/fr/post-processing.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Post Processing

            - - + + diff --git a/manual/fr/prerequisites.html b/manual/fr/prerequisites.html index 07485f1ab3150d..09167646d9650f 100644 --- a/manual/fr/prerequisites.html +++ b/manual/fr/prerequisites.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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';
             
             ...
             
            @@ -302,8 +302,8 @@ 

            - + + diff --git a/manual/fr/primitives.html b/manual/fr/primitives.html index 5f114c025c1615..9205ff31b3fc43 100644 --- a/manual/fr/primitives.html +++ b/manual/fr/primitives.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -363,8 +363,8 @@

            Primitives de

            - - + + diff --git a/manual/fr/rendering-on-demand.html b/manual/fr/rendering-on-demand.html index 5dc08f87c12a2e..d078bc34523c42 100644 --- a/manual/fr/rendering-on-demand.html +++ b/manual/fr/rendering-on-demand.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Rendering on Demand

            - - + + diff --git a/manual/fr/rendertargets.html b/manual/fr/rendertargets.html index 38c046259e3040..4c93cf4d17ddf2 100644 --- a/manual/fr/rendertargets.html +++ b/manual/fr/rendertargets.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -164,8 +164,8 @@

            Render Targets

            - - + + diff --git a/manual/fr/responsive.html b/manual/fr/responsive.html index cf5fd5db740f6a..9a9287af80366a 100644 --- a/manual/fr/responsive.html +++ b/manual/fr/responsive.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -280,8 +280,8 @@

            Gérer les affichages HD-DPI

            - - + + diff --git a/manual/fr/scenegraph.html b/manual/fr/scenegraph.html index 33f6155cff7b4b..401bf69e9dab61 100644 --- a/manual/fr/scenegraph.html +++ b/manual/fr/scenegraph.html @@ -1,16 +1,16 @@ - 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,20 +357,15 @@

            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/setup.html b/manual/fr/setup.html index 2ceccc912b10fc..20e24a775f1bb3 100644 --- a/manual/fr/setup.html +++ b/manual/fr/setup.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -73,8 +73,8 @@

            Configuration de

            - - + + diff --git a/manual/fr/shadertoy.html b/manual/fr/shadertoy.html index 2fa4cb08ab56d2..64df09069054b2 100644 --- a/manual/fr/shadertoy.html +++ b/manual/fr/shadertoy.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            and Shadertoy

            - - + + diff --git a/manual/fr/shadows.html b/manual/fr/shadows.html index 0a1477112116f1..89ac69a10fc16c 100644 --- a/manual/fr/shadows.html +++ b/manual/fr/shadows.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -371,8 +371,8 @@

            Les ombres dans

            - - + + diff --git a/manual/fr/textures.html b/manual/fr/textures.html index 7cb2eefbc1638f..4d90d5cd00ff83 100644 --- a/manual/fr/textures.html +++ b/manual/fr/textures.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -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 {
            @@ -465,8 +465,8 @@ 

            - + + diff --git a/manual/fr/tips.html b/manual/fr/tips.html index 8bd2e6766c5fe8..c1abd22dc58edc 100644 --- a/manual/fr/tips.html +++ b/manual/fr/tips.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Tips

            - - + + diff --git a/manual/fr/transparency.html b/manual/fr/transparency.html index 26913da7411179..07bc8f5a392126 100644 --- a/manual/fr/transparency.html +++ b/manual/fr/transparency.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Transparency

            - - + + diff --git a/manual/fr/voxel-geometry.html b/manual/fr/voxel-geometry.html index 869eb2e7edc0d9..3a896cf59d4448 100644 --- a/manual/fr/voxel-geometry.html +++ b/manual/fr/voxel-geometry.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            Voxel(Minecraft Like) Geometry

            - - + + diff --git a/manual/fr/webxr-basics.html b/manual/fr/webxr-basics.html new file mode 100644 index 00000000000000..32446e689f8e89 --- /dev/null +++ b/manual/fr/webxr-basics.html @@ -0,0 +1,46 @@ + + + VR + + + + + + + + + + + + + + + + + +
            +
            +

            VR

            +
            +
            +
            +

            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/webxr-look-to-select.html b/manual/fr/webxr-look-to-select.html index 956b4b496dce1f..a5481350750b10 100644 --- a/manual/fr/webxr-look-to-select.html +++ b/manual/fr/webxr-look-to-select.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            VR - Look to Select

            - - + + diff --git a/manual/fr/webxr-point-to-select.html b/manual/fr/webxr-point-to-select.html index fd6a5a4787a51f..87862cdb38416e 100644 --- a/manual/fr/webxr-point-to-select.html +++ b/manual/fr/webxr-point-to-select.html @@ -6,11 +6,11 @@ - - + + - - + + @@ -37,8 +37,8 @@

            VR - 3DOF Point to Select

            - - + + diff --git a/manual/fr/webxr.html b/manual/fr/webxr.html deleted file mode 100644 index fa69dfc27c378e..00000000000000 --- a/manual/fr/webxr.html +++ /dev/null @@ -1,46 +0,0 @@ - - - VR - - - - - - - - - - - - - - - - - -
            -
            -

            VR

            -
            -
            -
            -

            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/index.html b/manual/index.html index f0cfbdd2ae38a1..b6a0d110be9776 100644 --- a/manual/index.html +++ b/manual/index.html @@ -28,7 +28,7 @@

            three.js

            -
            +