├── .gitignore
├── LICENSE
├── README.md
├── images
├── 1.png
├── chrome_1.png
├── chrome_2.png
├── gon.png
├── ikea.png
├── sem.png
├── sig.png
├── vsc_1.png
└── vsc_2.png
├── index.html
├── libs
├── brotli
│ ├── BUILD
│ ├── LICENSE
│ ├── WORKSPACE
│ ├── decode.js
│ ├── decode.min.js
│ ├── decode_test.js
│ └── polyfill.js
└── three.js
│ ├── LICENSE
│ ├── README.md
│ ├── build
│ ├── three.js
│ ├── three.min.js
│ └── three.module.js
│ ├── extra
│ ├── GLTFLoader.js
│ ├── VRButton.js
│ ├── XRControllerModelFactory.js
│ ├── lines.js
│ └── lines
│ │ ├── Line2.js
│ │ ├── LineGeometry.js
│ │ ├── LineMaterial.js
│ │ ├── LineSegments2.js
│ │ ├── LineSegmentsGeometry.js
│ │ ├── Wireframe.js
│ │ └── WireframeGeometry2.js
│ ├── libs
│ ├── chevrotain.module.min.js
│ ├── dat.gui.module.js
│ ├── deflate.module.min.js
│ ├── gunzip.module.min.js
│ ├── inflate.module.min.js
│ ├── jszip.module.min.js
│ ├── meshopt_decoder.module.js
│ ├── mmdparser.module.js
│ ├── motion-controllers.module.js
│ ├── opentype.module.min.js
│ ├── stats.module.js
│ ├── tween.module.min.js
│ └── zstddec.module.js
│ ├── lines
│ ├── Line2.js
│ ├── LineGeometry.js
│ ├── LineMaterial.js
│ ├── LineSegments2.js
│ ├── LineSegmentsGeometry.js
│ ├── Wireframe.js
│ └── WireframeGeometry2.js
│ ├── loaders
│ ├── 3DMLoader.js
│ ├── 3MFLoader.js
│ ├── AMFLoader.js
│ ├── AssimpLoader.js
│ ├── BVHLoader.js
│ ├── BasisTextureLoader.js
│ ├── ColladaLoader.js
│ ├── DDSLoader.js
│ ├── DRACOLoader.js
│ ├── EXRLoader.js
│ ├── FBXLoader.js
│ ├── GCodeLoader.js
│ ├── GLTFLoader.js
│ ├── HDRCubeTextureLoader.js
│ ├── KMZLoader.js
│ ├── KTX2Loader.js
│ ├── KTXLoader.js
│ ├── LDrawLoader.js
│ ├── LUT3dlLoader.js
│ ├── LUTCubeLoader.js
│ ├── LWOLoader.js
│ ├── LottieLoader.js
│ ├── MD2Loader.js
│ ├── MDDLoader.js
│ ├── MMDLoader.js
│ ├── MTLLoader.js
│ ├── NRRDLoader.js
│ ├── NodeMaterialLoader.js
│ ├── OBJLoader.js
│ ├── OBJLoader2.js
│ ├── OBJLoader2Parallel.js
│ ├── PCDLoader.js
│ ├── PDBLoader.js
│ ├── PLYLoader.js
│ ├── PRWMLoader.js
│ ├── PVRLoader.js
│ ├── RGBELoader.js
│ ├── STLLoader.js
│ ├── SVGLoader.js
│ ├── TDSLoader.js
│ ├── TGALoader.js
│ ├── TTFLoader.js
│ ├── TiltLoader.js
│ ├── VOXLoader.js
│ ├── VRMLLoader.js
│ ├── VRMLoader.js
│ ├── VTKLoader.js
│ ├── XLoader.js
│ ├── XYZLoader.js
│ ├── lwo
│ │ ├── IFFParser.js
│ │ ├── LWO2Parser.js
│ │ └── LWO3Parser.js
│ └── obj2
│ │ ├── OBJLoader2Parser.js
│ │ ├── bridge
│ │ └── MtlObjBridge.js
│ │ ├── shared
│ │ ├── MaterialHandler.js
│ │ └── MeshReceiver.js
│ │ ├── utils
│ │ └── CodeSerializer.js
│ │ └── worker
│ │ ├── main
│ │ └── WorkerExecutionSupport.js
│ │ └── parallel
│ │ ├── OBJLoader2JsmWorker.js
│ │ └── WorkerRunner.js
│ └── webxr
│ ├── ARButton.js
│ ├── VRButton.js
│ ├── XRControllerModelFactory.js
│ ├── XRHandModelFactory.js
│ ├── XRHandOculusMeshModel.js
│ └── XRHandPrimitiveModel.js
├── small_garage.html
└── src
├── gaussian-utils
├── DecoderWorker.js
├── DecoderWorker_brotli.js
├── DecoderWorker_gaussian.js
├── WorkerPool.js
├── gaussian-attributes.js
├── gaussian-octree-loader.js
└── gaussian-octree.js
├── gl-matrix-min.js
├── indexedDB.js
├── lil-gui@0.18
├── localforage.min.js
├── main.js
├── main_old
├── main 0.js
├── main 1.js
├── main 2.js
└── main 3.js
├── potree.js
└── public.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .vscode/*
3 | model/*
4 | UNUSED/*
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Kevin Kwok
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LOD Web Viewer for LetsGo
2 |
3 | ## LetsGo: Large-Scale Garage Modeling and Rendering via LiDAR-Assisted Gaussian Primitives
4 |
6 |
7 | [Project page](https://zhaofuq.github.io/LetsGo/) | [Paper](https://arxiv.org/pdf/2404.09748) | [Video](https://www.youtube.com/watch?v=fs42UBKvGRw) | [LOD Viewer (SIBR)](https://zhaofuq.github.io/LetsGo/) | [Web Viewer](https://zhaofuq.github.io/LetsGo/)| [GarageWorld Dataset](https://zhaofuq.github.io/LetsGo/)
8 |
9 | We provide a web renderer to allow users to experience a scene with Level of Detail (LOD) Gaussian rendering. For users with a computer, the application can be run directly. However, for users with an iPad (preferably with an M- chip), you need to start the server on a computer and ensure that both the iPad and the computer are on the same local network to access it.
10 |
11 |
12 |
13 | ## Setup
14 |
15 | #### Install requirements (For mainstream computer OSs)
16 |
17 | - [**Chrome**](https://www.google.com/chrome/)
18 |
19 | - [**Visual Studio Code**](https://code.visualstudio.com/download) (to start the server)
20 | - And [**Live Server extension**](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)
21 |
22 | - Or
23 | - [**Node.js**](https://nodejs.org/en/download/package-manager) and [**NPM**](https://docs.npmjs.com/getting-started) (to start the server)
24 | - And [**Live server**](http://tapiov.net/live-server/)
25 |
26 |
27 | #### Install requirements (For iPadOS)
28 |
29 | - [**Chrome**](https://www.google.com/chrome/)
30 |
31 | #### Clone the repo
32 |
33 | Checkout this repository's main branch:
34 |
35 | ```sh
36 | ## through HTTPS
37 | git clone https://github.com/zhaofuq/LOD-Web-Viewer.git
38 | ## through SSH
39 | git clone git@github.com:zhaofuq/LOD-Web-Viewer.git
40 | ```
41 |
42 | #### Download the data
43 | Put [small garage sample data](https://drive.google.com/drive/folders/1WWHpzkRPYfVuqx9wP1wMpUM78LK3GlTk?usp=sharing) in `LOD-Web-Viewer`.
44 |
45 | ## To run an example
46 |
47 | #### Start with VSCode
48 |
49 | Use VSCode to open the folder:
50 |
51 | ```
52 | cd {your-folder}/LOD-web-viewer/
53 | code .
54 | ```
55 |
56 | Go Live,
57 |
58 |
59 |
60 |
61 |
62 | Then, open Chrome on the computer and visit the server, usually at `127.0.0.1:5500`.
63 |
64 | #### Start with NPM
65 |
66 | Run it in the terminal:
67 |
68 | ```
69 | your-name@your-computer:{your-folder}/LOD-web-viewer$ live-server
70 | Serving "{your-folder}/LOD-web-viewer" at http://127.0.0.1:8080
71 | ...
72 | ```
73 |
74 | Then, open Chrome on the computer and visit the server at `127.0.0.1:8080`.
75 |
76 | #### Visualization on computer
77 |
78 |
79 |
80 |
81 |
82 | It is recommended to use the `WASDQEIJKL` keys for moving the view horizontally,vertically, forward, backward, and side to side. Click on the webpage using your mouse or touchpad to refresh the view with more details.
83 |
84 | #### Visualization on iPad
85 |
86 | First, obtain your computer's IP address.
87 |
88 | Then, open Chrome on the iPad and visit the server at `192.168.xxx.xxx:{your-port}`.
89 |
90 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/images/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaofuq/LOD-Web-Viewer/6fedef1df59b808337738f875fdcba06d8ed7125/images/1.png
--------------------------------------------------------------------------------
/images/chrome_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaofuq/LOD-Web-Viewer/6fedef1df59b808337738f875fdcba06d8ed7125/images/chrome_1.png
--------------------------------------------------------------------------------
/images/chrome_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaofuq/LOD-Web-Viewer/6fedef1df59b808337738f875fdcba06d8ed7125/images/chrome_2.png
--------------------------------------------------------------------------------
/images/gon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaofuq/LOD-Web-Viewer/6fedef1df59b808337738f875fdcba06d8ed7125/images/gon.png
--------------------------------------------------------------------------------
/images/ikea.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaofuq/LOD-Web-Viewer/6fedef1df59b808337738f875fdcba06d8ed7125/images/ikea.png
--------------------------------------------------------------------------------
/images/sem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaofuq/LOD-Web-Viewer/6fedef1df59b808337738f875fdcba06d8ed7125/images/sem.png
--------------------------------------------------------------------------------
/images/sig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaofuq/LOD-Web-Viewer/6fedef1df59b808337738f875fdcba06d8ed7125/images/sig.png
--------------------------------------------------------------------------------
/images/vsc_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaofuq/LOD-Web-Viewer/6fedef1df59b808337738f875fdcba06d8ed7125/images/vsc_1.png
--------------------------------------------------------------------------------
/images/vsc_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaofuq/LOD-Web-Viewer/6fedef1df59b808337738f875fdcba06d8ed7125/images/vsc_2.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | LetsGo Viewer
8 |
101 |
102 |
103 |
104 |
105 |
LetsGo Viewer
106 | Large-Scale Garage Modeling and Rendering via LiDAR-Assisted Gaussian Primitives
107 |
108 |
109 |
110 |
Real-Time Level-of-detail Viewer Demos
111 |
124 |
125 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/libs/brotli/BUILD:
--------------------------------------------------------------------------------
1 | package(
2 | default_visibility = ["//visibility:public"],
3 | )
4 |
5 | licenses(["notice"]) # MIT
6 |
7 | load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library")
8 |
9 | # Not a real polyfill. Do NOT use for anything, but tests.
10 | closure_js_library(
11 | name = "polyfill",
12 | srcs = ["polyfill.js"],
13 | suppress = [
14 | "JSC_INVALID_OPERAND_TYPE",
15 | "JSC_MISSING_JSDOC",
16 | "JSC_STRICT_INEXISTENT_PROPERTY",
17 | "JSC_TYPE_MISMATCH",
18 | "JSC_UNKNOWN_EXPR_TYPE",
19 | ],
20 | )
21 |
22 | # Do NOT use this artifact; it is for test purposes only.
23 | closure_js_library(
24 | name = "decode",
25 | srcs = ["decode.js"],
26 | suppress = [
27 | "JSC_DUP_VAR_DECLARATION",
28 | "JSC_USELESS_BLOCK",
29 | ],
30 | deps = [":polyfill"],
31 | )
32 |
33 | load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_test")
34 |
35 | closure_js_test(
36 | name = "all_tests",
37 | srcs = ["decode_test.js"],
38 | deps = [
39 | ":decode",
40 | ":polyfill",
41 | "@io_bazel_rules_closure//closure/library:testing",
42 | ],
43 | )
44 |
--------------------------------------------------------------------------------
/libs/brotli/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/libs/brotli/WORKSPACE:
--------------------------------------------------------------------------------
1 | workspace(name = "org_brotli_js")
2 |
3 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
4 |
5 | git_repository(
6 | name = "io_bazel_rules_closure",
7 | commit = "29ec97e7c85d607ba9e41cab3993fbb13f812c4b",
8 | remote = "https://github.com/bazelbuild/rules_closure.git",
9 | )
10 |
11 | load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories")
12 | closure_repositories()
13 |
--------------------------------------------------------------------------------
/libs/brotli/decode_test.js:
--------------------------------------------------------------------------------
1 | goog.require('goog.testing.asserts');
2 | goog.require('goog.testing.jsunit');
3 |
4 | /**
5 | * @param {!Int8Array} bytes
6 | * @return {string}
7 | */
8 | function bytesToString(bytes) {
9 | return String.fromCharCode.apply(null, new Uint16Array(bytes));
10 | }
11 |
12 | function testMetadata() {
13 | assertEquals("", bytesToString(BrotliDecode(Int8Array.from([1, 11, 0, 42, 3]))));
14 | }
15 |
16 | function testEmpty() {
17 | assertEquals("", bytesToString(BrotliDecode(Int8Array.from([6]))));
18 | assertEquals("", bytesToString(BrotliDecode(Int8Array.from([0x81, 1]))));
19 | }
20 |
21 | function testBaseDictWord() {
22 | var input = Int8Array.from([
23 | 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe3, 0xb4, 0x0d, 0x00, 0x00,
24 | 0x07, 0x5b, 0x26, 0x31, 0x40, 0x02, 0x00, 0xe0, 0x4e, 0x1b, 0x41, 0x02
25 | ]);
26 | /** @type {!Int8Array} */
27 | var output = BrotliDecode(input);
28 | assertEquals("time", bytesToString(output));
29 | }
30 |
31 | function testBlockCountMessage() {
32 | var input = Int8Array.from([
33 | 0x1b, 0x0b, 0x00, 0x11, 0x01, 0x8c, 0xc1, 0xc5, 0x0d, 0x08, 0x00, 0x22,
34 | 0x65, 0xe1, 0xfc, 0xfd, 0x22, 0x2c, 0xc4, 0x00, 0x00, 0x38, 0xd8, 0x32,
35 | 0x89, 0x01, 0x12, 0x00, 0x00, 0x77, 0xda, 0x04, 0x10, 0x42, 0x00, 0x00, 0x00
36 | ]);
37 | /** @type {!Int8Array} */
38 | var output = BrotliDecode(input);
39 | assertEquals("aabbaaaaabab", bytesToString(output));
40 | }
41 |
42 | function testCompressedUncompressedShortCompressedSmallWindow() {
43 | var input = Int8Array.from([
44 | 0x21, 0xf4, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xa7, 0x6d, 0x00, 0x00,
45 | 0x38, 0xd8, 0x32, 0x89, 0x01, 0x12, 0x00, 0x00, 0x77, 0xda, 0x34, 0x7b,
46 | 0xdb, 0x50, 0x80, 0x02, 0x80, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x31,
47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x4e, 0xdb, 0x00, 0x00, 0x70, 0xb0,
48 | 0x65, 0x12, 0x03, 0x24, 0x00, 0x00, 0xee, 0xb4, 0x11, 0x24, 0x00
49 | ]);
50 | /** @type {!Int8Array} */
51 | var output = BrotliDecode(input);
52 | assertEquals(
53 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
54 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
55 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
56 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
57 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
58 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
59 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
60 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
61 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
62 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
63 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
64 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
65 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
66 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
67 | "aaaaaaaaaaaaaabbbbbbbbbb", bytesToString(output));
68 | }
69 |
70 | function testIntactDistanceRingBuffer0() {
71 | var input = Int8Array.from([
72 | 0x1b, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe3, 0xb4, 0x0d, 0x00, 0x00,
73 | 0x07, 0x5b, 0x26, 0x31, 0x40, 0x02, 0x00, 0xe0, 0x4e, 0x1b, 0xa1, 0x80,
74 | 0x20, 0x00
75 | ]);
76 | /** @type {!Int8Array} */
77 | var output = BrotliDecode(input);
78 | assertEquals("himselfself", bytesToString(output));
79 | }
80 |
--------------------------------------------------------------------------------
/libs/brotli/polyfill.js:
--------------------------------------------------------------------------------
1 | if (!Int32Array.__proto__.from) {
2 | Object.defineProperty(Int32Array.__proto__, 'from', {
3 | value: function(obj) {
4 | obj = Object(obj);
5 | if (!obj['length']) {
6 | return new this(0);
7 | }
8 | var typed_array = new this(obj.length);
9 | for(var i = 0; i < typed_array.length; i++) {
10 | typed_array[i] = obj[i];
11 | }
12 | return typed_array;
13 | }
14 | });
15 | }
16 |
17 | if (!Array.prototype.copyWithin) {
18 | Array.prototype.copyWithin = function(target, start, end) {
19 | var O = Object(this);
20 | var len = O.length >>> 0;
21 | var to = target | 0;
22 | var from = start | 0;
23 | var count = Math.min(Math.min(end | 0, len) - from, len - to);
24 | var direction = 1;
25 | if (from < to && to < (from + count)) {
26 | direction = -1;
27 | from += count - 1;
28 | to += count - 1;
29 | }
30 | while (count > 0) {
31 | O[to] = O[from];
32 | from += direction;
33 | to += direction;
34 | count--;
35 | }
36 | return O;
37 | };
38 | }
39 |
40 | if (!Array.prototype.fill) {
41 | Object.defineProperty(Array.prototype, 'fill', {
42 | value: function(value, start, end) {
43 | end = end | 0;
44 | var O = Object(this);
45 | var k = start | 0;
46 | while (k < end) {
47 | O[k] = value;
48 | k++;
49 | }
50 | return O;
51 | }
52 | });
53 | }
54 |
55 | if (!Int8Array.prototype.copyWithin) {
56 | Int8Array.prototype.copyWithin = Array.prototype.copyWithin;
57 | }
58 |
59 | if (!Int8Array.prototype.fill) {
60 | Int8Array.prototype.fill = Array.prototype.fill;
61 | }
62 |
63 | if (!Int32Array.prototype.fill) {
64 | Int32Array.prototype.fill = Array.prototype.fill;
65 | }
66 |
--------------------------------------------------------------------------------
/libs/three.js/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright © 2010-2019 three.js authors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/libs/three.js/README.md:
--------------------------------------------------------------------------------
1 | three.js
2 | ========
3 |
4 | [![NPM package][npm]][npm-url]
5 | [![Build Size][build-size]][build-size-url]
6 | [![Build Status][build-status]][build-status-url]
7 | [![Dependencies][dependencies]][dependencies-url]
8 | [![Dev Dependencies][dev-dependencies]][dev-dependencies-url]
9 | [![Language Grade][lgtm]][lgtm-url]
10 |
11 | #### JavaScript 3D library ####
12 |
13 | The aim of the project is to create an easy to use, lightweight, 3D library with a default WebGL renderer. The library also provides Canvas 2D, SVG and CSS3D renderers in the examples.
14 |
15 | [Examples](http://threejs.org/examples/) —
16 | [Documentation](http://threejs.org/docs/) —
17 | [Wiki](https://github.com/mrdoob/three.js/wiki) —
18 | [Migrating](https://github.com/mrdoob/three.js/wiki/Migration-Guide) —
19 | [Questions](http://stackoverflow.com/questions/tagged/three.js) —
20 | [Forum](https://discourse.threejs.org/) —
21 | [Gitter](https://gitter.im/mrdoob/three.js) —
22 | [Slack](https://join.slack.com/t/threejs/shared_invite/enQtMzYxMzczODM2OTgxLTQ1YmY4YTQxOTFjNDAzYmQ4NjU2YzRhNzliY2RiNDEyYjU2MjhhODgyYWQ5Y2MyZTU3MWNkOGVmOGRhOTQzYTk)
23 |
24 | ### Usage ###
25 |
26 | Download the [minified library](http://threejs.org/build/three.min.js) and include it in your HTML, or install and import it as a [module](http://threejs.org/docs/#manual/introduction/Import-via-modules),
27 | Alternatively, see [how to build the library yourself](https://github.com/mrdoob/three.js/wiki/Build-instructions).
28 |
29 | ```html
30 |
31 | ```
32 |
33 | 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.
34 |
35 | ```javascript
36 | var camera, scene, renderer;
37 | var geometry, material, mesh;
38 |
39 | init();
40 | animate();
41 |
42 | function init() {
43 |
44 | camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
45 | camera.position.z = 1;
46 |
47 | scene = new THREE.Scene();
48 |
49 | geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
50 | material = new THREE.MeshNormalMaterial();
51 |
52 | mesh = new THREE.Mesh( geometry, material );
53 | scene.add( mesh );
54 |
55 | renderer = new THREE.WebGLRenderer( { antialias: true } );
56 | renderer.setSize( window.innerWidth, window.innerHeight );
57 | document.body.appendChild( renderer.domElement );
58 |
59 | }
60 |
61 | function animate() {
62 |
63 | requestAnimationFrame( animate );
64 |
65 | mesh.rotation.x += 0.01;
66 | mesh.rotation.y += 0.02;
67 |
68 | renderer.render( scene, camera );
69 |
70 | }
71 | ```
72 |
73 | If everything went well you should see [this](https://jsfiddle.net/f2Lommf5/).
74 |
75 | ### Change log ###
76 |
77 | [Releases](https://github.com/mrdoob/three.js/releases)
78 |
79 |
80 | [npm]: https://img.shields.io/npm/v/three.svg
81 | [npm-url]: https://www.npmjs.com/package/three
82 | [build-size]: https://badgen.net/bundlephobia/minzip/three
83 | [build-size-url]: https://bundlephobia.com/result?p=three
84 | [build-status]: https://travis-ci.org/mrdoob/three.js.svg?branch=dev
85 | [build-status-url]: https://travis-ci.org/mrdoob/three.js
86 | [dependencies]: https://img.shields.io/david/mrdoob/three.js.svg
87 | [dependencies-url]: https://david-dm.org/mrdoob/three.js
88 | [dev-dependencies]: https://img.shields.io/david/dev/mrdoob/three.js.svg
89 | [dev-dependencies-url]: https://david-dm.org/mrdoob/three.js#info=devDependencies
90 | [lgtm]: https://img.shields.io/lgtm/grade/javascript/g/mrdoob/three.js.svg?label=code%20quality
91 | [lgtm-url]: https://lgtm.com/projects/g/mrdoob/three.js/
92 |
--------------------------------------------------------------------------------
/libs/three.js/extra/VRButton.js:
--------------------------------------------------------------------------------
1 |
2 | // Adapted from three.js VRButton
3 |
4 |
5 | class VRButton {
6 |
7 | constructor(){
8 | this.onStartListeners = [];
9 | this.onEndListeners = [];
10 | this.element = null;
11 | }
12 |
13 | onStart(callback){
14 | this.onStartListeners.push(callback);
15 | }
16 |
17 | onEnd(callback){
18 | this.onEndListeners.push(callback);
19 | }
20 |
21 | static async createButton( renderer, options ) {
22 |
23 | if ( options ) {
24 |
25 | console.error( 'THREE.VRButton: The "options" parameter has been removed. Please set the reference space type via renderer.xr.setReferenceSpaceType() instead.' );
26 |
27 | }
28 |
29 | const button = new VRButton();
30 | const element = document.createElement( 'button' );
31 |
32 | button.element = element;
33 |
34 | function setEnter(){
35 | button.element.innerHTML = `
36 | ENTER
37 | VR
38 | `;
39 | }
40 |
41 | function setExit(){
42 | button.element.innerHTML = `
43 | EXIT
44 | VR
45 | `;
46 | }
47 |
48 | function showEnterVR( /*device*/ ) {
49 |
50 | let currentSession = null;
51 |
52 | function onSessionStarted( session ) {
53 |
54 | session.addEventListener( 'end', onSessionEnded );
55 |
56 | for(let listener of button.onStartListeners){
57 | listener();
58 | }
59 |
60 |
61 | renderer.xr.setSession( session );
62 | setExit();
63 |
64 | currentSession = session;
65 |
66 | }
67 |
68 | function onSessionEnded( /*event*/ ) {
69 |
70 | currentSession.removeEventListener( 'end', onSessionEnded );
71 |
72 | for(let listener of button.onEndListeners){
73 | listener();
74 | }
75 |
76 | setEnter();
77 |
78 | currentSession = null;
79 |
80 | }
81 |
82 | //
83 |
84 | button.element.style.display = '';
85 |
86 | button.element.style.cursor = 'pointer';
87 |
88 | setEnter();
89 |
90 | button.element.onmouseenter = function () {
91 |
92 | button.element.style.opacity = '1.0';
93 |
94 | };
95 |
96 | button.element.onmouseleave = function () {
97 |
98 | button.element.style.opacity = '0.7';
99 |
100 | };
101 |
102 | button.element.onclick = function () {
103 |
104 | if ( currentSession === null ) {
105 |
106 | // WebXR's requestReferenceSpace only works if the corresponding feature
107 | // was requested at session creation time. For simplicity, just ask for
108 | // the interesting ones as optional features, but be aware that the
109 | // requestReferenceSpace call will fail if it turns out to be unavailable.
110 | // ('local' is always available for immersive sessions and doesn't need to
111 | // be requested separately.)
112 |
113 | const sessionInit = { optionalFeatures: [ 'local-floor', 'bounded-floor', 'hand-tracking' ] };
114 | navigator.xr.requestSession( 'immersive-vr', sessionInit ).then( onSessionStarted );
115 |
116 | } else {
117 |
118 | currentSession.end();
119 |
120 | }
121 |
122 | };
123 |
124 | }
125 |
126 | function stylizeElement( element ) {
127 |
128 | element.style.position = 'absolute';
129 | element.style.bottom = '20px';
130 | element.style.padding = '12px 6px';
131 | element.style.border = '1px solid #fff';
132 | element.style.borderRadius = '4px';
133 | element.style.background = 'rgba(0,0,0,0.1)';
134 | element.style.color = '#fff';
135 | element.style.font = 'normal 13px sans-serif';
136 | element.style.textAlign = 'center';
137 | element.style.opacity = '0.7';
138 | element.style.outline = 'none';
139 | element.style.zIndex = '999';
140 |
141 | }
142 |
143 | if ( 'xr' in navigator ) {
144 |
145 | button.element.id = 'VRButton';
146 | button.element.style.display = 'none';
147 |
148 | stylizeElement( button.element );
149 |
150 | let supported = await navigator.xr.isSessionSupported( 'immersive-vr' );
151 |
152 | if(supported){
153 | showEnterVR();
154 |
155 | return button;
156 | }else{
157 | return null;
158 | }
159 |
160 | } else {
161 |
162 | if ( window.isSecureContext === false ) {
163 |
164 | console.log("WEBXR NEEDS HTTPS");
165 |
166 | } else {
167 |
168 | console.log("WEBXR not available");
169 |
170 | }
171 |
172 | return null;
173 |
174 |
175 |
176 | }
177 |
178 | }
179 |
180 | }
181 |
182 | export { VRButton };
183 |
--------------------------------------------------------------------------------
/libs/three.js/extra/lines/Line2.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author WestLangley / http://github.com/WestLangley
3 | *
4 | */
5 |
6 | THREE.Line2 = function ( geometry, material ) {
7 |
8 | THREE.LineSegments2.call( this );
9 |
10 | this.type = 'Line2';
11 |
12 | this.geometry = geometry !== undefined ? geometry : new THREE.LineGeometry();
13 | this.material = material !== undefined ? material : new THREE.LineMaterial( { color: Math.random() * 0xffffff } );
14 |
15 | };
16 |
17 | THREE.Line2.prototype = Object.assign( Object.create( THREE.LineSegments2.prototype ), {
18 |
19 | constructor: THREE.Line2,
20 |
21 | isLine2: true,
22 |
23 | copy: function ( /* source */ ) {
24 |
25 | // todo
26 |
27 | return this;
28 |
29 | }
30 |
31 | } );
32 |
--------------------------------------------------------------------------------
/libs/three.js/extra/lines/LineGeometry.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author WestLangley / http://github.com/WestLangley
3 | *
4 | */
5 |
6 | THREE.LineGeometry = function () {
7 |
8 | THREE.LineSegmentsGeometry.call( this );
9 |
10 | this.type = 'LineGeometry';
11 |
12 | };
13 |
14 | THREE.LineGeometry.prototype = Object.assign( Object.create( THREE.LineSegmentsGeometry.prototype ), {
15 |
16 | constructor: THREE.LineGeometry,
17 |
18 | isLineGeometry: true,
19 |
20 | setPositions: function ( array ) {
21 |
22 | // converts [ x1, y1, z1, x2, y2, z2, ... ] to pairs format
23 |
24 | var length = array.length - 3;
25 | var points = new Float32Array( 2 * length );
26 |
27 | for ( var i = 0; i < length; i += 3 ) {
28 |
29 | points[ 2 * i ] = array[ i ];
30 | points[ 2 * i + 1 ] = array[ i + 1 ];
31 | points[ 2 * i + 2 ] = array[ i + 2 ];
32 |
33 | points[ 2 * i + 3 ] = array[ i + 3 ];
34 | points[ 2 * i + 4 ] = array[ i + 4 ];
35 | points[ 2 * i + 5 ] = array[ i + 5 ];
36 |
37 | }
38 |
39 | THREE.LineSegmentsGeometry.prototype.setPositions.call( this, points );
40 |
41 | return this;
42 |
43 | },
44 |
45 | setColors: function ( array ) {
46 |
47 | // converts [ r1, g1, b1, r2, g2, b2, ... ] to pairs format
48 |
49 | var length = array.length - 3;
50 | var colors = new Float32Array( 2 * length );
51 |
52 | for ( var i = 0; i < length; i += 3 ) {
53 |
54 | colors[ 2 * i ] = array[ i ];
55 | colors[ 2 * i + 1 ] = array[ i + 1 ];
56 | colors[ 2 * i + 2 ] = array[ i + 2 ];
57 |
58 | colors[ 2 * i + 3 ] = array[ i + 3 ];
59 | colors[ 2 * i + 4 ] = array[ i + 4 ];
60 | colors[ 2 * i + 5 ] = array[ i + 5 ];
61 |
62 | }
63 |
64 | THREE.LineSegmentsGeometry.prototype.setColors.call( this, colors );
65 |
66 | return this;
67 |
68 | },
69 |
70 | fromLine: function ( line ) {
71 |
72 | var geometry = line.geometry;
73 |
74 | if ( geometry.isGeometry ) {
75 |
76 | this.setPositions( geometry.vertices );
77 |
78 | } else if ( geometry.isBufferGeometry ) {
79 |
80 | this.setPositions( geometry.position.array ); // assumes non-indexed
81 |
82 | }
83 |
84 | // set colors, maybe
85 |
86 | return this;
87 |
88 | },
89 |
90 | copy: function ( /* source */ ) {
91 |
92 | // todo
93 |
94 | return this;
95 |
96 | }
97 |
98 | } );
99 |
--------------------------------------------------------------------------------
/libs/three.js/extra/lines/LineSegments2.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author WestLangley / http://github.com/WestLangley
3 | *
4 | */
5 |
6 | THREE.LineSegments2 = function ( geometry, material ) {
7 |
8 | THREE.Mesh.call( this );
9 |
10 | this.type = 'LineSegments2';
11 |
12 | this.geometry = geometry !== undefined ? geometry : new THREE.LineSegmentsGeometry();
13 | this.material = material !== undefined ? material : new THREE.LineMaterial( { color: Math.random() * 0xffffff } );
14 |
15 | };
16 |
17 | THREE.LineSegments2.prototype = Object.assign( Object.create( THREE.Mesh.prototype ), {
18 |
19 | constructor: THREE.LineSegments2,
20 |
21 | isLineSegments2: true,
22 |
23 | computeLineDistances: ( function () { // for backwards-compatability, but could be a method of LineSegmentsGeometry...
24 |
25 | var start = new THREE.Vector3();
26 | var end = new THREE.Vector3();
27 |
28 | return function computeLineDistances() {
29 |
30 | var geometry = this.geometry;
31 |
32 | var instanceStart = geometry.attributes.instanceStart;
33 | var instanceEnd = geometry.attributes.instanceEnd;
34 | var lineDistances = new Float32Array( 2 * instanceStart.data.count );
35 |
36 | for ( var i = 0, j = 0, l = instanceStart.data.count; i < l; i ++, j += 2 ) {
37 |
38 | start.fromBufferAttribute( instanceStart, i );
39 | end.fromBufferAttribute( instanceEnd, i );
40 |
41 | lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
42 | lineDistances[ j + 1 ] = lineDistances[ j ] + start.distanceTo( end );
43 |
44 | }
45 |
46 | var instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
47 |
48 | geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
49 | geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
50 |
51 | return this;
52 |
53 | };
54 |
55 | }() ),
56 |
57 | copy: function ( /* source */ ) {
58 |
59 | // todo
60 |
61 | return this;
62 |
63 | }
64 |
65 | } );
66 |
--------------------------------------------------------------------------------
/libs/three.js/extra/lines/LineSegmentsGeometry.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author WestLangley / http://github.com/WestLangley
3 | *
4 | */
5 |
6 | THREE.LineSegmentsGeometry = function () {
7 |
8 | THREE.InstancedBufferGeometry.call( this );
9 |
10 | this.type = 'LineSegmentsGeometry';
11 |
12 | var positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
13 | var uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ];
14 | var index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
15 |
16 | this.setIndex( index );
17 | this.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
18 | this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
19 |
20 | };
21 |
22 | THREE.LineSegmentsGeometry.prototype = Object.assign( Object.create( THREE.InstancedBufferGeometry.prototype ), {
23 |
24 | constructor: THREE.LineSegmentsGeometry,
25 |
26 | isLineSegmentsGeometry: true,
27 |
28 | applyMatrix: function ( matrix ) {
29 |
30 | var start = this.attributes.instanceStart;
31 | var end = this.attributes.instanceEnd;
32 |
33 | if ( start !== undefined ) {
34 |
35 | matrix.applyToBufferAttribute( start );
36 |
37 | matrix.applyToBufferAttribute( end );
38 |
39 | start.data.needsUpdate = true;
40 |
41 | }
42 |
43 | if ( this.boundingBox !== null ) {
44 |
45 | this.computeBoundingBox();
46 |
47 | }
48 |
49 | if ( this.boundingSphere !== null ) {
50 |
51 | this.computeBoundingSphere();
52 |
53 | }
54 |
55 | return this;
56 |
57 | },
58 |
59 | setPositions: function ( array ) {
60 |
61 | var lineSegments;
62 |
63 | if ( array instanceof Float32Array ) {
64 |
65 | lineSegments = array;
66 |
67 | } else if ( Array.isArray( array ) ) {
68 |
69 | lineSegments = new Float32Array( array );
70 |
71 | }
72 |
73 | var instanceBuffer = new THREE.InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
74 |
75 | this.setAttribute( 'instanceStart', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz
76 | this.setAttribute( 'instanceEnd', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz
77 |
78 | //
79 |
80 | this.computeBoundingBox();
81 | this.computeBoundingSphere();
82 |
83 | return this;
84 |
85 | },
86 |
87 | setColors: function ( array ) {
88 |
89 | var colors;
90 |
91 | if ( array instanceof Float32Array ) {
92 |
93 | colors = array;
94 |
95 | } else if ( Array.isArray( array ) ) {
96 |
97 | colors = new Float32Array( array );
98 |
99 | }
100 |
101 | var instanceColorBuffer = new THREE.InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
102 |
103 | this.setAttribute( 'instanceColorStart', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb
104 | this.setAttribute( 'instanceColorEnd', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb
105 |
106 | return this;
107 |
108 | },
109 |
110 | fromWireframeGeometry: function ( geometry ) {
111 |
112 | this.setPositions( geometry.attributes.position.array );
113 |
114 | return this;
115 |
116 | },
117 |
118 | fromEdgesGeometry: function ( geometry ) {
119 |
120 | this.setPositions( geometry.attributes.position.array );
121 |
122 | return this;
123 |
124 | },
125 |
126 | fromMesh: function ( mesh ) {
127 |
128 | this.fromWireframeGeometry( new THREE.WireframeGeometry( mesh.geometry ) );
129 |
130 | // set colors, maybe
131 |
132 | return this;
133 |
134 | },
135 |
136 | fromLineSegements: function ( lineSegments ) {
137 |
138 | var geometry = lineSegments.geometry;
139 |
140 | if ( geometry.isGeometry ) {
141 |
142 | this.setPositions( geometry.vertices );
143 |
144 | } else if ( geometry.isBufferGeometry ) {
145 |
146 | this.setPositions( geometry.position.array ); // assumes non-indexed
147 |
148 | }
149 |
150 | // set colors, maybe
151 |
152 | return this;
153 |
154 | },
155 |
156 | computeBoundingBox: function () {
157 |
158 | var box = new THREE.Box3();
159 |
160 | return function computeBoundingBox() {
161 |
162 | if ( this.boundingBox === null ) {
163 |
164 | this.boundingBox = new THREE.Box3();
165 |
166 | }
167 |
168 | var start = this.attributes.instanceStart;
169 | var end = this.attributes.instanceEnd;
170 |
171 | if ( start !== undefined && end !== undefined ) {
172 |
173 | this.boundingBox.setFromBufferAttribute( start );
174 |
175 | box.setFromBufferAttribute( end );
176 |
177 | this.boundingBox.union( box );
178 |
179 | }
180 |
181 | };
182 |
183 | }(),
184 |
185 | computeBoundingSphere: function () {
186 |
187 | var vector = new THREE.Vector3();
188 |
189 | return function computeBoundingSphere() {
190 |
191 | if ( this.boundingSphere === null ) {
192 |
193 | this.boundingSphere = new THREE.Sphere();
194 |
195 | }
196 |
197 | if ( this.boundingBox === null ) {
198 |
199 | this.computeBoundingBox();
200 |
201 | }
202 |
203 | var start = this.attributes.instanceStart;
204 | var end = this.attributes.instanceEnd;
205 |
206 | if ( start !== undefined && end !== undefined ) {
207 |
208 | var center = this.boundingSphere.center;
209 |
210 | this.boundingBox.getCenter( center );
211 |
212 | var maxRadiusSq = 0;
213 |
214 | for ( var i = 0, il = start.count; i < il; i ++ ) {
215 |
216 | vector.fromBufferAttribute( start, i );
217 | maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
218 |
219 | vector.fromBufferAttribute( end, i );
220 | maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
221 |
222 | }
223 |
224 | this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
225 |
226 | if ( isNaN( this.boundingSphere.radius ) ) {
227 |
228 | console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
229 |
230 | }
231 |
232 | }
233 |
234 | };
235 |
236 | }(),
237 |
238 | toJSON: function () {
239 |
240 | // todo
241 |
242 | },
243 |
244 | clone: function () {
245 |
246 | // todo
247 |
248 | },
249 |
250 | copy: function ( /* source */ ) {
251 |
252 | // todo
253 |
254 | return this;
255 |
256 | }
257 |
258 | } );
259 |
--------------------------------------------------------------------------------
/libs/three.js/extra/lines/Wireframe.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author WestLangley / http://github.com/WestLangley
3 | *
4 | */
5 |
6 | THREE.Wireframe = function ( geometry, material ) {
7 |
8 | THREE.Mesh.call( this );
9 |
10 | this.type = 'Wireframe';
11 |
12 | this.geometry = geometry !== undefined ? geometry : new THREE.LineSegmentsGeometry();
13 | this.material = material !== undefined ? material : new THREE.LineMaterial( { color: Math.random() * 0xffffff } );
14 |
15 | };
16 |
17 | THREE.Wireframe.prototype = Object.assign( Object.create( THREE.Mesh.prototype ), {
18 |
19 | constructor: THREE.Wireframe,
20 |
21 | isWireframe: true,
22 |
23 | computeLineDistances: ( function () { // for backwards-compatability, but could be a method of LineSegmentsGeometry...
24 |
25 | var start = new THREE.Vector3();
26 | var end = new THREE.Vector3();
27 |
28 | return function computeLineDistances() {
29 |
30 | var geometry = this.geometry;
31 |
32 | var instanceStart = geometry.attributes.instanceStart;
33 | var instanceEnd = geometry.attributes.instanceEnd;
34 | var lineDistances = new Float32Array( 2 * instanceStart.data.count );
35 |
36 | for ( var i = 0, j = 0, l = instanceStart.data.count; i < l; i ++, j += 2 ) {
37 |
38 | start.fromBufferAttribute( instanceStart, i );
39 | end.fromBufferAttribute( instanceEnd, i );
40 |
41 | lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
42 | lineDistances[ j + 1 ] = lineDistances[ j ] + start.distanceTo( end );
43 |
44 | }
45 |
46 | var instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
47 |
48 | geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
49 | geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
50 |
51 | return this;
52 |
53 | };
54 |
55 | }() ),
56 |
57 | copy: function ( /* source */ ) {
58 |
59 | // todo
60 |
61 | return this;
62 |
63 | }
64 |
65 | } );
66 |
--------------------------------------------------------------------------------
/libs/three.js/extra/lines/WireframeGeometry2.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author WestLangley / http://github.com/WestLangley
3 | *
4 | */
5 |
6 | THREE.WireframeGeometry2 = function ( geometry ) {
7 |
8 | THREE.LineSegmentsGeometry.call( this );
9 |
10 | this.type = 'WireframeGeometry2';
11 |
12 | this.fromWireframeGeometry( new THREE.WireframeGeometry( geometry ) );
13 |
14 | // set colors, maybe
15 |
16 | };
17 |
18 | THREE.WireframeGeometry2.prototype = Object.assign( Object.create( THREE.LineSegmentsGeometry.prototype ), {
19 |
20 | constructor: THREE.WireframeGeometry2,
21 |
22 | isWireframeGeometry2: true,
23 |
24 | copy: function ( /* source */ ) {
25 |
26 | // todo
27 |
28 | return this;
29 |
30 | }
31 |
32 | } );
33 |
--------------------------------------------------------------------------------
/libs/three.js/libs/inflate.module.min.js:
--------------------------------------------------------------------------------
1 | /** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */var mod={}, l=void 0,aa=mod;function r(c,d){var a=c.split("."),b=aa;!(a[0]in b)&&b.execScript&&b.execScript("var "+a[0]);for(var e;a.length&&(e=a.shift());)!a.length&&d!==l?b[e]=d:b=b[e]?b[e]:b[e]={}};var t="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array&&"undefined"!==typeof DataView;function v(c){var d=c.length,a=0,b=Number.POSITIVE_INFINITY,e,f,g,h,k,m,n,p,s,x;for(p=0;pa&&(a=c[p]),c[p]>=1;x=g<<16|p;for(s=m;s>>=1;switch(c){case 0:var d=this.input,a=this.a,b=this.c,e=this.b,f=d.length,g=l,h=l,k=b.length,m=l;this.d=this.f=0;if(a+1>=f)throw Error("invalid uncompressed block header: LEN");g=d[a++]|d[a++]<<8;if(a+1>=f)throw Error("invalid uncompressed block header: NLEN");h=d[a++]|d[a++]<<8;if(g===~h)throw Error("invalid uncompressed block header: length verify");if(a+g>d.length)throw Error("input buffer is broken");switch(this.i){case A:for(;e+
4 | g>b.length;){m=k-e;g-=m;if(t)b.set(d.subarray(a,a+m),e),e+=m,a+=m;else for(;m--;)b[e++]=d[a++];this.b=e;b=this.e();e=this.b}break;case y:for(;e+g>b.length;)b=this.e({p:2});break;default:throw Error("invalid inflate mode");}if(t)b.set(d.subarray(a,a+g),e),e+=g,a+=g;else for(;g--;)b[e++]=d[a++];this.a=a;this.b=e;this.c=b;break;case 1:this.j(ba,ca);break;case 2:for(var n=C(this,5)+257,p=C(this,5)+1,s=C(this,4)+4,x=new (t?Uint8Array:Array)(D.length),S=l,T=l,U=l,u=l,M=l,F=l,z=l,q=l,V=l,q=0;q=P?8:255>=P?9:279>=P?7:8;var ba=v(O),Q=new (t?Uint8Array:Array)(30),R,ga;R=0;for(ga=Q.length;R=g)throw Error("input buffer is broken");a|=e[f++]<>>d;c.d=b-d;c.a=f;return h}
8 | function E(c,d){for(var a=c.f,b=c.d,e=c.input,f=c.a,g=e.length,h=d[0],k=d[1],m,n;b=g);)a|=e[f++]<>>16;if(n>b)throw Error("invalid code length: "+n);c.f=a>>n;c.d=b-n;c.a=f;return m&65535}
9 | w.prototype.j=function(c,d){var a=this.c,b=this.b;this.o=c;for(var e=a.length-258,f,g,h,k;256!==(f=E(this,c));)if(256>f)b>=e&&(this.b=b,a=this.e(),b=this.b),a[b++]=f;else{g=f-257;k=I[g];0=e&&(this.b=b,a=this.e(),b=this.b);for(;k--;)a[b]=a[b++-h]}for(;8<=this.d;)this.d-=8,this.a--;this.b=b};
10 | w.prototype.w=function(c,d){var a=this.c,b=this.b;this.o=c;for(var e=a.length,f,g,h,k;256!==(f=E(this,c));)if(256>f)b>=e&&(a=this.e(),e=a.length),a[b++]=f;else{g=f-257;k=I[g];0e&&(a=this.e(),e=a.length);for(;k--;)a[b]=a[b++-h]}for(;8<=this.d;)this.d-=8,this.a--;this.b=b};
11 | w.prototype.e=function(){var c=new (t?Uint8Array:Array)(this.b-32768),d=this.b-32768,a,b,e=this.c;if(t)c.set(e.subarray(32768,c.length));else{a=0;for(b=c.length;aa;++a)e[a]=e[d+a];this.b=32768;return e};
12 | w.prototype.z=function(c){var d,a=this.input.length/this.a+1|0,b,e,f,g=this.input,h=this.c;c&&("number"===typeof c.p&&(a=c.p),"number"===typeof c.u&&(a+=c.u));2>a?(b=(g.length-this.a)/this.o[2],f=258*(b/2)|0,e=fd&&(this.c.length=d),c=this.c);return this.buffer=c};function W(c,d){var a,b;this.input=c;this.a=0;if(d||!(d={}))d.index&&(this.a=d.index),d.verify&&(this.A=d.verify);a=c[this.a++];b=c[this.a++];switch(a&15){case ha:this.method=ha;break;default:throw Error("unsupported compression method");}if(0!==((a<<8)+b)%31)throw Error("invalid fcheck flag:"+((a<<8)+b)%31);if(b&32)throw Error("fdict flag is not supported");this.q=new w(c,{index:this.a,bufferSize:d.bufferSize,bufferType:d.bufferType,resize:d.resize})}
15 | W.prototype.k=function(){var c=this.input,d,a;d=this.q.k();this.a=this.q.a;if(this.A){a=(c[this.a++]<<24|c[this.a++]<<16|c[this.a++]<<8|c[this.a++])>>>0;var b=d;if("string"===typeof b){var e=b.split(""),f,g;f=0;for(g=e.length;f>>0;b=e}for(var h=1,k=0,m=b.length,n,p=0;0>>0)throw Error("invalid adler-32 checksum");}return d};var ha=8;r("Zlib.Inflate",W);r("Zlib.Inflate.prototype.decompress",W.prototype.k);var X={ADAPTIVE:B.s,BLOCK:B.t},Y,Z,$,ia;if(Object.keys)Y=Object.keys(X);else for(Z in Y=[],$=0,X)Y[$++]=Z;$=0;for(ia=Y.length;$= prevTime + 1000 ) {
74 |
75 | fpsPanel.update( ( frames * 1000 ) / ( time - prevTime ), 100 );
76 |
77 | prevTime = time;
78 | frames = 0;
79 |
80 | if ( memPanel ) {
81 |
82 | var memory = performance.memory;
83 | memPanel.update( memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576 );
84 |
85 | }
86 |
87 | }
88 |
89 | return time;
90 |
91 | },
92 |
93 | update: function () {
94 |
95 | beginTime = this.end();
96 |
97 | },
98 |
99 | // Backwards Compatibility
100 |
101 | domElement: container,
102 | setMode: showPanel
103 |
104 | };
105 |
106 | };
107 |
108 | Stats.Panel = function ( name, fg, bg ) {
109 |
110 | var min = Infinity, max = 0, round = Math.round;
111 | var PR = round( window.devicePixelRatio || 1 );
112 |
113 | var WIDTH = 80 * PR, HEIGHT = 48 * PR,
114 | TEXT_X = 3 * PR, TEXT_Y = 2 * PR,
115 | GRAPH_X = 3 * PR, GRAPH_Y = 15 * PR,
116 | GRAPH_WIDTH = 74 * PR, GRAPH_HEIGHT = 30 * PR;
117 |
118 | var canvas = document.createElement( 'canvas' );
119 | canvas.width = WIDTH;
120 | canvas.height = HEIGHT;
121 | canvas.style.cssText = 'width:80px;height:48px';
122 |
123 | var context = canvas.getContext( '2d' );
124 | context.font = 'bold ' + ( 9 * PR ) + 'px Helvetica,Arial,sans-serif';
125 | context.textBaseline = 'top';
126 |
127 | context.fillStyle = bg;
128 | context.fillRect( 0, 0, WIDTH, HEIGHT );
129 |
130 | context.fillStyle = fg;
131 | context.fillText( name, TEXT_X, TEXT_Y );
132 | context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT );
133 |
134 | context.fillStyle = bg;
135 | context.globalAlpha = 0.9;
136 | context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT );
137 |
138 | return {
139 |
140 | dom: canvas,
141 |
142 | update: function ( value, maxValue ) {
143 |
144 | min = Math.min( min, value );
145 | max = Math.max( max, value );
146 |
147 | context.fillStyle = bg;
148 | context.globalAlpha = 1;
149 | context.fillRect( 0, 0, WIDTH, GRAPH_Y );
150 | context.fillStyle = fg;
151 | context.fillText( round( value ) + ' ' + name + ' (' + round( min ) + '-' + round( max ) + ')', TEXT_X, TEXT_Y );
152 |
153 | context.drawImage( canvas, GRAPH_X + PR, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT, GRAPH_X, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT );
154 |
155 | context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, GRAPH_HEIGHT );
156 |
157 | context.fillStyle = bg;
158 | context.globalAlpha = 0.9;
159 | context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, round( ( 1 - ( value / maxValue ) ) * GRAPH_HEIGHT ) );
160 |
161 | }
162 |
163 | };
164 |
165 | };
166 |
167 | export default Stats;
168 |
--------------------------------------------------------------------------------
/libs/three.js/libs/tween.module.min.js:
--------------------------------------------------------------------------------
1 | // tween.js 17.3.5 - https://github.com/tweenjs/tween.js
2 | var _Group=function(){this._tweens={},this._tweensAddedDuringUpdate={}};_Group.prototype={getAll:function(){return Object.keys(this._tweens).map(function(t){return this._tweens[t]}.bind(this))},removeAll:function(){this._tweens={}},add:function(t){this._tweens[t.getId()]=t,this._tweensAddedDuringUpdate[t.getId()]=t},remove:function(t){delete this._tweens[t.getId()],delete this._tweensAddedDuringUpdate[t.getId()]},update:function(t,n){var e=Object.keys(this._tweens);if(0===e.length)return!1;for(t=void 0!==t?t:TWEEN.now();0 1 && end.z > 1;
142 | if ( isBehindCameraNear || isPastCameraFar ) {
143 |
144 | continue;
145 |
146 | }
147 |
148 | // screen space
149 | start.x *= resolution.x / 2;
150 | start.y *= resolution.y / 2;
151 |
152 | end.x *= resolution.x / 2;
153 | end.y *= resolution.y / 2;
154 |
155 | // create 2d segment
156 | line.start.copy( start );
157 | line.start.z = 0;
158 |
159 | line.end.copy( end );
160 | line.end.z = 0;
161 |
162 | // get closest point on ray to segment
163 | var param = line.closestPointToPointParameter( ssOrigin3, true );
164 | line.at( param, closestPoint );
165 |
166 | // check if the intersection point is within clip space
167 | var zPos = MathUtils.lerp( start.z, end.z, param );
168 | var isInClipSpace = zPos >= - 1 && zPos <= 1;
169 |
170 | var isInside = ssOrigin3.distanceTo( closestPoint ) < lineWidth * 0.5;
171 |
172 | if ( isInClipSpace && isInside ) {
173 |
174 | line.start.fromBufferAttribute( instanceStart, i );
175 | line.end.fromBufferAttribute( instanceEnd, i );
176 |
177 | line.start.applyMatrix4( matrixWorld );
178 | line.end.applyMatrix4( matrixWorld );
179 |
180 | var pointOnLine = new Vector3();
181 | var point = new Vector3();
182 |
183 | ray.distanceSqToSegment( line.start, line.end, point, pointOnLine );
184 |
185 | intersects.push( {
186 |
187 | point: point,
188 | pointOnLine: pointOnLine,
189 | distance: ray.origin.distanceTo( point ),
190 |
191 | object: this,
192 | face: null,
193 | faceIndex: i,
194 | uv: null,
195 | uv2: null,
196 |
197 | } );
198 |
199 | }
200 |
201 | }
202 |
203 | };
204 |
205 | }() )
206 |
207 | } );
208 |
209 | export { LineSegments2 };
210 |
--------------------------------------------------------------------------------
/libs/three.js/lines/LineSegmentsGeometry.js:
--------------------------------------------------------------------------------
1 | import {
2 | Box3,
3 | Float32BufferAttribute,
4 | InstancedBufferGeometry,
5 | InstancedInterleavedBuffer,
6 | InterleavedBufferAttribute,
7 | Sphere,
8 | Vector3,
9 | WireframeGeometry
10 | } from '../build/three.module.js';
11 |
12 | var LineSegmentsGeometry = function () {
13 |
14 | InstancedBufferGeometry.call( this );
15 |
16 | this.type = 'LineSegmentsGeometry';
17 |
18 | var positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
19 | var uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ];
20 | var index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
21 |
22 | this.setIndex( index );
23 | this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
24 | this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
25 |
26 | };
27 |
28 | LineSegmentsGeometry.prototype = Object.assign( Object.create( InstancedBufferGeometry.prototype ), {
29 |
30 | constructor: LineSegmentsGeometry,
31 |
32 | isLineSegmentsGeometry: true,
33 |
34 | applyMatrix4: function ( matrix ) {
35 |
36 | var start = this.attributes.instanceStart;
37 | var end = this.attributes.instanceEnd;
38 |
39 | if ( start !== undefined ) {
40 |
41 | start.applyMatrix4( matrix );
42 |
43 | end.applyMatrix4( matrix );
44 |
45 | start.needsUpdate = true;
46 |
47 | }
48 |
49 | if ( this.boundingBox !== null ) {
50 |
51 | this.computeBoundingBox();
52 |
53 | }
54 |
55 | if ( this.boundingSphere !== null ) {
56 |
57 | this.computeBoundingSphere();
58 |
59 | }
60 |
61 | return this;
62 |
63 | },
64 |
65 | setPositions: function ( array ) {
66 |
67 | var lineSegments;
68 |
69 | if ( array instanceof Float32Array ) {
70 |
71 | lineSegments = array;
72 |
73 | } else if ( Array.isArray( array ) ) {
74 |
75 | lineSegments = new Float32Array( array );
76 |
77 | }
78 |
79 | var instanceBuffer = new InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
80 |
81 | this.setAttribute( 'instanceStart', new InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz
82 | this.setAttribute( 'instanceEnd', new InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz
83 |
84 | //
85 |
86 | this.computeBoundingBox();
87 | this.computeBoundingSphere();
88 |
89 | return this;
90 |
91 | },
92 |
93 | setColors: function ( array ) {
94 |
95 | var colors;
96 |
97 | if ( array instanceof Float32Array ) {
98 |
99 | colors = array;
100 |
101 | } else if ( Array.isArray( array ) ) {
102 |
103 | colors = new Float32Array( array );
104 |
105 | }
106 |
107 | var instanceColorBuffer = new InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
108 |
109 | this.setAttribute( 'instanceColorStart', new InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb
110 | this.setAttribute( 'instanceColorEnd', new InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb
111 |
112 | return this;
113 |
114 | },
115 |
116 | fromWireframeGeometry: function ( geometry ) {
117 |
118 | this.setPositions( geometry.attributes.position.array );
119 |
120 | return this;
121 |
122 | },
123 |
124 | fromEdgesGeometry: function ( geometry ) {
125 |
126 | this.setPositions( geometry.attributes.position.array );
127 |
128 | return this;
129 |
130 | },
131 |
132 | fromMesh: function ( mesh ) {
133 |
134 | this.fromWireframeGeometry( new WireframeGeometry( mesh.geometry ) );
135 |
136 | // set colors, maybe
137 |
138 | return this;
139 |
140 | },
141 |
142 | fromLineSegments: function ( lineSegments ) {
143 |
144 | var geometry = lineSegments.geometry;
145 |
146 | if ( geometry.isGeometry ) {
147 |
148 | this.setPositions( geometry.vertices );
149 |
150 | } else if ( geometry.isBufferGeometry ) {
151 |
152 | this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
153 |
154 | }
155 |
156 | // set colors, maybe
157 |
158 | return this;
159 |
160 | },
161 |
162 | computeBoundingBox: function () {
163 |
164 | var box = new Box3();
165 |
166 | return function computeBoundingBox() {
167 |
168 | if ( this.boundingBox === null ) {
169 |
170 | this.boundingBox = new Box3();
171 |
172 | }
173 |
174 | var start = this.attributes.instanceStart;
175 | var end = this.attributes.instanceEnd;
176 |
177 | if ( start !== undefined && end !== undefined ) {
178 |
179 | this.boundingBox.setFromBufferAttribute( start );
180 |
181 | box.setFromBufferAttribute( end );
182 |
183 | this.boundingBox.union( box );
184 |
185 | }
186 |
187 | };
188 |
189 | }(),
190 |
191 | computeBoundingSphere: function () {
192 |
193 | var vector = new Vector3();
194 |
195 | return function computeBoundingSphere() {
196 |
197 | if ( this.boundingSphere === null ) {
198 |
199 | this.boundingSphere = new Sphere();
200 |
201 | }
202 |
203 | if ( this.boundingBox === null ) {
204 |
205 | this.computeBoundingBox();
206 |
207 | }
208 |
209 | var start = this.attributes.instanceStart;
210 | var end = this.attributes.instanceEnd;
211 |
212 | if ( start !== undefined && end !== undefined ) {
213 |
214 | var center = this.boundingSphere.center;
215 |
216 | this.boundingBox.getCenter( center );
217 |
218 | var maxRadiusSq = 0;
219 |
220 | for ( var i = 0, il = start.count; i < il; i ++ ) {
221 |
222 | vector.fromBufferAttribute( start, i );
223 | maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
224 |
225 | vector.fromBufferAttribute( end, i );
226 | maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
227 |
228 | }
229 |
230 | this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
231 |
232 | if ( isNaN( this.boundingSphere.radius ) ) {
233 |
234 | console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
235 |
236 | }
237 |
238 | }
239 |
240 | };
241 |
242 | }(),
243 |
244 | toJSON: function () {
245 |
246 | // todo
247 |
248 | },
249 |
250 | applyMatrix: function ( matrix ) {
251 |
252 | console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' );
253 |
254 | return this.applyMatrix4( matrix );
255 |
256 | }
257 |
258 | } );
259 |
260 | export { LineSegmentsGeometry };
261 |
--------------------------------------------------------------------------------
/libs/three.js/lines/Wireframe.js:
--------------------------------------------------------------------------------
1 | import {
2 | InstancedInterleavedBuffer,
3 | InterleavedBufferAttribute,
4 | Mesh,
5 | Vector3
6 | } from '../build/three.module.js';
7 | import { LineSegmentsGeometry } from '../lines/LineSegmentsGeometry.js';
8 | import { LineMaterial } from '../lines/LineMaterial.js';
9 |
10 | var Wireframe = function ( geometry, material ) {
11 |
12 | Mesh.call( this );
13 |
14 | this.type = 'Wireframe';
15 |
16 | this.geometry = geometry !== undefined ? geometry : new LineSegmentsGeometry();
17 | this.material = material !== undefined ? material : new LineMaterial( { color: Math.random() * 0xffffff } );
18 |
19 | };
20 |
21 | Wireframe.prototype = Object.assign( Object.create( Mesh.prototype ), {
22 |
23 | constructor: Wireframe,
24 |
25 | isWireframe: true,
26 |
27 | computeLineDistances: ( function () { // for backwards-compatability, but could be a method of LineSegmentsGeometry...
28 |
29 | var start = new Vector3();
30 | var end = new Vector3();
31 |
32 | return function computeLineDistances() {
33 |
34 | var geometry = this.geometry;
35 |
36 | var instanceStart = geometry.attributes.instanceStart;
37 | var instanceEnd = geometry.attributes.instanceEnd;
38 | var lineDistances = new Float32Array( 2 * instanceStart.data.count );
39 |
40 | for ( var i = 0, j = 0, l = instanceStart.data.count; i < l; i ++, j += 2 ) {
41 |
42 | start.fromBufferAttribute( instanceStart, i );
43 | end.fromBufferAttribute( instanceEnd, i );
44 |
45 | lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
46 | lineDistances[ j + 1 ] = lineDistances[ j ] + start.distanceTo( end );
47 |
48 | }
49 |
50 | var instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
51 |
52 | geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
53 | geometry.setAttribute( 'instanceDistanceEnd', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
54 |
55 | return this;
56 |
57 | };
58 |
59 | }() )
60 |
61 | } );
62 |
63 | export { Wireframe };
64 |
--------------------------------------------------------------------------------
/libs/three.js/lines/WireframeGeometry2.js:
--------------------------------------------------------------------------------
1 | import {
2 | WireframeGeometry
3 | } from '../build/three.module.js';
4 | import { LineSegmentsGeometry } from '../lines/LineSegmentsGeometry.js';
5 |
6 | var WireframeGeometry2 = function ( geometry ) {
7 |
8 | LineSegmentsGeometry.call( this );
9 |
10 | this.type = 'WireframeGeometry2';
11 |
12 | this.fromWireframeGeometry( new WireframeGeometry( geometry ) );
13 |
14 | // set colors, maybe
15 |
16 | };
17 |
18 | WireframeGeometry2.prototype = Object.assign( Object.create( LineSegmentsGeometry.prototype ), {
19 |
20 | constructor: WireframeGeometry2,
21 |
22 | isWireframeGeometry2: true
23 |
24 | } );
25 |
26 | export { WireframeGeometry2 };
27 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/DDSLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | CompressedTextureLoader,
3 | RGBAFormat,
4 | RGBA_S3TC_DXT3_Format,
5 | RGBA_S3TC_DXT5_Format,
6 | RGB_ETC1_Format,
7 | RGB_S3TC_DXT1_Format
8 | } from '../../../build/three.module.js';
9 |
10 | var DDSLoader = function ( manager ) {
11 |
12 | CompressedTextureLoader.call( this, manager );
13 |
14 | };
15 |
16 | DDSLoader.prototype = Object.assign( Object.create( CompressedTextureLoader.prototype ), {
17 |
18 | constructor: DDSLoader,
19 |
20 | parse: function ( buffer, loadMipmaps ) {
21 |
22 | var dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 };
23 |
24 | // Adapted from @toji's DDS utils
25 | // https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
26 |
27 | // All values and structures referenced from:
28 | // http://msdn.microsoft.com/en-us/library/bb943991.aspx/
29 |
30 | var DDS_MAGIC = 0x20534444;
31 |
32 | // var DDSD_CAPS = 0x1;
33 | // var DDSD_HEIGHT = 0x2;
34 | // var DDSD_WIDTH = 0x4;
35 | // var DDSD_PITCH = 0x8;
36 | // var DDSD_PIXELFORMAT = 0x1000;
37 | var DDSD_MIPMAPCOUNT = 0x20000;
38 | // var DDSD_LINEARSIZE = 0x80000;
39 | // var DDSD_DEPTH = 0x800000;
40 |
41 | // var DDSCAPS_COMPLEX = 0x8;
42 | // var DDSCAPS_MIPMAP = 0x400000;
43 | // var DDSCAPS_TEXTURE = 0x1000;
44 |
45 | var DDSCAPS2_CUBEMAP = 0x200;
46 | var DDSCAPS2_CUBEMAP_POSITIVEX = 0x400;
47 | var DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800;
48 | var DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000;
49 | var DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000;
50 | var DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000;
51 | var DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000;
52 | // var DDSCAPS2_VOLUME = 0x200000;
53 |
54 | // var DDPF_ALPHAPIXELS = 0x1;
55 | // var DDPF_ALPHA = 0x2;
56 | var DDPF_FOURCC = 0x4;
57 | // var DDPF_RGB = 0x40;
58 | // var DDPF_YUV = 0x200;
59 | // var DDPF_LUMINANCE = 0x20000;
60 |
61 | function fourCCToInt32( value ) {
62 |
63 | return value.charCodeAt( 0 ) +
64 | ( value.charCodeAt( 1 ) << 8 ) +
65 | ( value.charCodeAt( 2 ) << 16 ) +
66 | ( value.charCodeAt( 3 ) << 24 );
67 |
68 | }
69 |
70 | function int32ToFourCC( value ) {
71 |
72 | return String.fromCharCode(
73 | value & 0xff,
74 | ( value >> 8 ) & 0xff,
75 | ( value >> 16 ) & 0xff,
76 | ( value >> 24 ) & 0xff
77 | );
78 |
79 | }
80 |
81 | function loadARGBMip( buffer, dataOffset, width, height ) {
82 |
83 | var dataLength = width * height * 4;
84 | var srcBuffer = new Uint8Array( buffer, dataOffset, dataLength );
85 | var byteArray = new Uint8Array( dataLength );
86 | var dst = 0;
87 | var src = 0;
88 | for ( var y = 0; y < height; y ++ ) {
89 |
90 | for ( var x = 0; x < width; x ++ ) {
91 |
92 | var b = srcBuffer[ src ]; src ++;
93 | var g = srcBuffer[ src ]; src ++;
94 | var r = srcBuffer[ src ]; src ++;
95 | var a = srcBuffer[ src ]; src ++;
96 | byteArray[ dst ] = r; dst ++; //r
97 | byteArray[ dst ] = g; dst ++; //g
98 | byteArray[ dst ] = b; dst ++; //b
99 | byteArray[ dst ] = a; dst ++; //a
100 |
101 | }
102 |
103 | }
104 |
105 | return byteArray;
106 |
107 | }
108 |
109 | var FOURCC_DXT1 = fourCCToInt32( 'DXT1' );
110 | var FOURCC_DXT3 = fourCCToInt32( 'DXT3' );
111 | var FOURCC_DXT5 = fourCCToInt32( 'DXT5' );
112 | var FOURCC_ETC1 = fourCCToInt32( 'ETC1' );
113 |
114 | var headerLengthInt = 31; // The header length in 32 bit ints
115 |
116 | // Offsets into the header array
117 |
118 | var off_magic = 0;
119 |
120 | var off_size = 1;
121 | var off_flags = 2;
122 | var off_height = 3;
123 | var off_width = 4;
124 |
125 | var off_mipmapCount = 7;
126 |
127 | var off_pfFlags = 20;
128 | var off_pfFourCC = 21;
129 | var off_RGBBitCount = 22;
130 | var off_RBitMask = 23;
131 | var off_GBitMask = 24;
132 | var off_BBitMask = 25;
133 | var off_ABitMask = 26;
134 |
135 | // var off_caps = 27;
136 | var off_caps2 = 28;
137 | // var off_caps3 = 29;
138 | // var off_caps4 = 30;
139 |
140 | // Parse header
141 |
142 | var header = new Int32Array( buffer, 0, headerLengthInt );
143 |
144 | if ( header[ off_magic ] !== DDS_MAGIC ) {
145 |
146 | console.error( 'THREE.DDSLoader.parse: Invalid magic number in DDS header.' );
147 | return dds;
148 |
149 | }
150 |
151 | if ( ! header[ off_pfFlags ] & DDPF_FOURCC ) {
152 |
153 | console.error( 'THREE.DDSLoader.parse: Unsupported format, must contain a FourCC code.' );
154 | return dds;
155 |
156 | }
157 |
158 | var blockBytes;
159 |
160 | var fourCC = header[ off_pfFourCC ];
161 |
162 | var isRGBAUncompressed = false;
163 |
164 | switch ( fourCC ) {
165 |
166 | case FOURCC_DXT1:
167 |
168 | blockBytes = 8;
169 | dds.format = RGB_S3TC_DXT1_Format;
170 | break;
171 |
172 | case FOURCC_DXT3:
173 |
174 | blockBytes = 16;
175 | dds.format = RGBA_S3TC_DXT3_Format;
176 | break;
177 |
178 | case FOURCC_DXT5:
179 |
180 | blockBytes = 16;
181 | dds.format = RGBA_S3TC_DXT5_Format;
182 | break;
183 |
184 | case FOURCC_ETC1:
185 |
186 | blockBytes = 8;
187 | dds.format = RGB_ETC1_Format;
188 | break;
189 |
190 | default:
191 |
192 | if ( header[ off_RGBBitCount ] === 32
193 | && header[ off_RBitMask ] & 0xff0000
194 | && header[ off_GBitMask ] & 0xff00
195 | && header[ off_BBitMask ] & 0xff
196 | && header[ off_ABitMask ] & 0xff000000 ) {
197 |
198 | isRGBAUncompressed = true;
199 | blockBytes = 64;
200 | dds.format = RGBAFormat;
201 |
202 | } else {
203 |
204 | console.error( 'THREE.DDSLoader.parse: Unsupported FourCC code ', int32ToFourCC( fourCC ) );
205 | return dds;
206 |
207 | }
208 |
209 | }
210 |
211 | dds.mipmapCount = 1;
212 |
213 | if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) {
214 |
215 | dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] );
216 |
217 | }
218 |
219 | var caps2 = header[ off_caps2 ];
220 | dds.isCubemap = caps2 & DDSCAPS2_CUBEMAP ? true : false;
221 | if ( dds.isCubemap && (
222 | ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) ||
223 | ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) ||
224 | ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) ||
225 | ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) ||
226 | ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) ||
227 | ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ )
228 | ) ) {
229 |
230 | console.error( 'THREE.DDSLoader.parse: Incomplete cubemap faces' );
231 | return dds;
232 |
233 | }
234 |
235 | dds.width = header[ off_width ];
236 | dds.height = header[ off_height ];
237 |
238 | var dataOffset = header[ off_size ] + 4;
239 |
240 | // Extract mipmaps buffers
241 |
242 | var faces = dds.isCubemap ? 6 : 1;
243 |
244 | for ( var face = 0; face < faces; face ++ ) {
245 |
246 | var width = dds.width;
247 | var height = dds.height;
248 |
249 | for ( var i = 0; i < dds.mipmapCount; i ++ ) {
250 |
251 | if ( isRGBAUncompressed ) {
252 |
253 | var byteArray = loadARGBMip( buffer, dataOffset, width, height );
254 | var dataLength = byteArray.length;
255 |
256 | } else {
257 |
258 | var dataLength = Math.max( 4, width ) / 4 * Math.max( 4, height ) / 4 * blockBytes;
259 | var byteArray = new Uint8Array( buffer, dataOffset, dataLength );
260 |
261 | }
262 |
263 | var mipmap = { 'data': byteArray, 'width': width, 'height': height };
264 | dds.mipmaps.push( mipmap );
265 |
266 | dataOffset += dataLength;
267 |
268 | width = Math.max( width >> 1, 1 );
269 | height = Math.max( height >> 1, 1 );
270 |
271 | }
272 |
273 | }
274 |
275 | return dds;
276 |
277 | }
278 |
279 | } );
280 |
281 | export { DDSLoader };
282 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/GCodeLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | BufferGeometry,
3 | Euler,
4 | FileLoader,
5 | Float32BufferAttribute,
6 | Group,
7 | LineBasicMaterial,
8 | LineSegments,
9 | Loader
10 | } from '../../../build/three.module.js';
11 |
12 | /**
13 | * GCodeLoader is used to load gcode files usually used for 3D printing or CNC applications.
14 | *
15 | * Gcode files are composed by commands used by machines to create objects.
16 | *
17 | * @class GCodeLoader
18 | * @param {Manager} manager Loading manager.
19 | */
20 |
21 | var GCodeLoader = function ( manager ) {
22 |
23 | Loader.call( this, manager );
24 |
25 | this.splitLayer = false;
26 |
27 | };
28 |
29 | GCodeLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
30 |
31 | constructor: GCodeLoader,
32 |
33 | load: function ( url, onLoad, onProgress, onError ) {
34 |
35 | var scope = this;
36 |
37 | var loader = new FileLoader( scope.manager );
38 | loader.setPath( scope.path );
39 | loader.setRequestHeader( scope.requestHeader );
40 | loader.setWithCredentials( scope.withCredentials );
41 | loader.load( url, function ( text ) {
42 |
43 | try {
44 |
45 | onLoad( scope.parse( text ) );
46 |
47 | } catch ( e ) {
48 |
49 | if ( onError ) {
50 |
51 | onError( e );
52 |
53 | } else {
54 |
55 | console.error( e );
56 |
57 | }
58 |
59 | scope.manager.itemError( url );
60 |
61 | }
62 |
63 | }, onProgress, onError );
64 |
65 | },
66 |
67 | parse: function ( data ) {
68 |
69 | var state = { x: 0, y: 0, z: 0, e: 0, f: 0, extruding: false, relative: false };
70 | var layers = [];
71 |
72 | var currentLayer = undefined;
73 |
74 | var pathMaterial = new LineBasicMaterial( { color: 0xFF0000 } );
75 | pathMaterial.name = 'path';
76 |
77 | var extrudingMaterial = new LineBasicMaterial( { color: 0x00FF00 } );
78 | extrudingMaterial.name = 'extruded';
79 |
80 | function newLayer( line ) {
81 |
82 | currentLayer = { vertex: [], pathVertex: [], z: line.z };
83 | layers.push( currentLayer );
84 |
85 | }
86 |
87 | //Create lie segment between p1 and p2
88 | function addSegment( p1, p2 ) {
89 |
90 | if ( currentLayer === undefined ) {
91 |
92 | newLayer( p1 );
93 |
94 | }
95 |
96 | if ( line.extruding ) {
97 |
98 | currentLayer.vertex.push( p1.x, p1.y, p1.z );
99 | currentLayer.vertex.push( p2.x, p2.y, p2.z );
100 |
101 | } else {
102 |
103 | currentLayer.pathVertex.push( p1.x, p1.y, p1.z );
104 | currentLayer.pathVertex.push( p2.x, p2.y, p2.z );
105 |
106 | }
107 |
108 | }
109 |
110 | function delta( v1, v2 ) {
111 |
112 | return state.relative ? v2 : v2 - v1;
113 |
114 | }
115 |
116 | function absolute( v1, v2 ) {
117 |
118 | return state.relative ? v1 + v2 : v2;
119 |
120 | }
121 |
122 | var lines = data.replace( /;.+/g, '' ).split( '\n' );
123 |
124 | for ( var i = 0; i < lines.length; i ++ ) {
125 |
126 | var tokens = lines[ i ].split( ' ' );
127 | var cmd = tokens[ 0 ].toUpperCase();
128 |
129 | //Argumments
130 | var args = {};
131 | tokens.splice( 1 ).forEach( function ( token ) {
132 |
133 | if ( token[ 0 ] !== undefined ) {
134 |
135 | var key = token[ 0 ].toLowerCase();
136 | var value = parseFloat( token.substring( 1 ) );
137 | args[ key ] = value;
138 |
139 | }
140 |
141 | } );
142 |
143 | //Process commands
144 | //G0/G1 – Linear Movement
145 | if ( cmd === 'G0' || cmd === 'G1' ) {
146 |
147 | var line = {
148 | x: args.x !== undefined ? absolute( state.x, args.x ) : state.x,
149 | y: args.y !== undefined ? absolute( state.y, args.y ) : state.y,
150 | z: args.z !== undefined ? absolute( state.z, args.z ) : state.z,
151 | e: args.e !== undefined ? absolute( state.e, args.e ) : state.e,
152 | f: args.f !== undefined ? absolute( state.f, args.f ) : state.f,
153 | };
154 |
155 | //Layer change detection is or made by watching Z, it's made by watching when we extrude at a new Z position
156 | if ( delta( state.e, line.e ) > 0 ) {
157 |
158 | line.extruding = delta( state.e, line.e ) > 0;
159 |
160 | if ( currentLayer == undefined || line.z != currentLayer.z ) {
161 |
162 | newLayer( line );
163 |
164 | }
165 |
166 | }
167 |
168 | addSegment( state, line );
169 | state = line;
170 |
171 | } else if ( cmd === 'G2' || cmd === 'G3' ) {
172 |
173 | //G2/G3 - Arc Movement ( G2 clock wise and G3 counter clock wise )
174 | //console.warn( 'THREE.GCodeLoader: Arc command not supported' );
175 |
176 | } else if ( cmd === 'G90' ) {
177 |
178 | //G90: Set to Absolute Positioning
179 | state.relative = false;
180 |
181 | } else if ( cmd === 'G91' ) {
182 |
183 | //G91: Set to state.relative Positioning
184 | state.relative = true;
185 |
186 | } else if ( cmd === 'G92' ) {
187 |
188 | //G92: Set Position
189 | var line = state;
190 | line.x = args.x !== undefined ? args.x : line.x;
191 | line.y = args.y !== undefined ? args.y : line.y;
192 | line.z = args.z !== undefined ? args.z : line.z;
193 | line.e = args.e !== undefined ? args.e : line.e;
194 | state = line;
195 |
196 | } else {
197 |
198 | //console.warn( 'THREE.GCodeLoader: Command not supported:' + cmd );
199 |
200 | }
201 |
202 | }
203 |
204 | function addObject( vertex, extruding ) {
205 |
206 | var geometry = new BufferGeometry();
207 | geometry.setAttribute( 'position', new Float32BufferAttribute( vertex, 3 ) );
208 |
209 | var segments = new LineSegments( geometry, extruding ? extrudingMaterial : pathMaterial );
210 | segments.name = 'layer' + i;
211 | object.add( segments );
212 |
213 | }
214 |
215 | var object = new Group();
216 | object.name = 'gcode';
217 |
218 | if ( this.splitLayer ) {
219 |
220 | for ( var i = 0; i < layers.length; i ++ ) {
221 |
222 | var layer = layers[ i ];
223 | addObject( layer.vertex, true );
224 | addObject( layer.pathVertex, false );
225 |
226 | }
227 |
228 | } else {
229 |
230 | var vertex = [], pathVertex = [];
231 |
232 | for ( var i = 0; i < layers.length; i ++ ) {
233 |
234 | var layer = layers[ i ];
235 | var layerVertex = layer.vertex;
236 | var layerPathVertex = layer.pathVertex;
237 |
238 | for ( var j = 0; j < layerVertex.length; j ++ ) {
239 |
240 | vertex.push( layerVertex[ j ] );
241 |
242 | }
243 |
244 | for ( var j = 0; j < layerPathVertex.length; j ++ ) {
245 |
246 | pathVertex.push( layerPathVertex[ j ] );
247 |
248 | }
249 |
250 | }
251 |
252 | addObject( vertex, true );
253 | addObject( pathVertex, false );
254 |
255 | }
256 |
257 | object.quaternion.setFromEuler( new Euler( - Math.PI / 2, 0, 0 ) );
258 |
259 | return object;
260 |
261 | }
262 |
263 | } );
264 |
265 | export { GCodeLoader };
266 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/HDRCubeTextureLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | CubeTexture,
3 | DataTexture,
4 | FileLoader,
5 | FloatType,
6 | HalfFloatType,
7 | LinearEncoding,
8 | LinearFilter,
9 | Loader,
10 | NearestFilter,
11 | RGBAFormat,
12 | RGBEEncoding,
13 | RGBFormat,
14 | UnsignedByteType
15 | } from '../../../build/three.module.js';
16 | import { RGBELoader } from '../loaders/RGBELoader.js';
17 |
18 | var HDRCubeTextureLoader = function ( manager ) {
19 |
20 | Loader.call( this, manager );
21 |
22 | this.hdrLoader = new RGBELoader();
23 | this.type = UnsignedByteType;
24 |
25 | };
26 |
27 | HDRCubeTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
28 |
29 | constructor: HDRCubeTextureLoader,
30 |
31 | load: function ( urls, onLoad, onProgress, onError ) {
32 |
33 | if ( ! Array.isArray( urls ) ) {
34 |
35 | console.warn( 'THREE.HDRCubeTextureLoader signature has changed. Use .setDataType() instead.' );
36 |
37 | this.setDataType( urls );
38 |
39 | urls = onLoad;
40 | onLoad = onProgress;
41 | onProgress = onError;
42 | onError = arguments[ 4 ];
43 |
44 | }
45 |
46 | var texture = new CubeTexture();
47 |
48 | texture.type = this.type;
49 |
50 | switch ( texture.type ) {
51 |
52 | case UnsignedByteType:
53 |
54 | texture.encoding = RGBEEncoding;
55 | texture.format = RGBAFormat;
56 | texture.minFilter = NearestFilter;
57 | texture.magFilter = NearestFilter;
58 | texture.generateMipmaps = false;
59 | break;
60 |
61 | case FloatType:
62 |
63 | texture.encoding = LinearEncoding;
64 | texture.format = RGBFormat;
65 | texture.minFilter = LinearFilter;
66 | texture.magFilter = LinearFilter;
67 | texture.generateMipmaps = false;
68 | break;
69 |
70 | case HalfFloatType:
71 |
72 | texture.encoding = LinearEncoding;
73 | texture.format = RGBFormat;
74 | texture.minFilter = LinearFilter;
75 | texture.magFilter = LinearFilter;
76 | texture.generateMipmaps = false;
77 | break;
78 |
79 | }
80 |
81 | var scope = this;
82 |
83 | var loaded = 0;
84 |
85 | function loadHDRData( i, onLoad, onProgress, onError ) {
86 |
87 | new FileLoader( scope.manager )
88 | .setPath( scope.path )
89 | .setResponseType( 'arraybuffer' )
90 | .setWithCredentials( scope.withCredentials )
91 | .load( urls[ i ], function ( buffer ) {
92 |
93 | loaded ++;
94 |
95 | var texData = scope.hdrLoader.parse( buffer );
96 |
97 | if ( ! texData ) return;
98 |
99 | if ( texData.data !== undefined ) {
100 |
101 | var dataTexture = new DataTexture( texData.data, texData.width, texData.height );
102 |
103 | dataTexture.type = texture.type;
104 | dataTexture.encoding = texture.encoding;
105 | dataTexture.format = texture.format;
106 | dataTexture.minFilter = texture.minFilter;
107 | dataTexture.magFilter = texture.magFilter;
108 | dataTexture.generateMipmaps = texture.generateMipmaps;
109 |
110 | texture.images[ i ] = dataTexture;
111 |
112 | }
113 |
114 | if ( loaded === 6 ) {
115 |
116 | texture.needsUpdate = true;
117 | if ( onLoad ) onLoad( texture );
118 |
119 | }
120 |
121 | }, onProgress, onError );
122 |
123 | }
124 |
125 | for ( var i = 0; i < urls.length; i ++ ) {
126 |
127 | loadHDRData( i, onLoad, onProgress, onError );
128 |
129 | }
130 |
131 | return texture;
132 |
133 | },
134 |
135 | setDataType: function ( value ) {
136 |
137 | this.type = value;
138 | this.hdrLoader.setDataType( value );
139 |
140 | return this;
141 |
142 | }
143 |
144 | } );
145 |
146 | export { HDRCubeTextureLoader };
147 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/KMZLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | FileLoader,
3 | Group,
4 | Loader,
5 | LoadingManager
6 | } from '../../../build/three.module.js';
7 | import { ColladaLoader } from '../loaders/ColladaLoader.js';
8 | import { JSZip } from '../libs/jszip.module.min.js';
9 |
10 | var KMZLoader = function ( manager ) {
11 |
12 | Loader.call( this, manager );
13 |
14 | };
15 |
16 | KMZLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
17 |
18 | constructor: KMZLoader,
19 |
20 | load: function ( url, onLoad, onProgress, onError ) {
21 |
22 | var scope = this;
23 |
24 | var loader = new FileLoader( scope.manager );
25 | loader.setPath( scope.path );
26 | loader.setResponseType( 'arraybuffer' );
27 | loader.setRequestHeader( scope.requestHeader );
28 | loader.setWithCredentials( scope.withCredentials );
29 | loader.load( url, function ( text ) {
30 |
31 | try {
32 |
33 | onLoad( scope.parse( text ) );
34 |
35 | } catch ( e ) {
36 |
37 | if ( onError ) {
38 |
39 | onError( e );
40 |
41 | } else {
42 |
43 | console.error( e );
44 |
45 | }
46 |
47 | scope.manager.itemError( url );
48 |
49 | }
50 |
51 | }, onProgress, onError );
52 |
53 | },
54 |
55 | parse: function ( data ) {
56 |
57 | function findFile( url ) {
58 |
59 | for ( var path in zip.files ) {
60 |
61 | if ( path.substr( - url.length ) === url ) {
62 |
63 | return zip.files[ path ];
64 |
65 | }
66 |
67 | }
68 |
69 | }
70 |
71 | var manager = new LoadingManager();
72 | manager.setURLModifier( function ( url ) {
73 |
74 | var image = findFile( url );
75 |
76 | if ( image ) {
77 |
78 | console.log( 'Loading', url );
79 |
80 | var blob = new Blob( [ image.asArrayBuffer() ], { type: 'application/octet-stream' } );
81 | return URL.createObjectURL( blob );
82 |
83 | }
84 |
85 | return url;
86 |
87 | } );
88 |
89 | //
90 |
91 | var zip = new JSZip( data ); // eslint-disable-line no-undef
92 |
93 | if ( zip.files[ 'doc.kml' ] ) {
94 |
95 | var xml = new DOMParser().parseFromString( zip.files[ 'doc.kml' ].asText(), 'application/xml' );
96 |
97 | var model = xml.querySelector( 'Placemark Model Link href' );
98 |
99 | if ( model ) {
100 |
101 | var loader = new ColladaLoader( manager );
102 | return loader.parse( zip.files[ model.textContent ].asText() );
103 |
104 | }
105 |
106 | } else {
107 |
108 | console.warn( 'KMZLoader: Missing doc.kml file.' );
109 |
110 | for ( var path in zip.files ) {
111 |
112 | var extension = path.split( '.' ).pop().toLowerCase();
113 |
114 | if ( extension === 'dae' ) {
115 |
116 | var loader = new ColladaLoader( manager );
117 | return loader.parse( zip.files[ path ].asText() );
118 |
119 | }
120 |
121 | }
122 |
123 | }
124 |
125 | console.error( 'KMZLoader: Couldn\'t find .dae file.' );
126 | return { scene: new Group() };
127 |
128 | }
129 |
130 | } );
131 |
132 | export { KMZLoader };
133 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/KTXLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | CompressedTextureLoader
3 | } from '../../../build/three.module.js';
4 |
5 | /**
6 | * for description see https://www.khronos.org/opengles/sdk/tools/KTX/
7 | * for file layout see https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
8 | *
9 | * ported from https://github.com/BabylonJS/Babylon.js/blob/master/src/Tools/babylon.khronosTextureContainer.ts
10 | */
11 |
12 |
13 | var KTXLoader = function ( manager ) {
14 |
15 | CompressedTextureLoader.call( this, manager );
16 |
17 | };
18 |
19 | KTXLoader.prototype = Object.assign( Object.create( CompressedTextureLoader.prototype ), {
20 |
21 | constructor: KTXLoader,
22 |
23 | parse: function ( buffer, loadMipmaps ) {
24 |
25 | var ktx = new KhronosTextureContainer( buffer, 1 );
26 |
27 | return {
28 | mipmaps: ktx.mipmaps( loadMipmaps ),
29 | width: ktx.pixelWidth,
30 | height: ktx.pixelHeight,
31 | format: ktx.glInternalFormat,
32 | isCubemap: ktx.numberOfFaces === 6,
33 | mipmapCount: ktx.numberOfMipmapLevels
34 | };
35 |
36 | }
37 |
38 | } );
39 |
40 | var KhronosTextureContainer = ( function () {
41 |
42 | /**
43 | * @param {ArrayBuffer} arrayBuffer- contents of the KTX container file
44 | * @param {number} facesExpected- should be either 1 or 6, based whether a cube texture or or
45 | * @param {boolean} threeDExpected- provision for indicating that data should be a 3D texture, not implemented
46 | * @param {boolean} textureArrayExpected- provision for indicating that data should be a texture array, not implemented
47 | */
48 | function KhronosTextureContainer( arrayBuffer, facesExpected /*, threeDExpected, textureArrayExpected */ ) {
49 |
50 | this.arrayBuffer = arrayBuffer;
51 |
52 | // Test that it is a ktx formatted file, based on the first 12 bytes, character representation is:
53 | // '´', 'K', 'T', 'X', ' ', '1', '1', 'ª', '\r', '\n', '\x1A', '\n'
54 | // 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
55 | var identifier = new Uint8Array( this.arrayBuffer, 0, 12 );
56 | if ( identifier[ 0 ] !== 0xAB ||
57 | identifier[ 1 ] !== 0x4B ||
58 | identifier[ 2 ] !== 0x54 ||
59 | identifier[ 3 ] !== 0x58 ||
60 | identifier[ 4 ] !== 0x20 ||
61 | identifier[ 5 ] !== 0x31 ||
62 | identifier[ 6 ] !== 0x31 ||
63 | identifier[ 7 ] !== 0xBB ||
64 | identifier[ 8 ] !== 0x0D ||
65 | identifier[ 9 ] !== 0x0A ||
66 | identifier[ 10 ] !== 0x1A ||
67 | identifier[ 11 ] !== 0x0A ) {
68 |
69 | console.error( 'texture missing KTX identifier' );
70 | return;
71 |
72 | }
73 |
74 | // load the reset of the header in native 32 bit uint
75 | var dataSize = Uint32Array.BYTES_PER_ELEMENT;
76 | var headerDataView = new DataView( this.arrayBuffer, 12, 13 * dataSize );
77 | var endianness = headerDataView.getUint32( 0, true );
78 | var littleEndian = endianness === 0x04030201;
79 |
80 | this.glType = headerDataView.getUint32( 1 * dataSize, littleEndian ); // must be 0 for compressed textures
81 | this.glTypeSize = headerDataView.getUint32( 2 * dataSize, littleEndian ); // must be 1 for compressed textures
82 | this.glFormat = headerDataView.getUint32( 3 * dataSize, littleEndian ); // must be 0 for compressed textures
83 | this.glInternalFormat = headerDataView.getUint32( 4 * dataSize, littleEndian ); // the value of arg passed to gl.compressedTexImage2D(,,x,,,,)
84 | this.glBaseInternalFormat = headerDataView.getUint32( 5 * dataSize, littleEndian ); // specify GL_RGB, GL_RGBA, GL_ALPHA, etc (un-compressed only)
85 | this.pixelWidth = headerDataView.getUint32( 6 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage2D(,,,x,,,)
86 | this.pixelHeight = headerDataView.getUint32( 7 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage2D(,,,,x,,)
87 | this.pixelDepth = headerDataView.getUint32( 8 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage3D(,,,,,x,,)
88 | this.numberOfArrayElements = headerDataView.getUint32( 9 * dataSize, littleEndian ); // used for texture arrays
89 | this.numberOfFaces = headerDataView.getUint32( 10 * dataSize, littleEndian ); // used for cubemap textures, should either be 1 or 6
90 | this.numberOfMipmapLevels = headerDataView.getUint32( 11 * dataSize, littleEndian ); // number of levels; disregard possibility of 0 for compressed textures
91 | this.bytesOfKeyValueData = headerDataView.getUint32( 12 * dataSize, littleEndian ); // the amount of space after the header for meta-data
92 |
93 | // Make sure we have a compressed type. Not only reduces work, but probably better to let dev know they are not compressing.
94 | if ( this.glType !== 0 ) {
95 |
96 | console.warn( 'only compressed formats currently supported' );
97 | return;
98 |
99 | } else {
100 |
101 | // value of zero is an indication to generate mipmaps @ runtime. Not usually allowed for compressed, so disregard.
102 | this.numberOfMipmapLevels = Math.max( 1, this.numberOfMipmapLevels );
103 |
104 | }
105 |
106 | if ( this.pixelHeight === 0 || this.pixelDepth !== 0 ) {
107 |
108 | console.warn( 'only 2D textures currently supported' );
109 | return;
110 |
111 | }
112 |
113 | if ( this.numberOfArrayElements !== 0 ) {
114 |
115 | console.warn( 'texture arrays not currently supported' );
116 | return;
117 |
118 | }
119 |
120 | if ( this.numberOfFaces !== facesExpected ) {
121 |
122 | console.warn( 'number of faces expected' + facesExpected + ', but found ' + this.numberOfFaces );
123 | return;
124 |
125 | }
126 |
127 | // we now have a completely validated file, so could use existence of loadType as success
128 | // would need to make this more elaborate & adjust checks above to support more than one load type
129 | this.loadType = KhronosTextureContainer.COMPRESSED_2D;
130 |
131 | }
132 |
133 | // return mipmaps for js
134 | KhronosTextureContainer.prototype.mipmaps = function ( loadMipmaps ) {
135 |
136 | var mipmaps = [];
137 |
138 | // initialize width & height for level 1
139 | var dataOffset = KhronosTextureContainer.HEADER_LEN + this.bytesOfKeyValueData;
140 | var width = this.pixelWidth;
141 | var height = this.pixelHeight;
142 | var mipmapCount = loadMipmaps ? this.numberOfMipmapLevels : 1;
143 |
144 | for ( var level = 0; level < mipmapCount; level ++ ) {
145 |
146 | var imageSize = new Int32Array( this.arrayBuffer, dataOffset, 1 )[ 0 ]; // size per face, since not supporting array cubemaps
147 | dataOffset += 4; // size of the image + 4 for the imageSize field
148 |
149 | for ( var face = 0; face < this.numberOfFaces; face ++ ) {
150 |
151 | var byteArray = new Uint8Array( this.arrayBuffer, dataOffset, imageSize );
152 |
153 | mipmaps.push( { 'data': byteArray, 'width': width, 'height': height } );
154 |
155 | dataOffset += imageSize;
156 | dataOffset += 3 - ( ( imageSize + 3 ) % 4 ); // add padding for odd sized image
157 |
158 | }
159 |
160 | width = Math.max( 1.0, width * 0.5 );
161 | height = Math.max( 1.0, height * 0.5 );
162 |
163 | }
164 |
165 | return mipmaps;
166 |
167 | };
168 |
169 | KhronosTextureContainer.HEADER_LEN = 12 + ( 13 * 4 ); // identifier + header elements (not including key value meta-data pairs)
170 | // load types
171 | KhronosTextureContainer.COMPRESSED_2D = 0; // uses a gl.compressedTexImage2D()
172 | KhronosTextureContainer.COMPRESSED_3D = 1; // uses a gl.compressedTexImage3D()
173 | KhronosTextureContainer.TEX_2D = 2; // uses a gl.texImage2D()
174 | KhronosTextureContainer.TEX_3D = 3; // uses a gl.texImage3D()
175 |
176 | return KhronosTextureContainer;
177 |
178 | }() );
179 |
180 | export { KTXLoader };
181 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/LUT3dlLoader.js:
--------------------------------------------------------------------------------
1 | // http://download.autodesk.com/us/systemdocs/help/2011/lustre/index.html?url=./files/WSc4e151a45a3b785a24c3d9a411df9298473-7ffd.htm,topicNumber=d0e9492
2 |
3 | import {
4 | Loader,
5 | FileLoader,
6 | DataTexture,
7 | DataTexture3D,
8 | RGBFormat,
9 | UnsignedByteType,
10 | ClampToEdgeWrapping,
11 | LinearFilter,
12 | } from '../../../build/three.module.js';
13 |
14 | export class LUT3dlLoader extends Loader {
15 |
16 | load( url, onLoad, onProgress, onError ) {
17 |
18 | const loader = new FileLoader( this.manager );
19 | loader.setPath( this.path );
20 | loader.setResponseType( 'text' );
21 | loader.load( url, text => {
22 |
23 | try {
24 |
25 | onLoad( this.parse( text ) );
26 |
27 | } catch ( e ) {
28 |
29 | if ( onError ) {
30 |
31 | onError( e );
32 |
33 | } else {
34 |
35 | console.error( e );
36 |
37 | }
38 |
39 | this.manager.itemError( url );
40 |
41 | }
42 |
43 | }, onProgress, onError );
44 |
45 | }
46 |
47 | parse( str ) {
48 |
49 | // remove empty lines and comment lints
50 | str = str
51 | .replace( /^#.*?(\n|\r)/gm, '' )
52 | .replace( /^\s*?(\n|\r)/gm, '' )
53 | .trim();
54 |
55 | const lines = str.split( /[\n\r]+/g );
56 |
57 | // first line is the positions on the grid that are provided by the LUT
58 | const gridLines = lines[ 0 ].trim().split( /\s+/g ).map( e => parseFloat( e ) );
59 | const gridStep = gridLines[ 1 ] - gridLines[ 0 ];
60 | const size = gridLines.length;
61 |
62 | for ( let i = 1, l = gridLines.length; i < l; i ++ ) {
63 |
64 | if ( gridStep !== ( gridLines[ i ] - gridLines[ i - 1 ] ) ) {
65 |
66 | throw new Error( 'LUT3dlLoader: Inconsistent grid size not supported.' );
67 |
68 | }
69 |
70 | }
71 |
72 | const dataArray = new Array( size * size * size * 3 );
73 | let index = 0;
74 | let maxOutputValue = 0.0;
75 | for ( let i = 1, l = lines.length; i < l; i ++ ) {
76 |
77 | const line = lines[ i ].trim();
78 | const split = line.split( /\s/g );
79 |
80 | const r = parseFloat( split[ 0 ] );
81 | const g = parseFloat( split[ 1 ] );
82 | const b = parseFloat( split[ 2 ] );
83 | maxOutputValue = Math.max( maxOutputValue, r, g, b );
84 |
85 | const bLayer = index % size;
86 | const gLayer = Math.floor( index / size ) % size;
87 | const rLayer = Math.floor( index / ( size * size ) ) % size;
88 |
89 | // b grows first, then g, then r
90 | const pixelIndex = bLayer * size * size + gLayer * size + rLayer;
91 | dataArray[ 3 * pixelIndex + 0 ] = r;
92 | dataArray[ 3 * pixelIndex + 1 ] = g;
93 | dataArray[ 3 * pixelIndex + 2 ] = b;
94 | index += 1;
95 |
96 | }
97 |
98 | // Find the apparent bit depth of the stored RGB values and scale the
99 | // values to [ 0, 255 ].
100 | const bits = Math.ceil( Math.log2( maxOutputValue ) );
101 | const maxBitValue = Math.pow( 2.0, bits );
102 | for ( let i = 0, l = dataArray.length; i < l; i ++ ) {
103 |
104 | const val = dataArray[ i ];
105 | dataArray[ i ] = 255 * val / maxBitValue;
106 |
107 | }
108 |
109 | const data = new Uint8Array( dataArray );
110 | const texture = new DataTexture();
111 | texture.image.data = data;
112 | texture.image.width = size;
113 | texture.image.height = size * size;
114 | texture.format = RGBFormat;
115 | texture.type = UnsignedByteType;
116 | texture.magFilter = LinearFilter;
117 | texture.wrapS = ClampToEdgeWrapping;
118 | texture.wrapT = ClampToEdgeWrapping;
119 | texture.generateMipmaps = false;
120 |
121 | const texture3D = new DataTexture3D();
122 | texture3D.image.data = data;
123 | texture3D.image.width = size;
124 | texture3D.image.height = size;
125 | texture3D.image.depth = size;
126 | texture3D.format = RGBFormat;
127 | texture3D.type = UnsignedByteType;
128 | texture3D.magFilter = LinearFilter;
129 | texture3D.wrapS = ClampToEdgeWrapping;
130 | texture3D.wrapT = ClampToEdgeWrapping;
131 | texture3D.wrapR = ClampToEdgeWrapping;
132 | texture3D.generateMipmaps = false;
133 |
134 | return {
135 | size,
136 | texture,
137 | texture3D,
138 | };
139 |
140 | }
141 |
142 | }
143 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/LUTCubeLoader.js:
--------------------------------------------------------------------------------
1 | // https://wwwimages2.adobe.com/content/dam/acom/en/products/speedgrade/cc/pdfs/cube-lut-specification-1.0.pdf
2 |
3 | import {
4 | Loader,
5 | FileLoader,
6 | Vector3,
7 | DataTexture,
8 | DataTexture3D,
9 | RGBFormat,
10 | UnsignedByteType,
11 | ClampToEdgeWrapping,
12 | LinearFilter,
13 | } from '../../../build/three.module.js';
14 |
15 | export class LUTCubeLoader extends Loader {
16 |
17 | load( url, onLoad, onProgress, onError ) {
18 |
19 | const loader = new FileLoader( this.manager );
20 | loader.setPath( this.path );
21 | loader.setResponseType( 'text' );
22 | loader.load( url, text => {
23 |
24 | try {
25 |
26 | onLoad( this.parse( text ) );
27 |
28 | } catch ( e ) {
29 |
30 | if ( onError ) {
31 |
32 | onError( e );
33 |
34 | } else {
35 |
36 | console.error( e );
37 |
38 | }
39 |
40 | this.manager.itemError( url );
41 |
42 | }
43 |
44 | }, onProgress, onError );
45 |
46 | }
47 |
48 | parse( str ) {
49 |
50 | // Remove empty lines and comments
51 | str = str
52 | .replace( /^#.*?(\n|\r)/gm, '' )
53 | .replace( /^\s*?(\n|\r)/gm, '' )
54 | .trim();
55 |
56 | let title = null;
57 | let size = null;
58 | const domainMin = new Vector3( 0, 0, 0 );
59 | const domainMax = new Vector3( 1, 1, 1 );
60 |
61 | const lines = str.split( /[\n\r]+/g );
62 | let data = null;
63 |
64 | let currIndex = 0;
65 | for ( let i = 0, l = lines.length; i < l; i ++ ) {
66 |
67 | const line = lines[ i ].trim();
68 | const split = line.split( /\s/g );
69 |
70 | switch ( split[ 0 ] ) {
71 |
72 | case 'TITLE':
73 | title = line.substring( 7, line.length - 1 );
74 | break;
75 | case 'LUT_3D_SIZE':
76 | // TODO: A .CUBE LUT file specifies floating point values and could be represented with
77 | // more precision than can be captured with Uint8Array.
78 | const sizeToken = split[ 1 ];
79 | size = parseFloat( sizeToken );
80 | data = new Uint8Array( size * size * size * 3 );
81 | break;
82 | case 'DOMAIN_MIN':
83 | domainMin.x = parseFloat( split[ 1 ] );
84 | domainMin.y = parseFloat( split[ 2 ] );
85 | domainMin.z = parseFloat( split[ 3 ] );
86 | break;
87 | case 'DOMAIN_MAX':
88 | domainMax.x = parseFloat( split[ 1 ] );
89 | domainMax.y = parseFloat( split[ 2 ] );
90 | domainMax.z = parseFloat( split[ 3 ] );
91 | break;
92 | default:
93 | const r = parseFloat( split[ 0 ] );
94 | const g = parseFloat( split[ 1 ] );
95 | const b = parseFloat( split[ 2 ] );
96 |
97 | if (
98 | r > 1.0 || r < 0.0 ||
99 | g > 1.0 || g < 0.0 ||
100 | b > 1.0 || b < 0.0
101 | ) {
102 |
103 | throw new Error( 'LUTCubeLoader : Non normalized values not supported.' );
104 |
105 | }
106 |
107 | data[ currIndex + 0 ] = r * 255;
108 | data[ currIndex + 1 ] = g * 255;
109 | data[ currIndex + 2 ] = b * 255;
110 | currIndex += 3;
111 |
112 | }
113 |
114 | }
115 |
116 | const texture = new DataTexture();
117 | texture.image.data = data;
118 | texture.image.width = size;
119 | texture.image.height = size * size;
120 | texture.format = RGBFormat;
121 | texture.type = UnsignedByteType;
122 | texture.magFilter = LinearFilter;
123 | texture.wrapS = ClampToEdgeWrapping;
124 | texture.wrapT = ClampToEdgeWrapping;
125 | texture.generateMipmaps = false;
126 |
127 | const texture3D = new DataTexture3D();
128 | texture3D.image.data = data;
129 | texture3D.image.width = size;
130 | texture3D.image.height = size;
131 | texture3D.image.depth = size;
132 | texture3D.format = RGBFormat;
133 | texture3D.type = UnsignedByteType;
134 | texture3D.magFilter = LinearFilter;
135 | texture3D.wrapS = ClampToEdgeWrapping;
136 | texture3D.wrapT = ClampToEdgeWrapping;
137 | texture3D.wrapR = ClampToEdgeWrapping;
138 | texture3D.generateMipmaps = false;
139 |
140 | return {
141 | title,
142 | size,
143 | domainMin,
144 | domainMax,
145 | texture,
146 | texture3D,
147 | };
148 |
149 | }
150 |
151 | }
152 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/LottieLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | FileLoader,
3 | Loader,
4 | CanvasTexture,
5 | NearestFilter
6 | } from '../../../build/three.module.js';
7 |
8 | class LottieLoader extends Loader {
9 |
10 | setQuality( value ) {
11 |
12 | this._quality = value;
13 |
14 | }
15 |
16 | load( url, onLoad, onProgress, onError ) {
17 |
18 | const quality = this._quality || 1;
19 |
20 | const texture = new CanvasTexture();
21 | texture.minFilter = NearestFilter;
22 |
23 | const loader = new FileLoader( this.manager );
24 | loader.setPath( this.path );
25 | loader.setWithCredentials( this.withCredentials );
26 |
27 | loader.load( url, function ( text ) {
28 |
29 | const data = JSON.parse( text );
30 |
31 | // bodymoving uses container.offetWidth and offsetHeight
32 | // to define width/height
33 |
34 | const container = document.createElement( 'div' );
35 | container.style.width = data.w + 'px';
36 | container.style.height = data.h + 'px';
37 | document.body.appendChild( container );
38 |
39 | // eslint-disable-next-line no-undef
40 | const animation = bodymovin.loadAnimation( {
41 | container: container,
42 | animType: 'canvas',
43 | loop: true,
44 | autoplay: true,
45 | animationData: data,
46 | rendererSettings: { dpr: quality }
47 | } );
48 |
49 | texture.animation = animation;
50 | texture.image = animation.container;
51 |
52 | animation.addEventListener( 'enterFrame', function () {
53 |
54 | texture.needsUpdate = true;
55 |
56 | } );
57 |
58 | container.style.display = 'none';
59 |
60 | if ( onLoad !== undefined ) {
61 |
62 | onLoad( texture );
63 |
64 | }
65 |
66 | }, onProgress, onError );
67 |
68 | return texture;
69 |
70 | }
71 |
72 | }
73 |
74 | export { LottieLoader };
75 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/MDDLoader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * MDD is a special format that stores a position for every vertex in a model for every frame in an animation.
3 | * Similar to BVH, it can be used to transfer animation data between different 3D applications or engines.
4 | *
5 | * MDD stores its data in binary format (big endian) in the following way:
6 | *
7 | * number of frames (a single uint32)
8 | * number of vertices (a single uint32)
9 | * time values for each frame (sequence of float32)
10 | * vertex data for each frame (sequence of float32)
11 | */
12 |
13 | import {
14 | AnimationClip,
15 | BufferAttribute,
16 | FileLoader,
17 | Loader,
18 | NumberKeyframeTrack
19 | } from '../../../build/three.module.js';
20 |
21 | var MDDLoader = function ( manager ) {
22 |
23 | Loader.call( this, manager );
24 |
25 | };
26 |
27 | MDDLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
28 |
29 | constructor: MDDLoader,
30 |
31 | load: function ( url, onLoad, onProgress, onError ) {
32 |
33 | var scope = this;
34 |
35 | var loader = new FileLoader( this.manager );
36 | loader.setPath( this.path );
37 | loader.setResponseType( 'arraybuffer' );
38 | loader.load( url, function ( data ) {
39 |
40 | onLoad( scope.parse( data ) );
41 |
42 | }, onProgress, onError );
43 |
44 | },
45 |
46 | parse: function ( data ) {
47 |
48 | var view = new DataView( data );
49 |
50 | var totalFrames = view.getUint32( 0 );
51 | var totalPoints = view.getUint32( 4 );
52 |
53 | var offset = 8;
54 |
55 | // animation clip
56 |
57 | var times = new Float32Array( totalFrames );
58 | var values = new Float32Array( totalFrames * totalFrames ).fill( 0 );
59 |
60 | for ( var i = 0; i < totalFrames; i ++ ) {
61 |
62 | times[ i ] = view.getFloat32( offset ); offset += 4;
63 | values[ ( totalFrames * i ) + i ] = 1;
64 |
65 | }
66 |
67 | var track = new NumberKeyframeTrack( '.morphTargetInfluences', times, values );
68 | var clip = new AnimationClip( 'default', times[ times.length - 1 ], [ track ] );
69 |
70 | // morph targets
71 |
72 | var morphTargets = [];
73 |
74 | for ( var i = 0; i < totalFrames; i ++ ) {
75 |
76 | var morphTarget = new Float32Array( totalPoints * 3 );
77 |
78 | for ( var j = 0; j < totalPoints; j ++ ) {
79 |
80 | var stride = ( j * 3 );
81 |
82 | morphTarget[ stride + 0 ] = view.getFloat32( offset ); offset += 4; // x
83 | morphTarget[ stride + 1 ] = view.getFloat32( offset ); offset += 4; // y
84 | morphTarget[ stride + 2 ] = view.getFloat32( offset ); offset += 4; // z
85 |
86 | }
87 |
88 | var attribute = new BufferAttribute( morphTarget, 3 );
89 | attribute.name = 'morph_' + i;
90 |
91 | morphTargets.push( attribute );
92 |
93 | }
94 |
95 | return {
96 | morphTargets: morphTargets,
97 | clip: clip
98 | };
99 |
100 | }
101 |
102 | } );
103 |
104 | export { MDDLoader };
105 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/NodeMaterialLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | DefaultLoadingManager,
3 | FileLoader
4 | } from '../../../build/three.module.js';
5 |
6 | import * as Nodes from '../nodes/Nodes.js';
7 |
8 | var NodeMaterialLoader = function ( manager, library ) {
9 |
10 | this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
11 |
12 | this.nodes = {};
13 | this.materials = {};
14 | this.passes = {};
15 | this.names = {};
16 | this.library = library || {};
17 |
18 | };
19 |
20 | var NodeMaterialLoaderUtils = {
21 |
22 | replaceUUIDObject: function ( object, uuid, value, recursive ) {
23 |
24 | recursive = recursive !== undefined ? recursive : true;
25 |
26 | if ( typeof uuid === 'object' ) uuid = uuid.uuid;
27 |
28 | if ( typeof object === 'object' ) {
29 |
30 | var keys = Object.keys( object );
31 |
32 | for ( var i = 0; i < keys.length; i ++ ) {
33 |
34 | var key = keys[ i ];
35 |
36 | if ( recursive ) {
37 |
38 | object[ key ] = this.replaceUUIDObject( object[ key ], uuid, value );
39 |
40 | }
41 |
42 | if ( key === uuid ) {
43 |
44 | object[ uuid ] = object[ key ];
45 |
46 | delete object[ key ];
47 |
48 | }
49 |
50 | }
51 |
52 | }
53 |
54 | return object === uuid ? value : object;
55 |
56 | },
57 |
58 | replaceUUID: function ( json, uuid, value ) {
59 |
60 | this.replaceUUIDObject( json, uuid, value, false );
61 | this.replaceUUIDObject( json.nodes, uuid, value );
62 | this.replaceUUIDObject( json.materials, uuid, value );
63 | this.replaceUUIDObject( json.passes, uuid, value );
64 | this.replaceUUIDObject( json.library, uuid, value, false );
65 |
66 | return json;
67 |
68 | }
69 |
70 | };
71 |
72 | Object.assign( NodeMaterialLoader.prototype, {
73 |
74 | load: function ( url, onLoad, onProgress, onError ) {
75 |
76 | var scope = this;
77 |
78 | var loader = new FileLoader( scope.manager );
79 | loader.setPath( scope.path );
80 | loader.load( url, function ( text ) {
81 |
82 | onLoad( scope.parse( JSON.parse( text ) ) );
83 |
84 | }, onProgress, onError );
85 |
86 | return this;
87 |
88 | },
89 |
90 | setPath: function ( value ) {
91 |
92 | this.path = value;
93 | return this;
94 |
95 | },
96 |
97 | getObjectByName: function ( uuid ) {
98 |
99 | return this.names[ uuid ];
100 |
101 | },
102 |
103 | getObjectById: function ( uuid ) {
104 |
105 | return this.library[ uuid ] ||
106 | this.nodes[ uuid ] ||
107 | this.materials[ uuid ] ||
108 | this.passes[ uuid ] ||
109 | this.names[ uuid ];
110 |
111 | },
112 |
113 | getNode: function ( uuid ) {
114 |
115 | var object = this.getObjectById( uuid );
116 |
117 | if ( ! object ) {
118 |
119 | console.warn( 'Node "' + uuid + '" not found.' );
120 |
121 | }
122 |
123 | return object;
124 |
125 | },
126 |
127 | resolve: function ( json ) {
128 |
129 | switch ( typeof json ) {
130 |
131 | case 'boolean':
132 | case 'number':
133 |
134 | return json;
135 |
136 | case 'string':
137 |
138 | if ( /^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$/i.test( json ) || this.library[ json ] ) {
139 |
140 | return this.getNode( json );
141 |
142 | }
143 |
144 | return json;
145 |
146 | default:
147 |
148 | if ( Array.isArray( json ) ) {
149 |
150 | for ( var i = 0; i < json.length; i ++ ) {
151 |
152 | json[ i ] = this.resolve( json[ i ] );
153 |
154 | }
155 |
156 | } else {
157 |
158 | for ( var prop in json ) {
159 |
160 | if ( prop === 'uuid' ) continue;
161 |
162 | json[ prop ] = this.resolve( json[ prop ] );
163 |
164 | }
165 |
166 | }
167 |
168 | }
169 |
170 | return json;
171 |
172 | },
173 |
174 | declare: function ( json ) {
175 |
176 | var uuid, node, object;
177 |
178 | for ( uuid in json.nodes ) {
179 |
180 | node = json.nodes[ uuid ];
181 |
182 | object = new Nodes[ node.nodeType + 'Node' ]();
183 |
184 | if ( node.name ) {
185 |
186 | object.name = node.name;
187 |
188 | this.names[ object.name ] = object;
189 |
190 | }
191 |
192 | this.nodes[ uuid ] = object;
193 |
194 | }
195 |
196 | for ( uuid in json.materials ) {
197 |
198 | node = json.materials[ uuid ];
199 |
200 | object = new Nodes[ node.type ]();
201 |
202 | if ( node.name ) {
203 |
204 | object.name = node.name;
205 |
206 | this.names[ object.name ] = object;
207 |
208 | }
209 |
210 | this.materials[ uuid ] = object;
211 |
212 | }
213 |
214 | for ( uuid in json.passes ) {
215 |
216 | node = json.passes[ uuid ];
217 |
218 | object = new Nodes[ node.type ]();
219 |
220 | if ( node.name ) {
221 |
222 | object.name = node.name;
223 |
224 | this.names[ object.name ] = object;
225 |
226 | }
227 |
228 | this.passes[ uuid ] = object;
229 |
230 | }
231 |
232 | if ( json.material ) this.material = this.materials[ json.material ];
233 |
234 | if ( json.pass ) this.pass = this.passes[ json.pass ];
235 |
236 | return json;
237 |
238 | },
239 |
240 | parse: function ( json ) {
241 |
242 | var uuid;
243 |
244 | json = this.resolve( this.declare( json ) );
245 |
246 | for ( uuid in json.nodes ) {
247 |
248 | this.nodes[ uuid ].copy( json.nodes[ uuid ] );
249 |
250 | }
251 |
252 | for ( uuid in json.materials ) {
253 |
254 | this.materials[ uuid ].copy( json.materials[ uuid ] );
255 |
256 | }
257 |
258 | for ( uuid in json.passes ) {
259 |
260 | this.passes[ uuid ].copy( json.passes[ uuid ] );
261 |
262 | }
263 |
264 | return this.material || this.pass || this;
265 |
266 | }
267 |
268 | } );
269 |
270 | export { NodeMaterialLoader, NodeMaterialLoaderUtils };
271 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/OBJLoader2Parallel.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Development repository: https://github.com/kaisalmen/WWOBJLoader
3 | */
4 |
5 | // Imports only related to wrapper
6 | import {
7 | Object3D
8 | } from '../../../build/three.module.js';
9 | import {
10 | CodeBuilderInstructions,
11 | WorkerExecutionSupport
12 | } from './obj2/worker/main/WorkerExecutionSupport.js';
13 | import { CodeSerializer } from './obj2/utils/CodeSerializer.js';
14 | import { OBJLoader2 } from './OBJLoader2.js';
15 |
16 | // Imports only related to worker (when standard workers (modules aren't supported) are used)
17 | import { OBJLoader2Parser } from './obj2/OBJLoader2Parser.js';
18 | import {
19 | WorkerRunner,
20 | DefaultWorkerPayloadHandler,
21 | ObjectManipulator
22 | } from './obj2/worker/parallel/WorkerRunner.js';
23 |
24 |
25 | /**
26 | * Creates a new OBJLoader2Parallel. Use it to load OBJ data from files or to parse OBJ data from arraybuffer.
27 | * It extends {@link OBJLoader2} with the capability to run the parser in a web worker.
28 | *
29 | * @param [LoadingManager] manager The loadingManager for the loader to use. Default is {@link LoadingManager}
30 | * @constructor
31 | */
32 | const OBJLoader2Parallel = function ( manager ) {
33 |
34 | OBJLoader2.call( this, manager );
35 | this.preferJsmWorker = false;
36 | this.jsmWorkerUrl = null;
37 |
38 | this.executeParallel = true;
39 | this.workerExecutionSupport = new WorkerExecutionSupport();
40 |
41 | };
42 |
43 | OBJLoader2Parallel.OBJLOADER2_PARALLEL_VERSION = '3.2.0';
44 | console.info( 'Using OBJLoader2Parallel version: ' + OBJLoader2Parallel.OBJLOADER2_PARALLEL_VERSION );
45 | OBJLoader2Parallel.DEFAULT_JSM_WORKER_PATH = './jsm/loaders/obj2/worker/parallel/OBJLoader2JsmWorker.js';
46 |
47 | OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototype ), {
48 |
49 | constructor: OBJLoader2Parallel,
50 |
51 | /**
52 | * Execution of parse in parallel via Worker is default, but normal {OBJLoader2} parsing can be enforced via false here.
53 | *
54 | * @param {boolean} executeParallel True or False
55 | * @return {OBJLoader2Parallel}
56 | */
57 | setExecuteParallel: function ( executeParallel ) {
58 |
59 | this.executeParallel = executeParallel === true;
60 | return this;
61 |
62 | },
63 |
64 | /**
65 | * Set whether jsm modules in workers should be used. This requires browser support which is currently only experimental.
66 | * @param {boolean} preferJsmWorker True or False
67 | * @param {URL} jsmWorkerUrl Provide complete jsm worker URL otherwise relative path to this module may not be correct
68 | * @return {OBJLoader2Parallel}
69 | */
70 | setJsmWorker: function ( preferJsmWorker, jsmWorkerUrl ) {
71 |
72 | this.preferJsmWorker = preferJsmWorker === true;
73 |
74 | if ( jsmWorkerUrl === undefined || jsmWorkerUrl === null ) {
75 |
76 | throw 'The url to the jsm worker is not valid. Aborting...';
77 |
78 | }
79 |
80 | this.jsmWorkerUrl = jsmWorkerUrl;
81 |
82 | return this;
83 |
84 | },
85 |
86 | /**
87 | * Allow to get hold of {@link WorkerExecutionSupport} for configuration purposes.
88 | * @return {WorkerExecutionSupport}
89 | */
90 | getWorkerExecutionSupport: function () {
91 |
92 | return this.workerExecutionSupport;
93 |
94 | },
95 |
96 | /**
97 | * Provide instructions on what is to be contained in the worker.
98 | * @return {CodeBuilderInstructions}
99 | */
100 | buildWorkerCode: function () {
101 |
102 | const codeBuilderInstructions = new CodeBuilderInstructions( true, true, this.preferJsmWorker );
103 |
104 | if ( codeBuilderInstructions.isSupportsJsmWorker() ) {
105 |
106 | codeBuilderInstructions.setJsmWorkerUrl( this.jsmWorkerUrl );
107 |
108 | }
109 |
110 | if ( codeBuilderInstructions.isSupportsStandardWorker() ) {
111 |
112 | const objectManipulator = new ObjectManipulator();
113 | const defaultWorkerPayloadHandler = new DefaultWorkerPayloadHandler( this.parser );
114 | const workerRunner = new WorkerRunner( {} );
115 | codeBuilderInstructions.addCodeFragment( CodeSerializer.serializeClass( OBJLoader2Parser, this.parser ) );
116 | codeBuilderInstructions.addCodeFragment( CodeSerializer.serializeClass( ObjectManipulator, objectManipulator ) );
117 | codeBuilderInstructions.addCodeFragment( CodeSerializer.serializeClass( DefaultWorkerPayloadHandler, defaultWorkerPayloadHandler ) );
118 | codeBuilderInstructions.addCodeFragment( CodeSerializer.serializeClass( WorkerRunner, workerRunner ) );
119 |
120 | const startCode = 'new ' + workerRunner.constructor.name + '( new ' + defaultWorkerPayloadHandler.constructor.name + '( new ' + this.parser.constructor.name + '() ) );';
121 | codeBuilderInstructions.addStartCode( startCode );
122 |
123 | }
124 |
125 | return codeBuilderInstructions;
126 |
127 | },
128 |
129 | /**
130 | * See {@link OBJLoader2.load}
131 | */
132 | load: function ( content, onLoad, onFileLoadProgress, onError, onMeshAlter ) {
133 |
134 | const scope = this;
135 | function interceptOnLoad( object3d, message ) {
136 |
137 | if ( object3d.name === 'OBJLoader2ParallelDummy' ) {
138 |
139 | if ( scope.parser.logging.enabled && scope.parser.logging.debug ) {
140 |
141 | console.debug( 'Received dummy answer from OBJLoader2Parallel#parse' );
142 |
143 | }
144 |
145 | } else {
146 |
147 | onLoad( object3d, message );
148 |
149 | }
150 |
151 | }
152 |
153 | OBJLoader2.prototype.load.call( this, content, interceptOnLoad, onFileLoadProgress, onError, onMeshAlter );
154 |
155 | },
156 |
157 | /**
158 | * See {@link OBJLoader2.parse}
159 | * The callback onLoad needs to be set to be able to receive the content if used in parallel mode.
160 | * Fallback is possible via {@link OBJLoader2Parallel#setExecuteParallel}.
161 | */
162 | parse: function ( content ) {
163 |
164 | if ( this.executeParallel ) {
165 |
166 | if ( this.parser.callbacks.onLoad === this.parser._onLoad ) {
167 |
168 | throw 'No callback other than the default callback was provided! Aborting!';
169 |
170 | }
171 |
172 | // check if worker has been initialize before. If yes, skip init
173 | if ( ! this.workerExecutionSupport.isWorkerLoaded( this.preferJsmWorker ) ) {
174 |
175 | this.workerExecutionSupport.buildWorker( this.buildWorkerCode() );
176 |
177 | const scope = this;
178 | const scopedOnAssetAvailable = function ( payload ) {
179 |
180 | scope._onAssetAvailable( payload );
181 |
182 | };
183 |
184 | function scopedOnLoad( message ) {
185 |
186 | scope.parser.callbacks.onLoad( scope.baseObject3d, message );
187 |
188 | }
189 |
190 | this.workerExecutionSupport.updateCallbacks( scopedOnAssetAvailable, scopedOnLoad );
191 |
192 | }
193 |
194 | // Create default materials beforehand, but do not override previously set materials (e.g. during init)
195 | this.materialHandler.createDefaultMaterials( false );
196 |
197 | this.workerExecutionSupport.executeParallel(
198 | {
199 | params: {
200 | modelName: this.modelName,
201 | instanceNo: this.instanceNo,
202 | useIndices: this.parser.useIndices,
203 | disregardNormals: this.parser.disregardNormals,
204 | materialPerSmoothingGroup: this.parser.materialPerSmoothingGroup,
205 | useOAsMesh: this.parser.useOAsMesh,
206 | materials: this.materialHandler.getMaterialsJSON()
207 | },
208 | data: {
209 | input: content,
210 | options: null
211 | },
212 | logging: {
213 | enabled: this.parser.logging.enabled,
214 | debug: this.parser.logging.debug
215 | }
216 | } );
217 |
218 | const dummy = new Object3D();
219 | dummy.name = 'OBJLoader2ParallelDummy';
220 | return dummy;
221 |
222 | } else {
223 |
224 | return OBJLoader2.prototype.parse.call( this, content );
225 |
226 | }
227 |
228 | },
229 |
230 | } );
231 |
232 | export { OBJLoader2Parallel };
233 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/PDBLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | BufferGeometry,
3 | FileLoader,
4 | Float32BufferAttribute,
5 | Loader
6 | } from '../../../build/three.module.js';
7 |
8 | var PDBLoader = function ( manager ) {
9 |
10 | Loader.call( this, manager );
11 |
12 | };
13 |
14 | PDBLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
15 |
16 | constructor: PDBLoader,
17 |
18 | load: function ( url, onLoad, onProgress, onError ) {
19 |
20 | var scope = this;
21 |
22 | var loader = new FileLoader( scope.manager );
23 | loader.setPath( scope.path );
24 | loader.setRequestHeader( scope.requestHeader );
25 | loader.setWithCredentials( scope.withCredentials );
26 | loader.load( url, function ( text ) {
27 |
28 | try {
29 |
30 | onLoad( scope.parse( text ) );
31 |
32 | } catch ( e ) {
33 |
34 | if ( onError ) {
35 |
36 | onError( e );
37 |
38 | } else {
39 |
40 | console.error( e );
41 |
42 | }
43 |
44 | scope.manager.itemError( url );
45 |
46 | }
47 |
48 | }, onProgress, onError );
49 |
50 | },
51 |
52 | // Based on CanvasMol PDB parser
53 |
54 | parse: function ( text ) {
55 |
56 | function trim( text ) {
57 |
58 | return text.replace( /^\s\s*/, '' ).replace( /\s\s*$/, '' );
59 |
60 | }
61 |
62 | function capitalize( text ) {
63 |
64 | return text.charAt( 0 ).toUpperCase() + text.substr( 1 ).toLowerCase();
65 |
66 | }
67 |
68 | function hash( s, e ) {
69 |
70 | return 's' + Math.min( s, e ) + 'e' + Math.max( s, e );
71 |
72 | }
73 |
74 | function parseBond( start, length ) {
75 |
76 | var eatom = parseInt( lines[ i ].substr( start, length ) );
77 |
78 | if ( eatom ) {
79 |
80 | var h = hash( satom, eatom );
81 |
82 | if ( _bhash[ h ] === undefined ) {
83 |
84 | _bonds.push( [ satom - 1, eatom - 1, 1 ] );
85 | _bhash[ h ] = _bonds.length - 1;
86 |
87 | } else {
88 |
89 | // doesn't really work as almost all PDBs
90 | // have just normal bonds appearing multiple
91 | // times instead of being double/triple bonds
92 | // bonds[bhash[h]][2] += 1;
93 |
94 | }
95 |
96 | }
97 |
98 | }
99 |
100 | function buildGeometry() {
101 |
102 | var build = {
103 | geometryAtoms: new BufferGeometry(),
104 | geometryBonds: new BufferGeometry(),
105 | json: {
106 | atoms: atoms
107 | }
108 | };
109 |
110 | var geometryAtoms = build.geometryAtoms;
111 | var geometryBonds = build.geometryBonds;
112 |
113 | var i, l;
114 | var x, y, z;
115 |
116 | var verticesAtoms = [];
117 | var colorsAtoms = [];
118 | var verticesBonds = [];
119 |
120 | // atoms
121 |
122 | for ( i = 0, l = atoms.length; i < l; i ++ ) {
123 |
124 | var atom = atoms[ i ];
125 |
126 | x = atom[ 0 ];
127 | y = atom[ 1 ];
128 | z = atom[ 2 ];
129 |
130 | verticesAtoms.push( x, y, z );
131 |
132 | var r = atom[ 3 ][ 0 ] / 255;
133 | var g = atom[ 3 ][ 1 ] / 255;
134 | var b = atom[ 3 ][ 2 ] / 255;
135 |
136 | colorsAtoms.push( r, g, b );
137 |
138 | }
139 |
140 | // bonds
141 |
142 | for ( i = 0, l = _bonds.length; i < l; i ++ ) {
143 |
144 | var bond = _bonds[ i ];
145 |
146 | var start = bond[ 0 ];
147 | var end = bond[ 1 ];
148 |
149 | var startAtom = _atomMap[ start ];
150 | var endAtom = _atomMap[ end ];
151 |
152 | x = startAtom[ 0 ];
153 | y = startAtom[ 1 ];
154 | z = startAtom[ 2 ];
155 |
156 | verticesBonds.push( x, y, z );
157 |
158 | x = endAtom[ 0 ];
159 | y = endAtom[ 1 ];
160 | z = endAtom[ 2 ];
161 |
162 | verticesBonds.push( x, y, z );
163 |
164 | }
165 |
166 | // build geometry
167 |
168 | geometryAtoms.setAttribute( 'position', new Float32BufferAttribute( verticesAtoms, 3 ) );
169 | geometryAtoms.setAttribute( 'color', new Float32BufferAttribute( colorsAtoms, 3 ) );
170 |
171 | geometryBonds.setAttribute( 'position', new Float32BufferAttribute( verticesBonds, 3 ) );
172 |
173 | return build;
174 |
175 | }
176 |
177 | var CPK = { h: [ 255, 255, 255 ], he: [ 217, 255, 255 ], li: [ 204, 128, 255 ], be: [ 194, 255, 0 ], b: [ 255, 181, 181 ], c: [ 144, 144, 144 ], n: [ 48, 80, 248 ], o: [ 255, 13, 13 ], f: [ 144, 224, 80 ], ne: [ 179, 227, 245 ], na: [ 171, 92, 242 ], mg: [ 138, 255, 0 ], al: [ 191, 166, 166 ], si: [ 240, 200, 160 ], p: [ 255, 128, 0 ], s: [ 255, 255, 48 ], cl: [ 31, 240, 31 ], ar: [ 128, 209, 227 ], k: [ 143, 64, 212 ], ca: [ 61, 255, 0 ], sc: [ 230, 230, 230 ], ti: [ 191, 194, 199 ], v: [ 166, 166, 171 ], cr: [ 138, 153, 199 ], mn: [ 156, 122, 199 ], fe: [ 224, 102, 51 ], co: [ 240, 144, 160 ], ni: [ 80, 208, 80 ], cu: [ 200, 128, 51 ], zn: [ 125, 128, 176 ], ga: [ 194, 143, 143 ], ge: [ 102, 143, 143 ], as: [ 189, 128, 227 ], se: [ 255, 161, 0 ], br: [ 166, 41, 41 ], kr: [ 92, 184, 209 ], rb: [ 112, 46, 176 ], sr: [ 0, 255, 0 ], y: [ 148, 255, 255 ], zr: [ 148, 224, 224 ], nb: [ 115, 194, 201 ], mo: [ 84, 181, 181 ], tc: [ 59, 158, 158 ], ru: [ 36, 143, 143 ], rh: [ 10, 125, 140 ], pd: [ 0, 105, 133 ], ag: [ 192, 192, 192 ], cd: [ 255, 217, 143 ], in: [ 166, 117, 115 ], sn: [ 102, 128, 128 ], sb: [ 158, 99, 181 ], te: [ 212, 122, 0 ], i: [ 148, 0, 148 ], xe: [ 66, 158, 176 ], cs: [ 87, 23, 143 ], ba: [ 0, 201, 0 ], la: [ 112, 212, 255 ], ce: [ 255, 255, 199 ], pr: [ 217, 255, 199 ], nd: [ 199, 255, 199 ], pm: [ 163, 255, 199 ], sm: [ 143, 255, 199 ], eu: [ 97, 255, 199 ], gd: [ 69, 255, 199 ], tb: [ 48, 255, 199 ], dy: [ 31, 255, 199 ], ho: [ 0, 255, 156 ], er: [ 0, 230, 117 ], tm: [ 0, 212, 82 ], yb: [ 0, 191, 56 ], lu: [ 0, 171, 36 ], hf: [ 77, 194, 255 ], ta: [ 77, 166, 255 ], w: [ 33, 148, 214 ], re: [ 38, 125, 171 ], os: [ 38, 102, 150 ], ir: [ 23, 84, 135 ], pt: [ 208, 208, 224 ], au: [ 255, 209, 35 ], hg: [ 184, 184, 208 ], tl: [ 166, 84, 77 ], pb: [ 87, 89, 97 ], bi: [ 158, 79, 181 ], po: [ 171, 92, 0 ], at: [ 117, 79, 69 ], rn: [ 66, 130, 150 ], fr: [ 66, 0, 102 ], ra: [ 0, 125, 0 ], ac: [ 112, 171, 250 ], th: [ 0, 186, 255 ], pa: [ 0, 161, 255 ], u: [ 0, 143, 255 ], np: [ 0, 128, 255 ], pu: [ 0, 107, 255 ], am: [ 84, 92, 242 ], cm: [ 120, 92, 227 ], bk: [ 138, 79, 227 ], cf: [ 161, 54, 212 ], es: [ 179, 31, 212 ], fm: [ 179, 31, 186 ], md: [ 179, 13, 166 ], no: [ 189, 13, 135 ], lr: [ 199, 0, 102 ], rf: [ 204, 0, 89 ], db: [ 209, 0, 79 ], sg: [ 217, 0, 69 ], bh: [ 224, 0, 56 ], hs: [ 230, 0, 46 ], mt: [ 235, 0, 38 ], ds: [ 235, 0, 38 ], rg: [ 235, 0, 38 ], cn: [ 235, 0, 38 ], uut: [ 235, 0, 38 ], uuq: [ 235, 0, 38 ], uup: [ 235, 0, 38 ], uuh: [ 235, 0, 38 ], uus: [ 235, 0, 38 ], uuo: [ 235, 0, 38 ] };
178 |
179 | var atoms = [];
180 |
181 | var _bonds = [];
182 | var _bhash = {};
183 | var _atomMap = {};
184 |
185 | var x, y, z, index, e;
186 |
187 | // parse
188 |
189 | var lines = text.split( '\n' );
190 |
191 | for ( var i = 0, l = lines.length; i < l; i ++ ) {
192 |
193 | if ( lines[ i ].substr( 0, 4 ) === 'ATOM' || lines[ i ].substr( 0, 6 ) === 'HETATM' ) {
194 |
195 | x = parseFloat( lines[ i ].substr( 30, 7 ) );
196 | y = parseFloat( lines[ i ].substr( 38, 7 ) );
197 | z = parseFloat( lines[ i ].substr( 46, 7 ) );
198 | index = parseInt( lines[ i ].substr( 6, 5 ) ) - 1;
199 |
200 | e = trim( lines[ i ].substr( 76, 2 ) ).toLowerCase();
201 |
202 | if ( e === '' ) {
203 |
204 | e = trim( lines[ i ].substr( 12, 2 ) ).toLowerCase();
205 |
206 | }
207 |
208 | var atomData = [ x, y, z, CPK[ e ], capitalize( e ) ];
209 |
210 | atoms.push( atomData );
211 | _atomMap[ index ] = atomData;
212 |
213 | } else if ( lines[ i ].substr( 0, 6 ) === 'CONECT' ) {
214 |
215 | var satom = parseInt( lines[ i ].substr( 6, 5 ) );
216 |
217 | parseBond( 11, 5 );
218 | parseBond( 16, 5 );
219 | parseBond( 21, 5 );
220 | parseBond( 26, 5 );
221 |
222 | }
223 |
224 | }
225 |
226 | // build and return geometry
227 |
228 | return buildGeometry();
229 |
230 | }
231 |
232 | } );
233 |
234 | export { PDBLoader };
235 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/PRWMLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | BufferAttribute,
3 | BufferGeometry,
4 | FileLoader,
5 | Loader
6 | } from '../../../build/three.module.js';
7 |
8 | /**
9 | * See https://github.com/kchapelier/PRWM for more informations about this file format
10 | */
11 |
12 | var PRWMLoader = ( function () {
13 |
14 | var bigEndianPlatform = null;
15 |
16 | /**
17 | * Check if the endianness of the platform is big-endian (most significant bit first)
18 | * @returns {boolean} True if big-endian, false if little-endian
19 | */
20 | function isBigEndianPlatform() {
21 |
22 | if ( bigEndianPlatform === null ) {
23 |
24 | var buffer = new ArrayBuffer( 2 ),
25 | uint8Array = new Uint8Array( buffer ),
26 | uint16Array = new Uint16Array( buffer );
27 |
28 | uint8Array[ 0 ] = 0xAA; // set first byte
29 | uint8Array[ 1 ] = 0xBB; // set second byte
30 | bigEndianPlatform = ( uint16Array[ 0 ] === 0xAABB );
31 |
32 | }
33 |
34 | return bigEndianPlatform;
35 |
36 | }
37 |
38 | // match the values defined in the spec to the TypedArray types
39 | var InvertedEncodingTypes = [
40 | null,
41 | Float32Array,
42 | null,
43 | Int8Array,
44 | Int16Array,
45 | null,
46 | Int32Array,
47 | Uint8Array,
48 | Uint16Array,
49 | null,
50 | Uint32Array
51 | ];
52 |
53 | // define the method to use on a DataView, corresponding the TypedArray type
54 | var getMethods = {
55 | Uint16Array: 'getUint16',
56 | Uint32Array: 'getUint32',
57 | Int16Array: 'getInt16',
58 | Int32Array: 'getInt32',
59 | Float32Array: 'getFloat32',
60 | Float64Array: 'getFloat64'
61 | };
62 |
63 |
64 | function copyFromBuffer( sourceArrayBuffer, viewType, position, length, fromBigEndian ) {
65 |
66 | var bytesPerElement = viewType.BYTES_PER_ELEMENT,
67 | result;
68 |
69 | if ( fromBigEndian === isBigEndianPlatform() || bytesPerElement === 1 ) {
70 |
71 | result = new viewType( sourceArrayBuffer, position, length );
72 |
73 | } else {
74 |
75 | var readView = new DataView( sourceArrayBuffer, position, length * bytesPerElement ),
76 | getMethod = getMethods[ viewType.name ],
77 | littleEndian = ! fromBigEndian,
78 | i = 0;
79 |
80 | result = new viewType( length );
81 |
82 | for ( ; i < length; i ++ ) {
83 |
84 | result[ i ] = readView[ getMethod ]( i * bytesPerElement, littleEndian );
85 |
86 | }
87 |
88 | }
89 |
90 | return result;
91 |
92 | }
93 |
94 |
95 | function decodePrwm( buffer ) {
96 |
97 | var array = new Uint8Array( buffer ),
98 | version = array[ 0 ],
99 | flags = array[ 1 ],
100 | indexedGeometry = !! ( flags >> 7 & 0x01 ),
101 | indicesType = flags >> 6 & 0x01,
102 | bigEndian = ( flags >> 5 & 0x01 ) === 1,
103 | attributesNumber = flags & 0x1F,
104 | valuesNumber = 0,
105 | indicesNumber = 0;
106 |
107 | if ( bigEndian ) {
108 |
109 | valuesNumber = ( array[ 2 ] << 16 ) + ( array[ 3 ] << 8 ) + array[ 4 ];
110 | indicesNumber = ( array[ 5 ] << 16 ) + ( array[ 6 ] << 8 ) + array[ 7 ];
111 |
112 | } else {
113 |
114 | valuesNumber = array[ 2 ] + ( array[ 3 ] << 8 ) + ( array[ 4 ] << 16 );
115 | indicesNumber = array[ 5 ] + ( array[ 6 ] << 8 ) + ( array[ 7 ] << 16 );
116 |
117 | }
118 |
119 | /** PRELIMINARY CHECKS **/
120 |
121 | if ( version === 0 ) {
122 |
123 | throw new Error( 'PRWM decoder: Invalid format version: 0' );
124 |
125 | } else if ( version !== 1 ) {
126 |
127 | throw new Error( 'PRWM decoder: Unsupported format version: ' + version );
128 |
129 | }
130 |
131 | if ( ! indexedGeometry ) {
132 |
133 | if ( indicesType !== 0 ) {
134 |
135 | throw new Error( 'PRWM decoder: Indices type must be set to 0 for non-indexed geometries' );
136 |
137 | } else if ( indicesNumber !== 0 ) {
138 |
139 | throw new Error( 'PRWM decoder: Number of indices must be set to 0 for non-indexed geometries' );
140 |
141 | }
142 |
143 | }
144 |
145 | /** PARSING **/
146 |
147 | var pos = 8;
148 |
149 | var attributes = {},
150 | attributeName,
151 | char,
152 | attributeType,
153 | cardinality,
154 | encodingType,
155 | arrayType,
156 | values,
157 | indices,
158 | i;
159 |
160 | for ( i = 0; i < attributesNumber; i ++ ) {
161 |
162 | attributeName = '';
163 |
164 | while ( pos < array.length ) {
165 |
166 | char = array[ pos ];
167 | pos ++;
168 |
169 | if ( char === 0 ) {
170 |
171 | break;
172 |
173 | } else {
174 |
175 | attributeName += String.fromCharCode( char );
176 |
177 | }
178 |
179 | }
180 |
181 | flags = array[ pos ];
182 |
183 | attributeType = flags >> 7 & 0x01;
184 | cardinality = ( flags >> 4 & 0x03 ) + 1;
185 | encodingType = flags & 0x0F;
186 | arrayType = InvertedEncodingTypes[ encodingType ];
187 |
188 | pos ++;
189 |
190 | // padding to next multiple of 4
191 | pos = Math.ceil( pos / 4 ) * 4;
192 |
193 | values = copyFromBuffer( buffer, arrayType, pos, cardinality * valuesNumber, bigEndian );
194 |
195 | pos += arrayType.BYTES_PER_ELEMENT * cardinality * valuesNumber;
196 |
197 | attributes[ attributeName ] = {
198 | type: attributeType,
199 | cardinality: cardinality,
200 | values: values
201 | };
202 |
203 | }
204 |
205 | pos = Math.ceil( pos / 4 ) * 4;
206 |
207 | indices = null;
208 |
209 | if ( indexedGeometry ) {
210 |
211 | indices = copyFromBuffer(
212 | buffer,
213 | indicesType === 1 ? Uint32Array : Uint16Array,
214 | pos,
215 | indicesNumber,
216 | bigEndian
217 | );
218 |
219 | }
220 |
221 | return {
222 | version: version,
223 | attributes: attributes,
224 | indices: indices
225 | };
226 |
227 | }
228 |
229 | // Define the public interface
230 |
231 | function PRWMLoader( manager ) {
232 |
233 | Loader.call( this, manager );
234 |
235 | }
236 |
237 | PRWMLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
238 |
239 | constructor: PRWMLoader,
240 |
241 | load: function ( url, onLoad, onProgress, onError ) {
242 |
243 | var scope = this;
244 |
245 | var loader = new FileLoader( scope.manager );
246 | loader.setPath( scope.path );
247 | loader.setResponseType( 'arraybuffer' );
248 | loader.setRequestHeader( scope.requestHeader );
249 | loader.setWithCredentials( scope.withCredentials );
250 |
251 | url = url.replace( /\*/g, isBigEndianPlatform() ? 'be' : 'le' );
252 |
253 | loader.load( url, function ( arrayBuffer ) {
254 |
255 | try {
256 |
257 | onLoad( scope.parse( arrayBuffer ) );
258 |
259 | } catch ( e ) {
260 |
261 | if ( onError ) {
262 |
263 | onError( e );
264 |
265 | } else {
266 |
267 | console.error( e );
268 |
269 | }
270 |
271 | scope.manager.itemError( url );
272 |
273 | }
274 |
275 | }, onProgress, onError );
276 |
277 | },
278 |
279 | parse: function ( arrayBuffer ) {
280 |
281 | var data = decodePrwm( arrayBuffer ),
282 | attributesKey = Object.keys( data.attributes ),
283 | bufferGeometry = new BufferGeometry(),
284 | attribute,
285 | i;
286 |
287 | for ( i = 0; i < attributesKey.length; i ++ ) {
288 |
289 | attribute = data.attributes[ attributesKey[ i ] ];
290 | bufferGeometry.setAttribute( attributesKey[ i ], new BufferAttribute( attribute.values, attribute.cardinality, attribute.normalized ) );
291 |
292 | }
293 |
294 | if ( data.indices !== null ) {
295 |
296 | bufferGeometry.setIndex( new BufferAttribute( data.indices, 1 ) );
297 |
298 | }
299 |
300 | return bufferGeometry;
301 |
302 | }
303 |
304 | } );
305 |
306 | PRWMLoader.isBigEndianPlatform = function () {
307 |
308 | return isBigEndianPlatform();
309 |
310 | };
311 |
312 | return PRWMLoader;
313 |
314 | } )();
315 |
316 | export { PRWMLoader };
317 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/PVRLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | CompressedTextureLoader,
3 | RGBA_PVRTC_2BPPV1_Format,
4 | RGBA_PVRTC_4BPPV1_Format,
5 | RGB_PVRTC_2BPPV1_Format,
6 | RGB_PVRTC_4BPPV1_Format
7 | } from '../../../build/three.module.js';
8 |
9 | /*
10 | * PVR v2 (legacy) parser
11 | * TODO : Add Support for PVR v3 format
12 | * TODO : implement loadMipmaps option
13 | */
14 |
15 | var PVRLoader = function ( manager ) {
16 |
17 | CompressedTextureLoader.call( this, manager );
18 |
19 | };
20 |
21 | PVRLoader.prototype = Object.assign( Object.create( CompressedTextureLoader.prototype ), {
22 |
23 | constructor: PVRLoader,
24 |
25 | parse: function ( buffer, loadMipmaps ) {
26 |
27 | var headerLengthInt = 13;
28 | var header = new Uint32Array( buffer, 0, headerLengthInt );
29 |
30 | var pvrDatas = {
31 | buffer: buffer,
32 | header: header,
33 | loadMipmaps: loadMipmaps
34 | };
35 |
36 | if ( header[ 0 ] === 0x03525650 ) {
37 |
38 | // PVR v3
39 |
40 | return PVRLoader._parseV3( pvrDatas );
41 |
42 | } else if ( header[ 11 ] === 0x21525650 ) {
43 |
44 | // PVR v2
45 |
46 | return PVRLoader._parseV2( pvrDatas );
47 |
48 | } else {
49 |
50 | console.error( 'THREE.PVRLoader: Unknown PVR format.' );
51 |
52 | }
53 |
54 | }
55 |
56 | } );
57 |
58 | PVRLoader._parseV3 = function ( pvrDatas ) {
59 |
60 | var header = pvrDatas.header;
61 | var bpp, format;
62 |
63 |
64 | var metaLen = header[ 12 ],
65 | pixelFormat = header[ 2 ],
66 | height = header[ 6 ],
67 | width = header[ 7 ],
68 | // numSurfs = header[ 9 ],
69 | numFaces = header[ 10 ],
70 | numMipmaps = header[ 11 ];
71 |
72 | switch ( pixelFormat ) {
73 |
74 | case 0 : // PVRTC 2bpp RGB
75 | bpp = 2;
76 | format = RGB_PVRTC_2BPPV1_Format;
77 | break;
78 |
79 | case 1 : // PVRTC 2bpp RGBA
80 | bpp = 2;
81 | format = RGBA_PVRTC_2BPPV1_Format;
82 | break;
83 |
84 | case 2 : // PVRTC 4bpp RGB
85 | bpp = 4;
86 | format = RGB_PVRTC_4BPPV1_Format;
87 | break;
88 |
89 | case 3 : // PVRTC 4bpp RGBA
90 | bpp = 4;
91 | format = RGBA_PVRTC_4BPPV1_Format;
92 | break;
93 |
94 | default :
95 | console.error( 'THREE.PVRLoader: Unsupported PVR format:', pixelFormat );
96 |
97 | }
98 |
99 | pvrDatas.dataPtr = 52 + metaLen;
100 | pvrDatas.bpp = bpp;
101 | pvrDatas.format = format;
102 | pvrDatas.width = width;
103 | pvrDatas.height = height;
104 | pvrDatas.numSurfaces = numFaces;
105 | pvrDatas.numMipmaps = numMipmaps;
106 | pvrDatas.isCubemap = ( numFaces === 6 );
107 |
108 | return PVRLoader._extract( pvrDatas );
109 |
110 | };
111 |
112 | PVRLoader._parseV2 = function ( pvrDatas ) {
113 |
114 | var header = pvrDatas.header;
115 |
116 | var headerLength = header[ 0 ],
117 | height = header[ 1 ],
118 | width = header[ 2 ],
119 | numMipmaps = header[ 3 ],
120 | flags = header[ 4 ],
121 | // dataLength = header[ 5 ],
122 | // bpp = header[ 6 ],
123 | // bitmaskRed = header[ 7 ],
124 | // bitmaskGreen = header[ 8 ],
125 | // bitmaskBlue = header[ 9 ],
126 | bitmaskAlpha = header[ 10 ],
127 | // pvrTag = header[ 11 ],
128 | numSurfs = header[ 12 ];
129 |
130 |
131 | var TYPE_MASK = 0xff;
132 | var PVRTC_2 = 24,
133 | PVRTC_4 = 25;
134 |
135 | var formatFlags = flags & TYPE_MASK;
136 |
137 | var bpp, format;
138 | var _hasAlpha = bitmaskAlpha > 0;
139 |
140 | if ( formatFlags === PVRTC_4 ) {
141 |
142 | format = _hasAlpha ? RGBA_PVRTC_4BPPV1_Format : RGB_PVRTC_4BPPV1_Format;
143 | bpp = 4;
144 |
145 | } else if ( formatFlags === PVRTC_2 ) {
146 |
147 | format = _hasAlpha ? RGBA_PVRTC_2BPPV1_Format : RGB_PVRTC_2BPPV1_Format;
148 | bpp = 2;
149 |
150 | } else {
151 |
152 | console.error( 'THREE.PVRLoader: Unknown PVR format:', formatFlags );
153 |
154 | }
155 |
156 | pvrDatas.dataPtr = headerLength;
157 | pvrDatas.bpp = bpp;
158 | pvrDatas.format = format;
159 | pvrDatas.width = width;
160 | pvrDatas.height = height;
161 | pvrDatas.numSurfaces = numSurfs;
162 | pvrDatas.numMipmaps = numMipmaps + 1;
163 |
164 | // guess cubemap type seems tricky in v2
165 | // it juste a pvr containing 6 surface (no explicit cubemap type)
166 | pvrDatas.isCubemap = ( numSurfs === 6 );
167 |
168 | return PVRLoader._extract( pvrDatas );
169 |
170 | };
171 |
172 |
173 | PVRLoader._extract = function ( pvrDatas ) {
174 |
175 | var pvr = {
176 | mipmaps: [],
177 | width: pvrDatas.width,
178 | height: pvrDatas.height,
179 | format: pvrDatas.format,
180 | mipmapCount: pvrDatas.numMipmaps,
181 | isCubemap: pvrDatas.isCubemap
182 | };
183 |
184 | var buffer = pvrDatas.buffer;
185 |
186 | var dataOffset = pvrDatas.dataPtr,
187 | bpp = pvrDatas.bpp,
188 | numSurfs = pvrDatas.numSurfaces,
189 | dataSize = 0,
190 | blockSize = 0,
191 | blockWidth = 0,
192 | blockHeight = 0,
193 | widthBlocks = 0,
194 | heightBlocks = 0;
195 |
196 | if ( bpp === 2 ) {
197 |
198 | blockWidth = 8;
199 | blockHeight = 4;
200 |
201 | } else {
202 |
203 | blockWidth = 4;
204 | blockHeight = 4;
205 |
206 | }
207 |
208 | blockSize = ( blockWidth * blockHeight ) * bpp / 8;
209 |
210 | pvr.mipmaps.length = pvrDatas.numMipmaps * numSurfs;
211 |
212 | var mipLevel = 0;
213 |
214 | while ( mipLevel < pvrDatas.numMipmaps ) {
215 |
216 | var sWidth = pvrDatas.width >> mipLevel,
217 | sHeight = pvrDatas.height >> mipLevel;
218 |
219 | widthBlocks = sWidth / blockWidth;
220 | heightBlocks = sHeight / blockHeight;
221 |
222 | // Clamp to minimum number of blocks
223 | if ( widthBlocks < 2 ) widthBlocks = 2;
224 | if ( heightBlocks < 2 ) heightBlocks = 2;
225 |
226 | dataSize = widthBlocks * heightBlocks * blockSize;
227 |
228 | for ( var surfIndex = 0; surfIndex < numSurfs; surfIndex ++ ) {
229 |
230 | var byteArray = new Uint8Array( buffer, dataOffset, dataSize );
231 |
232 | var mipmap = {
233 | data: byteArray,
234 | width: sWidth,
235 | height: sHeight
236 | };
237 |
238 | pvr.mipmaps[ surfIndex * pvrDatas.numMipmaps + mipLevel ] = mipmap;
239 |
240 | dataOffset += dataSize;
241 |
242 | }
243 |
244 | mipLevel ++;
245 |
246 | }
247 |
248 | return pvr;
249 |
250 | };
251 |
252 | export { PVRLoader };
253 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/TTFLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | FileLoader,
3 | Loader
4 | } from '../../../build/three.module.js';
5 | import { opentype } from '../libs/opentype.module.min.js';
6 |
7 | /**
8 | * Requires opentype.js to be included in the project.
9 | * Loads TTF files and converts them into typeface JSON that can be used directly
10 | * to create THREE.Font objects.
11 | */
12 |
13 | var TTFLoader = function ( manager ) {
14 |
15 | Loader.call( this, manager );
16 |
17 | this.reversed = false;
18 |
19 | };
20 |
21 |
22 | TTFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
23 |
24 | constructor: TTFLoader,
25 |
26 | load: function ( url, onLoad, onProgress, onError ) {
27 |
28 | var scope = this;
29 |
30 | var loader = new FileLoader( this.manager );
31 | loader.setPath( this.path );
32 | loader.setResponseType( 'arraybuffer' );
33 | loader.setRequestHeader( this.requestHeader );
34 | loader.setWithCredentials( this.withCredentials );
35 | loader.load( url, function ( buffer ) {
36 |
37 | try {
38 |
39 | onLoad( scope.parse( buffer ) );
40 |
41 | } catch ( e ) {
42 |
43 | if ( onError ) {
44 |
45 | onError( e );
46 |
47 | } else {
48 |
49 | console.error( e );
50 |
51 | }
52 |
53 | scope.manager.itemError( url );
54 |
55 | }
56 |
57 | }, onProgress, onError );
58 |
59 | },
60 |
61 | parse: function ( arraybuffer ) {
62 |
63 | function convert( font, reversed ) {
64 |
65 | var round = Math.round;
66 |
67 | var glyphs = {};
68 | var scale = ( 100000 ) / ( ( font.unitsPerEm || 2048 ) * 72 );
69 |
70 | var glyphIndexMap = font.encoding.cmap.glyphIndexMap;
71 | var unicodes = Object.keys( glyphIndexMap );
72 |
73 | for ( var i = 0; i < unicodes.length; i ++ ) {
74 |
75 | var unicode = unicodes[ i ];
76 | var glyph = font.glyphs.glyphs[ glyphIndexMap[ unicode ] ];
77 |
78 | if ( unicode !== undefined ) {
79 |
80 | var token = {
81 | ha: round( glyph.advanceWidth * scale ),
82 | x_min: round( glyph.xMin * scale ),
83 | x_max: round( glyph.xMax * scale ),
84 | o: ''
85 | };
86 |
87 | if ( reversed ) {
88 |
89 | glyph.path.commands = reverseCommands( glyph.path.commands );
90 |
91 | }
92 |
93 | glyph.path.commands.forEach( function ( command ) {
94 |
95 | if ( command.type.toLowerCase() === 'c' ) {
96 |
97 | command.type = 'b';
98 |
99 | }
100 |
101 | token.o += command.type.toLowerCase() + ' ';
102 |
103 | if ( command.x !== undefined && command.y !== undefined ) {
104 |
105 | token.o += round( command.x * scale ) + ' ' + round( command.y * scale ) + ' ';
106 |
107 | }
108 |
109 | if ( command.x1 !== undefined && command.y1 !== undefined ) {
110 |
111 | token.o += round( command.x1 * scale ) + ' ' + round( command.y1 * scale ) + ' ';
112 |
113 | }
114 |
115 | if ( command.x2 !== undefined && command.y2 !== undefined ) {
116 |
117 | token.o += round( command.x2 * scale ) + ' ' + round( command.y2 * scale ) + ' ';
118 |
119 | }
120 |
121 | } );
122 |
123 | glyphs[ String.fromCodePoint( glyph.unicode ) ] = token;
124 |
125 | }
126 |
127 | }
128 |
129 | return {
130 | glyphs: glyphs,
131 | familyName: font.getEnglishName( 'fullName' ),
132 | ascender: round( font.ascender * scale ),
133 | descender: round( font.descender * scale ),
134 | underlinePosition: font.tables.post.underlinePosition,
135 | underlineThickness: font.tables.post.underlineThickness,
136 | boundingBox: {
137 | xMin: font.tables.head.xMin,
138 | xMax: font.tables.head.xMax,
139 | yMin: font.tables.head.yMin,
140 | yMax: font.tables.head.yMax
141 | },
142 | resolution: 1000,
143 | original_font_information: font.tables.name
144 | };
145 |
146 | }
147 |
148 | function reverseCommands( commands ) {
149 |
150 | var paths = [];
151 | var path;
152 |
153 | commands.forEach( function ( c ) {
154 |
155 | if ( c.type.toLowerCase() === 'm' ) {
156 |
157 | path = [ c ];
158 | paths.push( path );
159 |
160 | } else if ( c.type.toLowerCase() !== 'z' ) {
161 |
162 | path.push( c );
163 |
164 | }
165 |
166 | } );
167 |
168 | var reversed = [];
169 |
170 | paths.forEach( function ( p ) {
171 |
172 | var result = {
173 | type: 'm',
174 | x: p[ p.length - 1 ].x,
175 | y: p[ p.length - 1 ].y
176 | };
177 |
178 | reversed.push( result );
179 |
180 | for ( var i = p.length - 1; i > 0; i -- ) {
181 |
182 | var command = p[ i ];
183 | var result = { type: command.type };
184 |
185 | if ( command.x2 !== undefined && command.y2 !== undefined ) {
186 |
187 | result.x1 = command.x2;
188 | result.y1 = command.y2;
189 | result.x2 = command.x1;
190 | result.y2 = command.y1;
191 |
192 | } else if ( command.x1 !== undefined && command.y1 !== undefined ) {
193 |
194 | result.x1 = command.x1;
195 | result.y1 = command.y1;
196 |
197 | }
198 |
199 | result.x = p[ i - 1 ].x;
200 | result.y = p[ i - 1 ].y;
201 | reversed.push( result );
202 |
203 | }
204 |
205 | } );
206 |
207 | return reversed;
208 |
209 | }
210 |
211 | if ( typeof opentype === 'undefined' ) {
212 |
213 | console.warn( 'THREE.TTFLoader: The loader requires opentype.js. Make sure it\'s included before using the loader.' );
214 | return null;
215 |
216 | }
217 |
218 | return convert( opentype.parse( arraybuffer ), this.reversed ); // eslint-disable-line no-undef
219 |
220 | }
221 |
222 | } );
223 |
224 | export { TTFLoader };
225 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/VRMLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | Loader
3 | } from '../../../build/three.module.js';
4 | import { GLTFLoader } from '../loaders/GLTFLoader.js';
5 |
6 | // VRM Specification: https://dwango.github.io/vrm/vrm_spec/
7 | //
8 | // VRM is based on glTF 2.0 and VRM extension is defined
9 | // in top-level json.extensions.VRM
10 |
11 | var VRMLoader = ( function () {
12 |
13 | function VRMLoader( manager ) {
14 |
15 | if ( GLTFLoader === undefined ) {
16 |
17 | throw new Error( 'THREE.VRMLoader: Import GLTFLoader.' );
18 |
19 | }
20 |
21 | Loader.call( this, manager );
22 |
23 | this.gltfLoader = new GLTFLoader( this.manager );
24 |
25 | }
26 |
27 | VRMLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
28 |
29 | constructor: VRMLoader,
30 |
31 | load: function ( url, onLoad, onProgress, onError ) {
32 |
33 | var scope = this;
34 |
35 | this.gltfLoader.load( url, function ( gltf ) {
36 |
37 | try {
38 |
39 | scope.parse( gltf, onLoad );
40 |
41 | } catch ( e ) {
42 |
43 | if ( onError ) {
44 |
45 | onError( e );
46 |
47 | } else {
48 |
49 | console.error( e );
50 |
51 | }
52 |
53 | scope.manager.itemError( url );
54 |
55 | }
56 |
57 | }, onProgress, onError );
58 |
59 | },
60 |
61 | setDRACOLoader: function ( dracoLoader ) {
62 |
63 | this.gltfLoader.setDRACOLoader( dracoLoader );
64 | return this;
65 |
66 | },
67 |
68 | parse: function ( gltf, onLoad ) {
69 |
70 | // var gltfParser = gltf.parser;
71 | // var gltfExtensions = gltf.userData.gltfExtensions || {};
72 | // var vrmExtension = gltfExtensions.VRM || {};
73 |
74 | // handle VRM Extension here
75 |
76 | onLoad( gltf );
77 |
78 | }
79 |
80 | } );
81 |
82 | return VRMLoader;
83 |
84 | } )();
85 |
86 | export { VRMLoader };
87 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/XYZLoader.js:
--------------------------------------------------------------------------------
1 | import {
2 | BufferGeometry,
3 | FileLoader,
4 | Float32BufferAttribute,
5 | Loader
6 | } from '../../../build/three.module.js';
7 |
8 | class XYZLoader extends Loader {
9 |
10 | load( url, onLoad, onProgress, onError ) {
11 |
12 | const scope = this;
13 |
14 | const loader = new FileLoader( this.manager );
15 | loader.setPath( this.path );
16 | loader.setRequestHeader( this.requestHeader );
17 | loader.setWithCredentials( this.withCredentials );
18 | loader.load( url, function ( text ) {
19 |
20 | try {
21 |
22 | onLoad( scope.parse( text ) );
23 |
24 | } catch ( e ) {
25 |
26 | if ( onError ) {
27 |
28 | onError( e );
29 |
30 | } else {
31 |
32 | console.error( e );
33 |
34 | }
35 |
36 | scope.manager.itemError( url );
37 |
38 | }
39 |
40 | }, onProgress, onError );
41 |
42 | }
43 |
44 | parse( text ) {
45 |
46 | const lines = text.split( '\n' );
47 |
48 | const vertices = [];
49 | const colors = [];
50 |
51 | for ( let line of lines ) {
52 |
53 | line = line.trim();
54 |
55 | if ( line.charAt( 0 ) === '#' ) continue; // skip comments
56 |
57 | const lineValues = line.split( /\s+/ );
58 |
59 | if ( lineValues.length === 3 ) {
60 |
61 | // XYZ
62 |
63 | vertices.push( parseFloat( lineValues[ 0 ] ) );
64 | vertices.push( parseFloat( lineValues[ 1 ] ) );
65 | vertices.push( parseFloat( lineValues[ 2 ] ) );
66 |
67 | }
68 |
69 | if ( lineValues.length === 6 ) {
70 |
71 | // XYZRGB
72 |
73 | vertices.push( parseFloat( lineValues[ 0 ] ) );
74 | vertices.push( parseFloat( lineValues[ 1 ] ) );
75 | vertices.push( parseFloat( lineValues[ 2 ] ) );
76 |
77 | colors.push( parseFloat( lineValues[ 3 ] ) / 255 );
78 | colors.push( parseFloat( lineValues[ 4 ] ) / 255 );
79 | colors.push( parseFloat( lineValues[ 5 ] ) / 255 );
80 |
81 | }
82 |
83 | }
84 |
85 | const geometry = new BufferGeometry();
86 | geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
87 |
88 | if ( colors.length > 0 ) {
89 |
90 | geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
91 |
92 | }
93 |
94 | return geometry;
95 |
96 | }
97 |
98 | }
99 |
100 | export { XYZLoader };
101 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/obj2/bridge/MtlObjBridge.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Development repository: https://github.com/kaisalmen/WWOBJLoader
3 | */
4 |
5 | import { MTLLoader } from '../../../../jsm/loaders/MTLLoader.js';
6 |
7 |
8 | const MtlObjBridge = {
9 |
10 | /**
11 | *
12 | * @param processResult
13 | * @param assetLoader
14 | */
15 | link: function ( processResult, assetLoader ) {
16 |
17 | if ( typeof assetLoader.addMaterials === 'function' ) {
18 |
19 | assetLoader.addMaterials( this.addMaterialsFromMtlLoader( processResult ), true );
20 |
21 | }
22 |
23 | },
24 |
25 | /**
26 | * Returns the array instance of {@link MTLLoader.MaterialCreator}.
27 | *
28 | * @param Instance of {@link MTLLoader.MaterialCreator}
29 | */
30 | addMaterialsFromMtlLoader: function ( materialCreator ) {
31 |
32 | let newMaterials = {};
33 |
34 | if ( materialCreator instanceof MTLLoader.MaterialCreator ) {
35 |
36 | materialCreator.preload();
37 | newMaterials = materialCreator.materials;
38 |
39 | }
40 |
41 | return newMaterials;
42 |
43 | }
44 | };
45 |
46 | export { MtlObjBridge };
47 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/obj2/shared/MaterialHandler.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Development repository: https://github.com/kaisalmen/WWOBJLoader
3 | */
4 |
5 | import {
6 | LineBasicMaterial,
7 | MaterialLoader,
8 | MeshStandardMaterial,
9 | PointsMaterial
10 | } from '../../../../../build/three.module.js';
11 |
12 |
13 | const MaterialHandler = function () {
14 |
15 | this.logging = {
16 | enabled: false,
17 | debug: false
18 | };
19 |
20 | this.callbacks = {
21 | onLoadMaterials: null
22 | };
23 | this.materials = {};
24 |
25 | };
26 |
27 | MaterialHandler.prototype = {
28 |
29 | constructor: MaterialHandler,
30 |
31 | /**
32 | * Enable or disable logging in general (except warn and error), plus enable or disable debug logging.
33 | *
34 | * @param {boolean} enabled True or false.
35 | * @param {boolean} debug True or false.
36 | */
37 | setLogging: function ( enabled, debug ) {
38 |
39 | this.logging.enabled = enabled === true;
40 | this.logging.debug = debug === true;
41 |
42 | },
43 |
44 | _setCallbacks: function ( onLoadMaterials ) {
45 |
46 | if ( onLoadMaterials !== undefined && onLoadMaterials !== null && onLoadMaterials instanceof Function ) {
47 |
48 | this.callbacks.onLoadMaterials = onLoadMaterials;
49 |
50 | }
51 |
52 | },
53 |
54 | /**
55 | * Creates default materials and adds them to the materials object.
56 | *
57 | * @param overrideExisting boolean Override existing material
58 | */
59 | createDefaultMaterials: function ( overrideExisting ) {
60 |
61 | const defaultMaterial = new MeshStandardMaterial( { color: 0xDCF1FF } );
62 | defaultMaterial.name = 'defaultMaterial';
63 |
64 | const defaultVertexColorMaterial = new MeshStandardMaterial( { color: 0xDCF1FF } );
65 | defaultVertexColorMaterial.name = 'defaultVertexColorMaterial';
66 | defaultVertexColorMaterial.vertexColors = true;
67 |
68 | const defaultLineMaterial = new LineBasicMaterial();
69 | defaultLineMaterial.name = 'defaultLineMaterial';
70 |
71 | const defaultPointMaterial = new PointsMaterial( { size: 0.1 } );
72 | defaultPointMaterial.name = 'defaultPointMaterial';
73 |
74 | const runtimeMaterials = {};
75 | runtimeMaterials[ defaultMaterial.name ] = defaultMaterial;
76 | runtimeMaterials[ defaultVertexColorMaterial.name ] = defaultVertexColorMaterial;
77 | runtimeMaterials[ defaultLineMaterial.name ] = defaultLineMaterial;
78 | runtimeMaterials[ defaultPointMaterial.name ] = defaultPointMaterial;
79 |
80 | this.addMaterials( runtimeMaterials, overrideExisting );
81 |
82 | },
83 |
84 | /**
85 | * Updates the materials with contained material objects (sync) or from alteration instructions (async).
86 | *
87 | * @param {Object} materialPayload Material update instructions
88 | * @returns {Object} Map of {@link Material}
89 | */
90 | addPayloadMaterials: function ( materialPayload ) {
91 |
92 | let material, materialName;
93 | const materialCloneInstructions = materialPayload.materials.materialCloneInstructions;
94 | let newMaterials = {};
95 |
96 | if ( materialCloneInstructions !== undefined && materialCloneInstructions !== null ) {
97 |
98 | let materialNameOrg = materialCloneInstructions.materialNameOrg;
99 | materialNameOrg = ( materialNameOrg !== undefined && materialNameOrg !== null ) ? materialNameOrg : '';
100 | const materialOrg = this.materials[ materialNameOrg ];
101 | if ( materialOrg ) {
102 |
103 | material = materialOrg.clone();
104 |
105 | materialName = materialCloneInstructions.materialName;
106 | material.name = materialName;
107 |
108 | Object.assign( material, materialCloneInstructions.materialProperties );
109 |
110 | this.materials[ materialName ] = material;
111 | newMaterials[ materialName ] = material;
112 |
113 | } else {
114 |
115 | if ( this.logging.enabled ) {
116 |
117 | console.info( 'Requested material "' + materialNameOrg + '" is not available!' );
118 |
119 | }
120 |
121 | }
122 |
123 | }
124 |
125 | let materials = materialPayload.materials.serializedMaterials;
126 |
127 | if ( materials !== undefined && materials !== null && Object.keys( materials ).length > 0 ) {
128 |
129 | const loader = new MaterialLoader();
130 | let materialJson;
131 |
132 | for ( materialName in materials ) {
133 |
134 | materialJson = materials[ materialName ];
135 |
136 | if ( materialJson !== undefined && materialJson !== null ) {
137 |
138 | material = loader.parse( materialJson );
139 |
140 | if ( this.logging.enabled ) {
141 |
142 | console.info( 'De-serialized material with name "' + materialName + '" will be added.' );
143 |
144 | }
145 |
146 | this.materials[ materialName ] = material;
147 | newMaterials[ materialName ] = material;
148 |
149 | }
150 |
151 | }
152 |
153 | }
154 |
155 | materials = materialPayload.materials.runtimeMaterials;
156 | newMaterials = this.addMaterials( materials, true, newMaterials );
157 |
158 | return newMaterials;
159 |
160 | },
161 |
162 | /**
163 | * Set materials loaded by any supplier of an Array of {@link Material}.
164 | *
165 | * @param materials Object with named {@link Material}
166 | * @param overrideExisting boolean Override existing material
167 | * @param newMaterials [Object] with named {@link Material}
168 | */
169 | addMaterials: function ( materials, overrideExisting, newMaterials ) {
170 |
171 | if ( newMaterials === undefined || newMaterials === null ) {
172 |
173 | newMaterials = {};
174 |
175 | }
176 |
177 | if ( materials !== undefined && materials !== null && Object.keys( materials ).length > 0 ) {
178 |
179 | let material;
180 | let existingMaterial;
181 | let add;
182 |
183 | for ( const materialName in materials ) {
184 |
185 | material = materials[ materialName ];
186 | add = overrideExisting === true;
187 |
188 | if ( ! add ) {
189 |
190 | existingMaterial = this.materials[ materialName ];
191 | add = ( existingMaterial === null || existingMaterial === undefined );
192 |
193 | }
194 |
195 | if ( add ) {
196 |
197 | this.materials[ materialName ] = material;
198 | newMaterials[ materialName ] = material;
199 |
200 | }
201 |
202 | if ( this.logging.enabled && this.logging.debug ) {
203 |
204 | console.info( 'Material with name "' + materialName + '" was added.' );
205 |
206 | }
207 |
208 | }
209 |
210 | }
211 |
212 | if ( this.callbacks.onLoadMaterials ) {
213 |
214 | this.callbacks.onLoadMaterials( newMaterials );
215 |
216 | }
217 |
218 | return newMaterials;
219 |
220 | },
221 |
222 | /**
223 | * Returns the mapping object of material name and corresponding material.
224 | *
225 | * @returns {Object} Map of {@link Material}
226 | */
227 | getMaterials: function () {
228 |
229 | return this.materials;
230 |
231 | },
232 |
233 | /**
234 | *
235 | * @param {String} materialName
236 | * @returns {Material}
237 | */
238 | getMaterial: function ( materialName ) {
239 |
240 | return this.materials[ materialName ];
241 |
242 | },
243 |
244 | /**
245 | * Returns the mapping object of material name and corresponding jsonified material.
246 | *
247 | * @returns {Object} Map of Materials in JSON representation
248 | */
249 | getMaterialsJSON: function () {
250 |
251 | const materialsJSON = {};
252 | let material;
253 |
254 | for ( const materialName in this.materials ) {
255 |
256 | material = this.materials[ materialName ];
257 | materialsJSON[ materialName ] = material.toJSON();
258 |
259 | }
260 |
261 | return materialsJSON;
262 |
263 | },
264 |
265 | /**
266 | * Removes all materials
267 | */
268 | clearMaterials: function () {
269 |
270 | this.materials = {};
271 |
272 | }
273 |
274 | };
275 |
276 | export { MaterialHandler };
277 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/obj2/utils/CodeSerializer.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Development repository: https://github.com/kaisalmen/WWOBJLoader
3 | */
4 |
5 | const CodeSerializer = {
6 |
7 | /**
8 | * Serialize an object with specific prototype definition.
9 | *
10 | * @param {Object} targetPrototype The object that should be serialized
11 | * @param {Object} targetPrototypeInstance An instance of the oriobject that should be serialized
12 | * @param {String} [basePrototypeName] Name of the prototype
13 | * @param {Object} [overrideFunctions} Array of {@Link CodeSerializationInstruction} allows to replace or remove function with provided content
14 | *
15 | * @returns {String}
16 | */
17 | serializeClass: function ( targetPrototype, targetPrototypeInstance, basePrototypeName, overrideFunctions ) {
18 |
19 | let objectPart, constructorString, i, funcInstructions, funcTemp;
20 | const fullObjectName = targetPrototypeInstance.constructor.name;
21 | const prototypeFunctions = [];
22 | const objectProperties = [];
23 | const objectFunctions = [];
24 | const isExtended = ( basePrototypeName !== null && basePrototypeName !== undefined );
25 |
26 | if ( ! Array.isArray( overrideFunctions ) ) overrideFunctions = [];
27 |
28 | for ( const name in targetPrototype.prototype ) {
29 |
30 | objectPart = targetPrototype.prototype[ name ];
31 | funcInstructions = new CodeSerializationInstruction( name, fullObjectName + '.prototype.' + name );
32 | funcInstructions.setCode( objectPart.toString() );
33 |
34 | if ( name === 'constructor' ) {
35 |
36 | if ( ! funcInstructions.isRemoveCode() ) {
37 |
38 | constructorString = fullObjectName + ' = ' + funcInstructions.getCode() + ';\n\n';
39 |
40 | }
41 |
42 | } else if ( typeof objectPart === 'function' ) {
43 |
44 | funcTemp = overrideFunctions[ name ];
45 |
46 | if ( funcTemp instanceof CodeSerializationInstruction && funcTemp.getName() === funcInstructions.getName() ) {
47 |
48 | funcInstructions = funcTemp;
49 |
50 | }
51 |
52 | if ( ! funcInstructions.isRemoveCode() ) {
53 |
54 | if ( isExtended ) {
55 |
56 | prototypeFunctions.push( funcInstructions.getFullName() + ' = ' + funcInstructions.getCode() + ';\n\n' );
57 |
58 | } else {
59 |
60 | prototypeFunctions.push( '\t' + funcInstructions.getName() + ': ' + funcInstructions.getCode() + ',\n\n' );
61 |
62 | }
63 |
64 | }
65 |
66 | }
67 |
68 | }
69 |
70 | for ( const name in targetPrototype ) {
71 |
72 | objectPart = targetPrototype[ name ];
73 | funcInstructions = new CodeSerializationInstruction( name, fullObjectName + '.' + name );
74 |
75 | if ( typeof objectPart === 'function' ) {
76 |
77 | funcTemp = overrideFunctions[ name ];
78 | if ( funcTemp instanceof CodeSerializationInstruction && funcTemp.getName() === funcInstructions.getName() ) {
79 |
80 | funcInstructions = funcTemp;
81 |
82 | } else {
83 |
84 | funcInstructions.setCode( objectPart.toString() );
85 |
86 | }
87 |
88 | if ( ! funcInstructions.isRemoveCode() ) {
89 |
90 | objectFunctions.push( funcInstructions.getFullName() + ' = ' + funcInstructions.getCode() + ';\n\n' );
91 |
92 | }
93 |
94 | } else {
95 |
96 | if ( typeof ( objectPart ) === 'string' || objectPart instanceof String ) {
97 |
98 | funcInstructions.setCode( '\"' + objectPart.toString() + '\"' );
99 |
100 | } else if ( typeof objectPart === 'object' ) {
101 |
102 | console.log( 'Omitting object "' + funcInstructions.getName() + '" and replace it with empty object.' );
103 | funcInstructions.setCode( '{}' );
104 |
105 | } else {
106 |
107 | funcInstructions.setCode( objectPart );
108 |
109 | }
110 |
111 | if ( ! funcInstructions.isRemoveCode() ) {
112 |
113 | objectProperties.push( funcInstructions.getFullName() + ' = ' + funcInstructions.getCode() + ';\n' );
114 |
115 | }
116 |
117 | }
118 |
119 | }
120 |
121 | let objectString = constructorString + '\n\n';
122 |
123 | if ( isExtended ) {
124 |
125 | objectString += fullObjectName + '.prototype = Object.create( ' + basePrototypeName + '.prototype );\n';
126 |
127 | }
128 |
129 | objectString += fullObjectName + '.prototype.constructor = ' + fullObjectName + ';\n';
130 | objectString += '\n\n';
131 |
132 | for ( i = 0; i < objectProperties.length; i ++ ) {
133 |
134 | objectString += objectProperties[ i ];
135 |
136 | }
137 |
138 | objectString += '\n\n';
139 |
140 | for ( i = 0; i < objectFunctions.length; i ++ ) {
141 |
142 | objectString += objectFunctions[ i ];
143 |
144 | }
145 |
146 | objectString += '\n\n';
147 |
148 | if ( isExtended ) {
149 |
150 | for ( i = 0; i < prototypeFunctions.length; i ++ ) {
151 |
152 | objectString += prototypeFunctions[ i ];
153 |
154 | }
155 |
156 | } else {
157 |
158 | objectString += fullObjectName + '.prototype = {\n\n';
159 | for ( i = 0; i < prototypeFunctions.length; i ++ ) {
160 |
161 | objectString += prototypeFunctions[ i ];
162 |
163 | }
164 |
165 | objectString += '\n};';
166 |
167 | }
168 |
169 | objectString += '\n\n';
170 |
171 | return objectString;
172 |
173 | },
174 | };
175 |
176 | /**
177 | * Allows to define instructions to override or remove
178 | * @param {String} name Usually the name of a function
179 | * @param {String} fullName The name plus full object description
180 | * @constructor
181 | */
182 | const CodeSerializationInstruction = function ( name, fullName ) {
183 |
184 | this.name = name;
185 | this.fullName = fullName;
186 | this.code = null;
187 | this.removeCode = false;
188 |
189 | };
190 |
191 | CodeSerializationInstruction.prototype = {
192 |
193 | constructor: CodeSerializationInstruction,
194 |
195 | /**
196 | * Returns the name of the function
197 | * @return {String}
198 | */
199 | getName: function () {
200 |
201 | return this.name;
202 |
203 | },
204 |
205 | /**
206 | * Returns the full name of the function
207 | * @return {String}
208 | */
209 | getFullName: function () {
210 |
211 | return this.fullName;
212 |
213 | },
214 |
215 | /**
216 | * Set the string containing the serialized function
217 | * @param {String} code
218 | * @return {CodeSerializationInstruction}
219 | */
220 | setCode: function ( code ) {
221 |
222 | this.code = code;
223 | return this;
224 |
225 | },
226 |
227 | /**
228 | * Returns the serialized function code
229 | * @return {String}
230 | */
231 | getCode: function () {
232 |
233 | return this.code;
234 |
235 | },
236 |
237 | /**
238 | * Set if function should be removed
239 | * @param {boolean} removeCode
240 | * @return {CodeSerializationInstruction}
241 | */
242 | setRemoveCode: function ( removeCode ) {
243 |
244 | this.removeCode = removeCode;
245 | return this;
246 |
247 | },
248 |
249 | /**
250 | * If function should be completely removed
251 | * @return {boolean}
252 | */
253 | isRemoveCode: function () {
254 |
255 | return this.removeCode;
256 |
257 | }
258 |
259 | };
260 |
261 | export {
262 | CodeSerializer,
263 | CodeSerializationInstruction
264 | };
265 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/obj2/worker/parallel/OBJLoader2JsmWorker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Development repository: https://github.com/kaisalmen/WWOBJLoader
3 | */
4 |
5 | import { OBJLoader2Parser } from '../../OBJLoader2Parser.js';
6 |
7 | import {
8 | WorkerRunner,
9 | DefaultWorkerPayloadHandler
10 | } from './WorkerRunner.js';
11 |
12 | new WorkerRunner( new DefaultWorkerPayloadHandler( new OBJLoader2Parser() ) );
13 |
--------------------------------------------------------------------------------
/libs/three.js/loaders/obj2/worker/parallel/WorkerRunner.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Development repository: https://github.com/kaisalmen/WWOBJLoader
3 | */
4 |
5 | const ObjectManipulator = function () {
6 | };
7 |
8 | ObjectManipulator.prototype = {
9 |
10 | constructor: ObjectManipulator,
11 |
12 | /**
13 | * Applies values from parameter object via set functions or via direct assignment.
14 | *
15 | * @param {Object} objToAlter The objToAlter instance
16 | * @param {Object} params The parameter object
17 | * @param {boolean} forceCreation Force the creation of a property
18 | */
19 | applyProperties: function ( objToAlter, params, forceCreation ) {
20 |
21 | // fast-fail
22 | if ( objToAlter === undefined || objToAlter === null || params === undefined || params === null ) return;
23 |
24 | let property, funcName, values;
25 | for ( property in params ) {
26 |
27 | funcName = 'set' + property.substring( 0, 1 ).toLocaleUpperCase() + property.substring( 1 );
28 | values = params[ property ];
29 |
30 | if ( typeof objToAlter[ funcName ] === 'function' ) {
31 |
32 | objToAlter[ funcName ]( values );
33 |
34 | } else if ( objToAlter.hasOwnProperty( property ) || forceCreation ) {
35 |
36 | objToAlter[ property ] = values;
37 |
38 | }
39 |
40 | }
41 |
42 | }
43 | };
44 |
45 | const DefaultWorkerPayloadHandler = function ( parser ) {
46 |
47 | this.parser = parser;
48 | this.logging = {
49 | enabled: false,
50 | debug: false
51 | };
52 |
53 | };
54 |
55 | DefaultWorkerPayloadHandler.prototype = {
56 |
57 | constructor: DefaultWorkerPayloadHandler,
58 |
59 | handlePayload: function ( payload ) {
60 |
61 | if ( payload.logging ) {
62 |
63 | this.logging.enabled = payload.logging.enabled === true;
64 | this.logging.debug = payload.logging.debug === true;
65 |
66 | }
67 |
68 | if ( payload.cmd === 'parse' ) {
69 |
70 | const scope = this;
71 | const callbacks = {
72 | callbackOnAssetAvailable: function ( payload ) {
73 |
74 | self.postMessage( payload );
75 |
76 | },
77 | callbackOnProgress: function ( text ) {
78 |
79 | if ( scope.logging.enabled && scope.logging.debug ) console.debug( 'WorkerRunner: progress: ' + text );
80 |
81 | }
82 | };
83 |
84 | const parser = this.parser;
85 | if ( typeof parser[ 'setLogging' ] === 'function' ) {
86 |
87 | parser.setLogging( this.logging.enabled, this.logging.debug );
88 |
89 | }
90 |
91 | const objectManipulator = new ObjectManipulator();
92 | objectManipulator.applyProperties( parser, payload.params, false );
93 | objectManipulator.applyProperties( parser, callbacks, false );
94 |
95 | const arraybuffer = payload.data.input;
96 | let executeFunctionName = 'execute';
97 | if ( typeof parser.getParseFunctionName === 'function' ) executeFunctionName = parser.getParseFunctionName();
98 | if ( payload.usesMeshDisassembler ) {
99 |
100 | // TODO: Allow to plug and use generic MeshDisassembler
101 |
102 | } else {
103 |
104 | parser[ executeFunctionName ]( arraybuffer, payload.data.options );
105 |
106 | }
107 |
108 | if ( this.logging.enabled ) console.log( 'WorkerRunner: Run complete!' );
109 |
110 | self.postMessage( {
111 | cmd: 'completeOverall',
112 | msg: 'WorkerRunner completed run.'
113 | } );
114 |
115 | } else {
116 |
117 | console.error( 'WorkerRunner: Received unknown command: ' + payload.cmd );
118 |
119 | }
120 |
121 | }
122 | };
123 |
124 |
125 | /**
126 | * Default implementation of the WorkerRunner responsible for creation and configuration of the parser within the worker.
127 | * @constructor
128 | */
129 | const WorkerRunner = function ( payloadHandler ) {
130 |
131 | this.payloadHandler = payloadHandler;
132 |
133 | const scope = this;
134 | const scopedRunner = function ( event ) {
135 |
136 | scope.processMessage( event.data );
137 |
138 | };
139 |
140 | self.addEventListener( 'message', scopedRunner, false );
141 |
142 | };
143 |
144 | WorkerRunner.prototype = {
145 |
146 | constructor: WorkerRunner,
147 |
148 | /**
149 | * Configures the Parser implementation according the supplied configuration object.
150 | *
151 | * @param {Object} payload Raw mesh description (buffers, params, materials) used to build one to many meshes.
152 | */
153 | processMessage: function ( payload ) {
154 |
155 | this.payloadHandler.handlePayload( payload );
156 |
157 | }
158 |
159 | };
160 |
161 | export {
162 | WorkerRunner,
163 | DefaultWorkerPayloadHandler,
164 | ObjectManipulator
165 | };
166 |
--------------------------------------------------------------------------------
/libs/three.js/webxr/ARButton.js:
--------------------------------------------------------------------------------
1 | class ARButton {
2 |
3 | static createButton( renderer, sessionInit = {} ) {
4 |
5 | const button = document.createElement( 'button' );
6 |
7 | function showStartAR( /*device*/ ) {
8 |
9 | if ( sessionInit.domOverlay === undefined ) {
10 |
11 | var overlay = document.createElement( 'div' );
12 | overlay.style.display = 'none';
13 | document.body.appendChild( overlay );
14 |
15 | var svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' );
16 | svg.setAttribute( 'width', 38 );
17 | svg.setAttribute( 'height', 38 );
18 | svg.style.position = 'absolute';
19 | svg.style.right = '20px';
20 | svg.style.top = '20px';
21 | svg.addEventListener( 'click', function () {
22 |
23 | currentSession.end();
24 |
25 | } );
26 | overlay.appendChild( svg );
27 |
28 | var path = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' );
29 | path.setAttribute( 'd', 'M 12,12 L 28,28 M 28,12 12,28' );
30 | path.setAttribute( 'stroke', '#fff' );
31 | path.setAttribute( 'stroke-width', 2 );
32 | svg.appendChild( path );
33 |
34 | sessionInit.optionalFeatures = [ 'dom-overlay' ];
35 | sessionInit.domOverlay = { root: overlay };
36 |
37 | }
38 |
39 | //
40 |
41 | let currentSession = null;
42 |
43 | function onSessionStarted( session ) {
44 |
45 | session.addEventListener( 'end', onSessionEnded );
46 |
47 | renderer.xr.setReferenceSpaceType( 'local' );
48 | renderer.xr.setSession( session );
49 |
50 | button.textContent = 'STOP AR';
51 | sessionInit.domOverlay.root.style.display = '';
52 |
53 | currentSession = session;
54 |
55 | }
56 |
57 | function onSessionEnded( /*event*/ ) {
58 |
59 | currentSession.removeEventListener( 'end', onSessionEnded );
60 |
61 | button.textContent = 'START AR';
62 | sessionInit.domOverlay.root.style.display = 'none';
63 |
64 | currentSession = null;
65 |
66 | }
67 |
68 | //
69 |
70 | button.style.display = '';
71 |
72 | button.style.cursor = 'pointer';
73 | button.style.left = 'calc(50% - 50px)';
74 | button.style.width = '100px';
75 |
76 | button.textContent = 'START AR';
77 |
78 | button.onmouseenter = function () {
79 |
80 | button.style.opacity = '1.0';
81 |
82 | };
83 |
84 | button.onmouseleave = function () {
85 |
86 | button.style.opacity = '0.5';
87 |
88 | };
89 |
90 | button.onclick = function () {
91 |
92 | if ( currentSession === null ) {
93 |
94 | navigator.xr.requestSession( 'immersive-ar', sessionInit ).then( onSessionStarted );
95 |
96 | } else {
97 |
98 | currentSession.end();
99 |
100 | }
101 |
102 | };
103 |
104 | }
105 |
106 | function disableButton() {
107 |
108 | button.style.display = '';
109 |
110 | button.style.cursor = 'auto';
111 | button.style.left = 'calc(50% - 75px)';
112 | button.style.width = '150px';
113 |
114 | button.onmouseenter = null;
115 | button.onmouseleave = null;
116 |
117 | button.onclick = null;
118 |
119 | }
120 |
121 | function showARNotSupported() {
122 |
123 | disableButton();
124 |
125 | button.textContent = 'AR NOT SUPPORTED';
126 |
127 | }
128 |
129 | function stylizeElement( element ) {
130 |
131 | element.style.position = 'absolute';
132 | element.style.bottom = '20px';
133 | element.style.padding = '12px 6px';
134 | element.style.border = '1px solid #fff';
135 | element.style.borderRadius = '4px';
136 | element.style.background = 'rgba(0,0,0,0.1)';
137 | element.style.color = '#fff';
138 | element.style.font = 'normal 13px sans-serif';
139 | element.style.textAlign = 'center';
140 | element.style.opacity = '0.5';
141 | element.style.outline = 'none';
142 | element.style.zIndex = '999';
143 |
144 | }
145 |
146 | if ( 'xr' in navigator ) {
147 |
148 | button.id = 'ARButton';
149 | button.style.display = 'none';
150 |
151 | stylizeElement( button );
152 |
153 | navigator.xr.isSessionSupported( 'immersive-ar' ).then( function ( supported ) {
154 |
155 | supported ? showStartAR() : showARNotSupported();
156 |
157 | } ).catch( showARNotSupported );
158 |
159 | return button;
160 |
161 | } else {
162 |
163 | const message = document.createElement( 'a' );
164 |
165 | if ( window.isSecureContext === false ) {
166 |
167 | message.href = document.location.href.replace( /^http:/, 'https:' );
168 | message.innerHTML = 'WEBXR NEEDS HTTPS'; // TODO Improve message
169 |
170 | } else {
171 |
172 | message.href = 'https://immersiveweb.dev/';
173 | message.innerHTML = 'WEBXR NOT AVAILABLE';
174 |
175 | }
176 |
177 | message.style.left = 'calc(50% - 90px)';
178 | message.style.width = '180px';
179 | message.style.textDecoration = 'none';
180 |
181 | stylizeElement( message );
182 |
183 | return message;
184 |
185 | }
186 |
187 | }
188 |
189 | }
190 |
191 | export { ARButton };
192 |
--------------------------------------------------------------------------------
/libs/three.js/webxr/VRButton.js:
--------------------------------------------------------------------------------
1 | class VRButton {
2 |
3 | static createButton( renderer, options ) {
4 |
5 | if ( options ) {
6 |
7 | console.error( 'THREE.VRButton: The "options" parameter has been removed. Please set the reference space type via renderer.xr.setReferenceSpaceType() instead.' );
8 |
9 | }
10 |
11 | const button = document.createElement( 'button' );
12 |
13 | function showEnterVR( /*device*/ ) {
14 |
15 | let currentSession = null;
16 |
17 | function onSessionStarted( session ) {
18 |
19 | session.addEventListener( 'end', onSessionEnded );
20 |
21 | renderer.xr.setSession( session );
22 | button.textContent = 'EXIT VR';
23 |
24 | currentSession = session;
25 |
26 | }
27 |
28 | function onSessionEnded( /*event*/ ) {
29 |
30 | currentSession.removeEventListener( 'end', onSessionEnded );
31 |
32 | button.textContent = 'ENTER VR';
33 |
34 | currentSession = null;
35 |
36 | }
37 |
38 | //
39 |
40 | button.style.display = '';
41 |
42 | button.style.cursor = 'pointer';
43 | button.style.left = 'calc(50% - 50px)';
44 | button.style.width = '100px';
45 |
46 | button.textContent = 'ENTER VR';
47 |
48 | button.onmouseenter = function () {
49 |
50 | button.style.opacity = '1.0';
51 |
52 | };
53 |
54 | button.onmouseleave = function () {
55 |
56 | button.style.opacity = '0.5';
57 |
58 | };
59 |
60 | button.onclick = function () {
61 |
62 | if ( currentSession === null ) {
63 |
64 | // WebXR's requestReferenceSpace only works if the corresponding feature
65 | // was requested at session creation time. For simplicity, just ask for
66 | // the interesting ones as optional features, but be aware that the
67 | // requestReferenceSpace call will fail if it turns out to be unavailable.
68 | // ('local' is always available for immersive sessions and doesn't need to
69 | // be requested separately.)
70 |
71 | const sessionInit = { optionalFeatures: [ 'local-floor', 'bounded-floor', 'hand-tracking' ] };
72 | navigator.xr.requestSession( 'immersive-vr', sessionInit ).then( onSessionStarted );
73 |
74 | } else {
75 |
76 | currentSession.end();
77 |
78 | }
79 |
80 | };
81 |
82 | }
83 |
84 | function disableButton() {
85 |
86 | button.style.display = '';
87 |
88 | button.style.cursor = 'auto';
89 | button.style.left = 'calc(50% - 75px)';
90 | button.style.width = '150px';
91 |
92 | button.onmouseenter = null;
93 | button.onmouseleave = null;
94 |
95 | button.onclick = null;
96 |
97 | }
98 |
99 | function showWebXRNotFound() {
100 |
101 | disableButton();
102 |
103 | button.textContent = 'VR NOT SUPPORTED';
104 |
105 | }
106 |
107 | function stylizeElement( element ) {
108 |
109 | element.style.position = 'absolute';
110 | element.style.bottom = '20px';
111 | element.style.padding = '12px 6px';
112 | element.style.border = '1px solid #fff';
113 | element.style.borderRadius = '4px';
114 | element.style.background = 'rgba(0,0,0,0.1)';
115 | element.style.color = '#fff';
116 | element.style.font = 'normal 13px sans-serif';
117 | element.style.textAlign = 'center';
118 | element.style.opacity = '0.5';
119 | element.style.outline = 'none';
120 | element.style.zIndex = '999';
121 |
122 | }
123 |
124 | if ( 'xr' in navigator ) {
125 |
126 | button.id = 'VRButton';
127 | button.style.display = 'none';
128 |
129 | stylizeElement( button );
130 |
131 | navigator.xr.isSessionSupported( 'immersive-vr' ).then( function ( supported ) {
132 |
133 | supported ? showEnterVR() : showWebXRNotFound();
134 |
135 | } );
136 |
137 | return button;
138 |
139 | } else {
140 |
141 | const message = document.createElement( 'a' );
142 |
143 | if ( window.isSecureContext === false ) {
144 |
145 | message.href = document.location.href.replace( /^http:/, 'https:' );
146 | message.innerHTML = 'WEBXR NEEDS HTTPS'; // TODO Improve message
147 |
148 | } else {
149 |
150 | message.href = 'https://immersiveweb.dev/';
151 | message.innerHTML = 'WEBXR NOT AVAILABLE';
152 |
153 | }
154 |
155 | message.style.left = 'calc(50% - 90px)';
156 | message.style.width = '180px';
157 | message.style.textDecoration = 'none';
158 |
159 | stylizeElement( message );
160 |
161 | return message;
162 |
163 | }
164 |
165 | }
166 |
167 | }
168 |
169 | export { VRButton };
170 |
--------------------------------------------------------------------------------
/libs/three.js/webxr/XRHandModelFactory.js:
--------------------------------------------------------------------------------
1 | import {
2 | Object3D
3 | } from '../../../build/three.module.js';
4 |
5 | import {
6 | XRHandPrimitiveModel
7 | } from './XRHandPrimitiveModel.js';
8 |
9 | import {
10 | XRHandOculusMeshModel
11 | } from './XRHandOculusMeshModel.js';
12 |
13 | function XRHandModel( controller ) {
14 |
15 | Object3D.call( this );
16 |
17 | this.controller = controller;
18 | this.motionController = null;
19 | this.envMap = null;
20 |
21 | this.mesh = null;
22 |
23 | }
24 |
25 | XRHandModel.prototype = Object.assign( Object.create( Object3D.prototype ), {
26 |
27 | constructor: XRHandModel,
28 |
29 | updateMatrixWorld: function ( force ) {
30 |
31 | Object3D.prototype.updateMatrixWorld.call( this, force );
32 |
33 | if ( this.motionController ) {
34 |
35 | this.motionController.updateMesh();
36 |
37 | }
38 |
39 | },
40 | } );
41 |
42 |
43 | const XRHandModelFactory = ( function () {
44 |
45 | function XRHandModelFactory() {
46 |
47 | this.path = '';
48 |
49 | }
50 |
51 | XRHandModelFactory.prototype = {
52 |
53 | constructor: XRHandModelFactory,
54 |
55 | setPath: function ( path ) {
56 |
57 | this.path = path;
58 | return this;
59 |
60 | },
61 |
62 | createHandModel: function ( controller, profile, options ) {
63 |
64 | const handModel = new XRHandModel( controller );
65 |
66 | controller.addEventListener( 'connected', ( event ) => {
67 |
68 | const xrInputSource = event.data;
69 |
70 | if ( xrInputSource.hand && ! handModel.motionController ) {
71 |
72 | handModel.visible = true;
73 | handModel.xrInputSource = xrInputSource;
74 |
75 | // @todo Detect profile if not provided
76 | if ( profile === undefined || profile === 'spheres' ) {
77 |
78 | handModel.motionController = new XRHandPrimitiveModel( handModel, controller, this.path, xrInputSource.handedness, { primitive: 'sphere' } );
79 |
80 | } else if ( profile === 'boxes' ) {
81 |
82 | handModel.motionController = new XRHandPrimitiveModel( handModel, controller, this.path, xrInputSource.handedness, { primitive: 'box' } );
83 |
84 | } else if ( profile === 'oculus' ) {
85 |
86 | handModel.motionController = new XRHandOculusMeshModel( handModel, controller, this.path, xrInputSource.handedness, options );
87 |
88 | }
89 |
90 | }
91 |
92 | } );
93 |
94 | controller.addEventListener( 'disconnected', () => {
95 |
96 | // handModel.motionController = null;
97 | // handModel.remove( scene );
98 | // scene = null;
99 |
100 | } );
101 |
102 | return handModel;
103 |
104 | }
105 |
106 | };
107 |
108 | return XRHandModelFactory;
109 |
110 | } )();
111 |
112 |
113 | export { XRHandModelFactory };
114 |
--------------------------------------------------------------------------------
/libs/three.js/webxr/XRHandOculusMeshModel.js:
--------------------------------------------------------------------------------
1 | import { FBXLoader } from '../loaders/FBXLoader.js';
2 |
3 | class XRHandOculusMeshModel {
4 |
5 | constructor( handModel, controller, path, handedness, options ) {
6 |
7 | this.controller = controller;
8 | this.handModel = handModel;
9 |
10 | this.bones = [];
11 | const loader = new FBXLoader();
12 | const low = options && options.model === 'lowpoly' ? '_low' : '';
13 |
14 | loader.setPath( path );
15 | loader.load( `OculusHand_${handedness === 'right' ? 'R' : 'L'}${low}.fbx`, object => {
16 |
17 | this.handModel.add( object );
18 | // Hack because of the scale of the skinnedmesh
19 | object.scale.setScalar( 0.01 );
20 |
21 | const mesh = object.getObjectByProperty( 'type', 'SkinnedMesh' );
22 | mesh.frustumCulled = false;
23 | mesh.castShadow = true;
24 | mesh.receiveShadow = true;
25 |
26 | const bonesMapping = [
27 | 'b_%_wrist', // XRHand.WRIST,
28 |
29 | 'b_%_thumb1', // XRHand.THUMB_METACARPAL,
30 | 'b_%_thumb2', // XRHand.THUMB_PHALANX_PROXIMAL,
31 | 'b_%_thumb3', // XRHand.THUMB_PHALANX_DISTAL,
32 | 'b_%_thumb_null', // XRHand.THUMB_PHALANX_TIP,
33 |
34 | null, //'b_%_index1', // XRHand.INDEX_METACARPAL,
35 | 'b_%_index1', // XRHand.INDEX_PHALANX_PROXIMAL,
36 | 'b_%_index2', // XRHand.INDEX_PHALANX_INTERMEDIATE,
37 | 'b_%_index3', // XRHand.INDEX_PHALANX_DISTAL,
38 | 'b_%_index_null', // XRHand.INDEX_PHALANX_TIP,
39 |
40 | null, //'b_%_middle1', // XRHand.MIDDLE_METACARPAL,
41 | 'b_%_middle1', // XRHand.MIDDLE_PHALANX_PROXIMAL,
42 | 'b_%_middle2', // XRHand.MIDDLE_PHALANX_INTERMEDIATE,
43 | 'b_%_middle3', // XRHand.MIDDLE_PHALANX_DISTAL,
44 | 'b_%_middlenull', // XRHand.MIDDLE_PHALANX_TIP,
45 |
46 | null, //'b_%_ring1', // XRHand.RING_METACARPAL,
47 | 'b_%_ring1', // XRHand.RING_PHALANX_PROXIMAL,
48 | 'b_%_ring2', // XRHand.RING_PHALANX_INTERMEDIATE,
49 | 'b_%_ring3', // XRHand.RING_PHALANX_DISTAL,
50 | 'b_%_ring_inull', // XRHand.RING_PHALANX_TIP,
51 |
52 | 'b_%_pinky0', // XRHand.LITTLE_METACARPAL,
53 | 'b_%_pinky1', // XRHand.LITTLE_PHALANX_PROXIMAL,
54 | 'b_%_pinky2', // XRHand.LITTLE_PHALANX_INTERMEDIATE,
55 | 'b_%_pinky3', // XRHand.LITTLE_PHALANX_DISTAL,
56 | 'b_%_pinkynull', // XRHand.LITTLE_PHALANX_TIP
57 | ];
58 | bonesMapping.forEach( boneName => {
59 |
60 | if ( boneName ) {
61 |
62 | const bone = object.getObjectByName( boneName.replace( /%/g, handedness === 'right' ? 'r' : 'l' ) );
63 | this.bones.push( bone );
64 |
65 | } else {
66 |
67 | this.bones.push( null );
68 |
69 | }
70 |
71 | } );
72 |
73 | } );
74 |
75 | }
76 |
77 | updateMesh() {
78 |
79 | // XR Joints
80 | const XRJoints = this.controller.joints;
81 | for ( let i = 0; i < this.bones.length; i ++ ) {
82 |
83 | const bone = this.bones[ i ];
84 | const XRJoint = XRJoints[ i ];
85 |
86 | if ( XRJoint ) {
87 |
88 | if ( XRJoint.visible ) {
89 |
90 | const position = XRJoint.position;
91 |
92 | if ( bone ) {
93 |
94 | bone.position.copy( position.clone().multiplyScalar( 100 ) );
95 | bone.quaternion.copy( XRJoint.quaternion );
96 | // bone.scale.setScalar( XRJoint.jointRadius || defaultRadius );
97 |
98 | }
99 |
100 | }
101 |
102 | }
103 |
104 | }
105 |
106 | }
107 |
108 | }
109 |
110 | export { XRHandOculusMeshModel };
111 |
--------------------------------------------------------------------------------
/libs/three.js/webxr/XRHandPrimitiveModel.js:
--------------------------------------------------------------------------------
1 | import {
2 | SphereBufferGeometry,
3 | BoxBufferGeometry,
4 | MeshStandardMaterial,
5 | Mesh,
6 | Group
7 | } from '../../../build/three.module.js';
8 |
9 | class XRHandPrimitiveModel {
10 |
11 | constructor( handModel, controller, path, handedness, options ) {
12 |
13 | this.controller = controller;
14 | this.handModel = handModel;
15 |
16 | this.envMap = null;
17 |
18 | this.handMesh = new Group();
19 | this.handModel.add( this.handMesh );
20 |
21 | if ( window.XRHand ) {
22 |
23 | let geometry;
24 |
25 | if ( ! options || ! options.primitive || options.primitive === 'sphere' ) {
26 |
27 | geometry = new SphereBufferGeometry( 1, 10, 10 );
28 |
29 | } else if ( options.primitive === 'box' ) {
30 |
31 | geometry = new BoxBufferGeometry( 1, 1, 1 );
32 |
33 | }
34 |
35 | const jointMaterial = new MeshStandardMaterial( { color: 0xffffff, roughness: 1, metalness: 0 } );
36 | const tipMaterial = new MeshStandardMaterial( { color: 0x999999, roughness: 1, metalness: 0 } );
37 |
38 | const tipIndexes = [
39 | window.XRHand.THUMB_PHALANX_TIP,
40 | window.XRHand.INDEX_PHALANX_TIP,
41 | window.XRHand.MIDDLE_PHALANX_TIP,
42 | window.XRHand.RING_PHALANX_TIP,
43 | window.XRHand.LITTLE_PHALANX_TIP
44 | ];
45 | for ( let i = 0; i <= window.XRHand.LITTLE_PHALANX_TIP; i ++ ) {
46 |
47 | var cube = new Mesh( geometry, tipIndexes.indexOf( i ) !== - 1 ? tipMaterial : jointMaterial );
48 | cube.castShadow = true;
49 | cube.receiveShadow = true;
50 | this.handMesh.add( cube );
51 |
52 | }
53 |
54 | }
55 |
56 | }
57 |
58 | updateMesh() {
59 |
60 | const defaultRadius = 0.008;
61 | const objects = this.handMesh.children;
62 |
63 | // XR Joints
64 | const XRJoints = this.controller.joints;
65 |
66 | for ( let i = 0; i < objects.length; i ++ ) {
67 |
68 | const jointMesh = objects[ i ];
69 | const XRJoint = XRJoints[ i ];
70 |
71 | if ( XRJoint.visible ) {
72 |
73 | jointMesh.position.copy( XRJoint.position );
74 | jointMesh.quaternion.copy( XRJoint.quaternion );
75 | jointMesh.scale.setScalar( XRJoint.jointRadius || defaultRadius );
76 |
77 | }
78 |
79 | jointMesh.visible = XRJoint.visible;
80 |
81 | }
82 |
83 | }
84 |
85 | }
86 |
87 | export { XRHandPrimitiveModel };
88 |
--------------------------------------------------------------------------------
/small_garage.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LetsGo Viewer
6 |
7 |
9 |
10 |
11 |
151 |
152 |
153 |
154 |
157 |
158 |
LetsGo Viewer
159 |
160 |
161 |
162 |
163 |
164 |
Instructions
165 |
166 | - W/S arrow keys to move forward/back
167 | - A/D arrow keys to move left/right
168 | - space to play the video (if available)
169 |
170 | camera angle (wasd)
171 | - q/e to roll camera counterclockwise/clockwise
172 |
173 | trackpad
174 | - scroll up/down/left/right to orbit
175 | - pinch to move forward/back
176 | - ctrl key + scroll to move forward/back
177 | - shift + scroll to move up/down or strafe
178 |
179 | mouse
180 | - click and drag to orbit
181 | - right click (or ctrl/cmd key) and drag up/down to move
182 |
183 | touch (mobile)
184 | - one finger to orbit
185 | - two finger pinch to move forward/back
186 | - two finger rotate to rotate camera clockwise/counterclockwise
187 | - two finger pan to move side-to-side and up-down
188 |
189 | other
190 | - press p to resume default animation
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
205 |
206 |
207 | Load Resources 0Mb...(0%)
208 |
209 |
210 |
211 |
212 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
--------------------------------------------------------------------------------
/src/gaussian-utils/WorkerPool.js:
--------------------------------------------------------------------------------
1 |
2 | export class WorkerPool{
3 | constructor(){
4 | this.workers = {};
5 | }
6 |
7 | getWorker(url){
8 | if (!this.workers[url]){
9 | this.workers[url] = [];
10 | }
11 |
12 | if (this.workers[url].length === 0){
13 | let worker = new Worker(url);
14 | this.workers[url].push(worker);
15 | }
16 |
17 | let worker = this.workers[url].pop();
18 |
19 | return worker;
20 | }
21 |
22 | returnWorker(url, worker){
23 | this.workers[url].push(worker);
24 | }
25 | };
26 |
27 | //Potree.workerPool = new Potree.WorkerPool();
28 |
--------------------------------------------------------------------------------
/src/gaussian-utils/gaussian-attributes.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Some types of possible point attribute data formats
4 | * modified from potree\src\loader\PointAttributes.js
5 | * @class
6 | * update by Fuqiang Zhao
7 | */
8 | const PointAttributeTypes = {
9 | DATA_TYPE_DOUBLE: {ordinal: 0, name: "double", size: 8},
10 | DATA_TYPE_FLOAT: {ordinal: 1, name: "float", size: 4},
11 | DATA_TYPE_INT8: {ordinal: 2, name: "int8", size: 1},
12 | DATA_TYPE_UINT8: {ordinal: 3, name: "uint8", size: 1},
13 | DATA_TYPE_INT16: {ordinal: 4, name: "int16", size: 2},
14 | DATA_TYPE_UINT16: {ordinal: 5, name: "uint16", size: 2},
15 | DATA_TYPE_INT32: {ordinal: 6, name: "int32", size: 4},
16 | DATA_TYPE_UINT32: {ordinal: 7, name: "uint32", size: 4},
17 | DATA_TYPE_INT64: {ordinal: 8, name: "int64", size: 8},
18 | DATA_TYPE_UINT64: {ordinal: 9, name: "uint64", size: 8}
19 | };
20 |
21 | let i = 0;
22 | for (let obj in PointAttributeTypes) {
23 | PointAttributeTypes[i] = PointAttributeTypes[obj];
24 | i++;
25 | }
26 |
27 | export {PointAttributeTypes};
28 |
29 |
30 | class PointAttribute{
31 |
32 | constructor(name, type, numElements){
33 | this.name = name;
34 | this.type = type;
35 | this.numElements = numElements;
36 | this.byteSize = this.numElements * this.type.size;
37 | this.description = "";
38 | this.range = [Infinity, -Infinity];
39 | }
40 |
41 | };
42 |
43 | PointAttribute.POSITION_CARTESIAN = new PointAttribute(
44 | "POSITION_CARTESIAN", PointAttributeTypes.DATA_TYPE_FLOAT, 3);
45 |
46 | PointAttribute.RGBA_PACKED = new PointAttribute(
47 | "COLOR_PACKED", PointAttributeTypes.DATA_TYPE_INT8, 4);
48 |
49 | PointAttribute.COLOR_PACKED = PointAttribute.RGBA_PACKED;
50 |
51 | PointAttribute.RGB_PACKED = new PointAttribute(
52 | "COLOR_PACKED", PointAttributeTypes.DATA_TYPE_INT8, 3);
53 |
54 | PointAttribute.NORMAL_FLOATS = new PointAttribute(
55 | "NORMAL_FLOATS", PointAttributeTypes.DATA_TYPE_FLOAT, 3);
56 |
57 | PointAttribute.INTENSITY = new PointAttribute(
58 | "INTENSITY", PointAttributeTypes.DATA_TYPE_UINT16, 1);
59 |
60 | PointAttribute.CLASSIFICATION = new PointAttribute(
61 | "CLASSIFICATION", PointAttributeTypes.DATA_TYPE_UINT8, 1);
62 |
63 | PointAttribute.NORMAL_SPHEREMAPPED = new PointAttribute(
64 | "NORMAL_SPHEREMAPPED", PointAttributeTypes.DATA_TYPE_UINT8, 2);
65 |
66 | PointAttribute.NORMAL_OCT16 = new PointAttribute(
67 | "NORMAL_OCT16", PointAttributeTypes.DATA_TYPE_UINT8, 2);
68 |
69 | PointAttribute.NORMAL = new PointAttribute(
70 | "NORMAL", PointAttributeTypes.DATA_TYPE_FLOAT, 3);
71 |
72 | PointAttribute.RETURN_NUMBER = new PointAttribute(
73 | "RETURN_NUMBER", PointAttributeTypes.DATA_TYPE_UINT8, 1);
74 |
75 | PointAttribute.NUMBER_OF_RETURNS = new PointAttribute(
76 | "NUMBER_OF_RETURNS", PointAttributeTypes.DATA_TYPE_UINT8, 1);
77 |
78 | PointAttribute.SOURCE_ID = new PointAttribute(
79 | "SOURCE_ID", PointAttributeTypes.DATA_TYPE_UINT16, 1);
80 |
81 | PointAttribute.INDICES = new PointAttribute(
82 | "INDICES", PointAttributeTypes.DATA_TYPE_UINT32, 1);
83 |
84 | PointAttribute.SPACING = new PointAttribute(
85 | "SPACING", PointAttributeTypes.DATA_TYPE_FLOAT, 1);
86 |
87 | PointAttribute.GPS_TIME = new PointAttribute(
88 | "GPS_TIME", PointAttributeTypes.DATA_TYPE_DOUBLE, 1);
89 |
90 | export {PointAttribute};
91 |
92 | export class PointAttributes{
93 |
94 | constructor(pointAttributes){
95 | this.attributes = [];
96 | this.byteSize = 0;
97 | this.size = 0;
98 | this.vectors = [];
99 |
100 | if (pointAttributes != null) {
101 | for (let i = 0; i < pointAttributes.length; i++) {
102 | let pointAttributeName = pointAttributes[i];
103 | let pointAttribute = PointAttribute[pointAttributeName];
104 | this.attributes.push(pointAttribute);
105 | this.byteSize += pointAttribute.byteSize;
106 | this.size++;
107 | }
108 | }
109 | }
110 |
111 |
112 | add(pointAttribute){
113 | this.attributes.push(pointAttribute);
114 | this.byteSize += pointAttribute.byteSize;
115 | this.size++;
116 | };
117 |
118 | addVector(vector){
119 | this.vectors.push(vector);
120 | }
121 |
122 | hasNormals(){
123 | for (let name in this.attributes) {
124 | let pointAttribute = this.attributes[name];
125 | if (
126 | pointAttribute === PointAttribute.NORMAL_SPHEREMAPPED ||
127 | pointAttribute === PointAttribute.NORMAL_FLOATS ||
128 | pointAttribute === PointAttribute.NORMAL ||
129 | pointAttribute === PointAttribute.NORMAL_OCT16) {
130 | return true;
131 | }
132 | }
133 |
134 | return false;
135 | };
136 |
137 | }
138 |
--------------------------------------------------------------------------------
/src/gaussian-utils/gaussian-octree.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Some types of possible point attribute data formats
3 | * modified from potree\src\modules\loader\2.0\OctreeGeometry.js
4 | * @class
5 | * update by Fuqiang Zhao
6 | */
7 | import * as THREE from "../../libs/three.js/build/three.module.js";
8 | import {potree} from "../potree.js";
9 | export class OctreeGeometry{
10 | constructor(){
11 | this.url = null;
12 | this.spacing = 0;
13 | this.boundingBox = null;
14 | this.root = null;
15 | this.pointAttributes = null;
16 | this.loader = null;
17 | }
18 |
19 | };
20 |
21 | export class OctreeGeometryNode{
22 |
23 | constructor(name, octreeGeometry, boundingBox){
24 | this.id = OctreeGeometryNode.IDCount++;
25 | this.name = name;
26 | this.index = parseInt(name.charAt(name.length - 1));
27 | this.octreeGeometry = octreeGeometry;
28 | this.boundingBox = boundingBox;
29 | this.boundingSphere = boundingBox.getBoundingSphere(new THREE.Sphere());
30 | this.children = {};
31 | this.numPoints = 0;
32 | this.level = null;
33 | this.oneTimeDisposeHandlers = [];
34 | }
35 |
36 | isGeometryNode(){
37 | return true;
38 | }
39 |
40 | getLevel(){
41 | return this.level;
42 | }
43 |
44 | isTreeNode(){
45 | return false;
46 | }
47 |
48 | isLoaded(){
49 | return this.loaded;
50 | }
51 |
52 | getBoundingSphere(){
53 | return this.boundingSphere;
54 | }
55 |
56 | getBoundingBox(){
57 | return this.boundingBox;
58 | }
59 |
60 | getChildren(){
61 | let children = [];
62 |
63 | for (let i = 0; i < 8; i++) {
64 | if (this.children[i]) {
65 | children.push(this.children[i]);
66 | }
67 | }
68 |
69 | return children;
70 | }
71 |
72 | getBoundingBox(){
73 | return this.boundingBox;
74 | }
75 |
76 | load(){
77 |
78 | if (potree.numNodesLoading >= potree.maxNodesLoading) {
79 | return;
80 | }
81 |
82 | this.octreeGeometry.loader.load(this);
83 | }
84 |
85 | getNumPoints(){
86 | return this.numPoints;
87 | }
88 |
89 | dispose(){
90 | if (this.geometry && this.parent != null) {
91 | this.geometry.dispose();
92 | this.geometry = null;
93 | this.loaded = false;
94 |
95 | // this.dispatchEvent( { type: 'dispose' } );
96 | for (let i = 0; i < this.oneTimeDisposeHandlers.length; i++) {
97 | let handler = this.oneTimeDisposeHandlers[i];
98 | handler();
99 | }
100 | this.oneTimeDisposeHandlers = [];
101 | }
102 | }
103 |
104 | };
105 |
106 | OctreeGeometryNode.IDCount = 0;
--------------------------------------------------------------------------------
/src/indexedDB.js:
--------------------------------------------------------------------------------
1 | import localforage from "localforage";
2 |
3 |
4 | export async function canInsetToLocalDB() {
5 | let flag = true;
6 | if (navigator.storage && navigator.storage.estimate) {
7 | const quota = await navigator.storage.estimate();
8 | const percentageUsed = quota.usage / quota.quota;
9 | console.log('DB使用:', percentageUsed)
10 | if (percentageUsed > 0.8) {
11 | localforage.clear()
12 | flag = false;
13 | }
14 | }
15 | return flag
16 | }
17 |
18 | export async function localforageSetItem(key, value) {
19 | let canInsert = canInsetToLocalDB()
20 | if (!canInsert) {
21 | await localforage.clear()
22 | localforage.setItem(key, value);
23 | }
24 | else {
25 | localforage.setItem(key, value);
26 | }
27 | }
28 | export async function localforageGetItem(key) {
29 | const localData = await localforage.getItem(key);
30 | return localData;
31 | }
--------------------------------------------------------------------------------
/src/potree.js:
--------------------------------------------------------------------------------
1 |
2 | import { WorkerPool } from "./gaussian-utils/WorkerPool.js";
3 | import { OctreeLoader } from "./gaussian-utils/gaussian-octree-loader.js";
4 |
5 | export const workerPool = new WorkerPool();
6 |
7 | export const version = {
8 | major: 1,
9 | minor: 8,
10 | suffix: '.0'
11 | };
12 |
13 | // export let pointBudget = 1 * 1000 * 1000;
14 | // export let framenumber = 0;
15 | // export let numNodesLoading = 0;
16 | // export let maxNodesLoading = 4;
17 |
18 | export const potree = {
19 | pointBudget: 1 * 1000 * 1000,
20 | framenumber: 0,
21 | numNodesLoading: 0,
22 | maxNodesLoading: 4
23 | }
24 |
25 | export async function loadPointCloud(path, name, octreeFileUrl, callback) {
26 |
27 | let loaded = function (e) {
28 | e.geometry.name = name;
29 | callback(e);
30 | };
31 |
32 | let promise = new Promise(async (resolve, reject) => {
33 | // load pointcloud
34 | if (!path) {
35 | reject(new Error("Path is undefined or empty"));
36 | } else if (path.indexOf('metadata.json') > 0) {
37 | OctreeLoader.load(path, octreeFileUrl).then(e => {
38 | let geometry = e.geometry;
39 | if (!geometry) {
40 | console.error(new Error(`failed to load point cloud from URL: ${path}`));
41 | } else {
42 |
43 | resolve({ type: 'geometry', geometry: geometry });
44 | }
45 | }).catch(e => {
46 | console.error(new Error(`failed to load point cloud from URL: ${path}`));
47 | reject(e);
48 | });
49 | } else {
50 | //callback({'type': 'loading_failed'});
51 | reject(new Error(`Invalid path for point cloud: ${path}`));
52 | }
53 | });
54 |
55 | if (callback) {
56 | promise.then(pointcloud => {
57 | loaded(pointcloud);
58 | });
59 | } else {
60 | return promise;
61 | }
62 | }
--------------------------------------------------------------------------------
/src/public.js:
--------------------------------------------------------------------------------
1 | var host = window.location.host;
2 | var isLocal = !host.includes('47.120.55.223')
3 |
4 | var instructionsBtn = document.getElementById('instructions_title');
5 | var flat = true
6 | instructionsBtn.addEventListener('click', function () {
7 | console.log(flat)
8 | document.getElementById('instructions').style.display = flat ? "block" : "none"
9 | flat = !flat
10 | });
--------------------------------------------------------------------------------