t3d-3dtiles 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +41 -0
  3. package/build/t3d.3dtiles.js +5418 -0
  4. package/build/t3d.3dtiles.min.js +2 -0
  5. package/build/t3d.3dtiles.module.js +6183 -0
  6. package/examples/jsm/CesiumIon.js +30 -0
  7. package/examples/jsm/Tiles3DDebugger.js +219 -0
  8. package/examples/jsm/Tiles3DUtils.js +32 -0
  9. package/examples/jsm/helpers/LineSegmentHelper.js +74 -0
  10. package/examples/jsm/helpers/OBBHelper.js +48 -0
  11. package/examples/jsm/helpers/Tiles3DHelper.js +135 -0
  12. package/examples/jsm/math/Intersects.js +100 -0
  13. package/examples/jsm/math/LineSegment.js +234 -0
  14. package/package.json +57 -0
  15. package/src/Tiles3D.js +402 -0
  16. package/src/libs/ImageBitmapLoader.js +56 -0
  17. package/src/libs/glTF/Constants.js +85 -0
  18. package/src/libs/glTF/GLTFLoader.js +169 -0
  19. package/src/libs/glTF/GLTFResource.js +28 -0
  20. package/src/libs/glTF/GLTFUtils.js +131 -0
  21. package/src/libs/glTF/extensions/EXT_meshopt_compression.js +35 -0
  22. package/src/libs/glTF/extensions/KHR_draco_mesh_compression.js +54 -0
  23. package/src/libs/glTF/extensions/KHR_lights_punctual.js +53 -0
  24. package/src/libs/glTF/extensions/KHR_materials_clearcoat.js +42 -0
  25. package/src/libs/glTF/extensions/KHR_materials_pbrSpecularGlossiness.js +53 -0
  26. package/src/libs/glTF/extensions/KHR_materials_unlit.js +13 -0
  27. package/src/libs/glTF/extensions/KHR_texture_basisu.js +14 -0
  28. package/src/libs/glTF/extensions/KHR_texture_transform.js +31 -0
  29. package/src/libs/glTF/parsers/AccessorParser.js +99 -0
  30. package/src/libs/glTF/parsers/AnimationParser.js +118 -0
  31. package/src/libs/glTF/parsers/BufferParser.js +35 -0
  32. package/src/libs/glTF/parsers/BufferViewParser.js +27 -0
  33. package/src/libs/glTF/parsers/ImageParser.js +97 -0
  34. package/src/libs/glTF/parsers/IndexParser.js +22 -0
  35. package/src/libs/glTF/parsers/MaterialParser.js +146 -0
  36. package/src/libs/glTF/parsers/NodeParser.js +145 -0
  37. package/src/libs/glTF/parsers/PrimitiveParser.js +289 -0
  38. package/src/libs/glTF/parsers/ReferenceParser.js +67 -0
  39. package/src/libs/glTF/parsers/SceneParser.js +41 -0
  40. package/src/libs/glTF/parsers/SkinParser.js +53 -0
  41. package/src/libs/glTF/parsers/TextureParser.js +71 -0
  42. package/src/libs/glTF/parsers/Validator.js +16 -0
  43. package/src/loaders/B3DMLoader.js +49 -0
  44. package/src/loaders/CMPTLoader.js +48 -0
  45. package/src/loaders/I3DMLoader.js +49 -0
  46. package/src/loaders/PNTSLoader.js +20 -0
  47. package/src/loaders/TileGLTFLoader.js +17 -0
  48. package/src/loaders/parsers/HeaderParser.js +104 -0
  49. package/src/loaders/parsers/LoadParser.js +22 -0
  50. package/src/loaders/parsers/TableParser.js +66 -0
  51. package/src/loaders/parsers/b3dm/B3DMParser.js +18 -0
  52. package/src/loaders/parsers/b3dm/B3DMRootParser.js +22 -0
  53. package/src/loaders/parsers/b3dm/MaterialParser.js +156 -0
  54. package/src/loaders/parsers/cmpt/CMPTParser.js +37 -0
  55. package/src/loaders/parsers/cmpt/CMPTRootParser.js +44 -0
  56. package/src/loaders/parsers/gltf/IndexParser.js +24 -0
  57. package/src/loaders/parsers/i3dm/I3DMParser.js +28 -0
  58. package/src/loaders/parsers/i3dm/I3DMRootParser.js +123 -0
  59. package/src/loaders/parsers/i3dm/MaterialParser.js +152 -0
  60. package/src/loaders/parsers/i3dm/PrimitiveParser.js +291 -0
  61. package/src/loaders/parsers/pnts/PNTSRootParser.js +69 -0
  62. package/src/main.js +14 -0
  63. package/src/materials/InstancedBasicMaterial.js +32 -0
  64. package/src/materials/InstancedPBRMaterial.js +32 -0
  65. package/src/materials/InstancedShaderChunks.js +23 -0
  66. package/src/math/Ellipsoid.js +41 -0
  67. package/src/math/EllipsoidRegion.js +160 -0
  68. package/src/math/FastFrustum.js +49 -0
  69. package/src/math/GeoUtils.js +31 -0
  70. package/src/math/OBB.js +395 -0
  71. package/src/math/TileBoundingVolume.js +172 -0
  72. package/src/math/TileOBB.js +103 -0
  73. package/src/utils/BatchTable.js +14 -0
  74. package/src/utils/CameraList.js +131 -0
  75. package/src/utils/FeatureTable.js +107 -0
  76. package/src/utils/IntersectionUtils.js +136 -0
  77. package/src/utils/LRUCache.js +159 -0
  78. package/src/utils/ModelLoader.js +150 -0
  79. package/src/utils/PriorityQueue.js +102 -0
  80. package/src/utils/RequestState.js +17 -0
  81. package/src/utils/TilesLoader.js +386 -0
  82. package/src/utils/TilesScheduler.js +375 -0
  83. package/src/utils/Utils.js +43 -0
@@ -0,0 +1,56 @@
1
+ import { Loader } from 't3d';
2
+
3
+ class ImageBitmapLoader extends Loader {
4
+
5
+ constructor(manager) {
6
+ super(manager);
7
+
8
+ if (typeof createImageBitmap === 'undefined') {
9
+ console.warn('ImageBitmapLoader: createImageBitmap() not supported.');
10
+ }
11
+
12
+ if (typeof fetch === 'undefined') {
13
+ console.warn('ImageBitmapLoader: fetch() not supported.');
14
+ }
15
+
16
+ this.options = { premultiplyAlpha: 'none' };
17
+ }
18
+
19
+ setOptions(options) {
20
+ this.options = options;
21
+ return this;
22
+ }
23
+
24
+ load(url, onLoad, _onProgress, onError) {
25
+ if (url === undefined) url = '';
26
+ if (this.path !== undefined) url = this.path + url;
27
+
28
+ url = this.manager.resolveURL(url);
29
+
30
+ const scope = this;
31
+
32
+ const fetchOptions = {};
33
+ fetchOptions.credentials = (this.crossOrigin === 'anonymous') ? 'same-origin' : 'include';
34
+ fetchOptions.headers = this.requestHeader;
35
+
36
+ fetch(url, fetchOptions).then(function(res) {
37
+ return res.blob();
38
+ }).then(function(blob) {
39
+ return createImageBitmap(blob, Object.assign(scope.options, { colorSpaceConversion: 'none' }));
40
+ }).then(function(imageBitmap) {
41
+ if (onLoad) onLoad(imageBitmap);
42
+
43
+ scope.manager.itemEnd(url);
44
+ }).catch(function(e) {
45
+ if (onError) onError(e);
46
+
47
+ scope.manager.itemError(url);
48
+ scope.manager.itemEnd(url);
49
+ });
50
+
51
+ scope.manager.itemStart(url);
52
+ }
53
+
54
+ }
55
+
56
+ export { ImageBitmapLoader };
@@ -0,0 +1,85 @@
1
+ import {
2
+ TEXTURE_FILTER,
3
+ TEXTURE_WRAP
4
+ } from 't3d';
5
+
6
+ export const ATTRIBUTES = {
7
+ POSITION: 'a_Position',
8
+ NORMAL: 'a_Normal',
9
+ TANGENT: 'a_Tangent',
10
+ TEXCOORD_0: 'a_Uv',
11
+ TEXCOORD_1: 'a_Uv2',
12
+ TEXCOORD_2: 'a_Uv3',
13
+ TEXCOORD_3: 'a_Uv4',
14
+ TEXCOORD_4: 'a_Uv5',
15
+ TEXCOORD_5: 'a_Uv6',
16
+ TEXCOORD_6: 'a_Uv7',
17
+ TEXCOORD_7: 'a_Uv8',
18
+ COLOR_0: 'a_Color',
19
+ WEIGHTS_0: 'skinWeight',
20
+ JOINTS_0: 'skinIndex',
21
+
22
+ TEXCOORD0: 'a_Uv', // deprecated
23
+ TEXCOORD: 'a_Uv', // deprecated
24
+ COLOR0: 'a_Color', // deprecated
25
+ COLOR: 'a_Color', // deprecated
26
+ WEIGHT: 'skinWeight', // deprecated
27
+ JOINT: 'skinIndex' // deprecated
28
+ };
29
+
30
+ export const ALPHA_MODES = {
31
+ OPAQUE: 'OPAQUE',
32
+ MASK: 'MASK',
33
+ BLEND: 'BLEND'
34
+ };
35
+
36
+ export const PATH_PROPERTIES = {
37
+ scale: 'scale',
38
+ translation: 'position',
39
+ rotation: 'quaternion',
40
+ weights: 'morphTargetInfluences'
41
+ };
42
+
43
+ export const ACCESSOR_TYPE_SIZES = {
44
+ 'SCALAR': 1,
45
+ 'VEC2': 2,
46
+ 'VEC3': 3,
47
+ 'VEC4': 4,
48
+ 'MAT2': 4,
49
+ 'MAT3': 9,
50
+ 'MAT4': 16
51
+ };
52
+
53
+ export const ACCESSOR_COMPONENT_TYPES = {
54
+ 5120: Int8Array,
55
+ 5121: Uint8Array,
56
+ 5122: Int16Array,
57
+ 5123: Uint16Array,
58
+ 5125: Uint32Array,
59
+ 5126: Float32Array
60
+ };
61
+
62
+ export const WEBGL_FILTERS = {
63
+ 9728: TEXTURE_FILTER.NEAREST,
64
+ 9729: TEXTURE_FILTER.LINEAR,
65
+ 9984: TEXTURE_FILTER.NEAREST_MIPMAP_NEAREST,
66
+ 9985: TEXTURE_FILTER.LINEAR_MIPMAP_NEAREST,
67
+ 9986: TEXTURE_FILTER.NEAREST_MIPMAP_LINEAR,
68
+ 9987: TEXTURE_FILTER.LINEAR_MIPMAP_LINEAR
69
+ };
70
+
71
+ export const WEBGL_WRAPPINGS = {
72
+ 33071: TEXTURE_WRAP.CLAMP_TO_EDGE,
73
+ 33648: TEXTURE_WRAP.MIRRORED_REPEAT,
74
+ 10497: TEXTURE_WRAP.REPEAT
75
+ };
76
+
77
+ export const WEBGL_DRAW_MODES = {
78
+ POINTS: 0,
79
+ LINES: 1,
80
+ LINE_LOOP: 2,
81
+ LINE_STRIP: 3,
82
+ TRIANGLES: 4,
83
+ TRIANGLE_STRIP: 5,
84
+ TRIANGLE_FAN: 6
85
+ };
@@ -0,0 +1,169 @@
1
+ import { DefaultLoadingManager, FileLoader, ImageLoader } from 't3d';
2
+
3
+ import { ImageBitmapLoader } from '../ImageBitmapLoader.js';
4
+ import { IndexParser } from './parsers/IndexParser.js';
5
+ import { ReferenceParser } from './parsers/ReferenceParser.js';
6
+ import { Validator } from './parsers/Validator.js';
7
+ import { BufferParser } from './parsers/BufferParser.js';
8
+ import { BufferViewParser } from './parsers/BufferViewParser.js';
9
+ import { ImageParser } from './parsers/ImageParser.js';
10
+ import { TextureParser } from './parsers/TextureParser.js';
11
+ import { MaterialParser } from './parsers/MaterialParser.js';
12
+ import { AccessorParser } from './parsers/AccessorParser.js';
13
+ import { PrimitiveParser } from './parsers/PrimitiveParser.js';
14
+ import { NodeParser } from './parsers/NodeParser.js';
15
+ import { SkinParser } from './parsers/SkinParser.js';
16
+ import { SceneParser } from './parsers/SceneParser.js';
17
+ import { AnimationParser } from './parsers/AnimationParser.js';
18
+
19
+ import { GLTFResource } from './GLTFResource.js';
20
+ import { GLTFUtils } from './GLTFUtils.js';
21
+
22
+ const DefaultParsePipeline = [
23
+ IndexParser,
24
+ ReferenceParser,
25
+ Validator,
26
+ BufferParser,
27
+ BufferViewParser,
28
+ ImageParser,
29
+ TextureParser,
30
+ MaterialParser,
31
+ AccessorParser,
32
+ PrimitiveParser,
33
+ NodeParser,
34
+ SkinParser,
35
+ SceneParser,
36
+ AnimationParser
37
+ ];
38
+
39
+ export class GLTFLoader {
40
+
41
+ constructor(manager = DefaultLoadingManager, parsers = DefaultParsePipeline) {
42
+ this.manager = manager;
43
+
44
+ // If ture, loading manager will dispatch progress for every buffer and image.
45
+ // otherwise, loading manager will only dispatch progress for the whole gltf resource.
46
+ this.detailLoadProgress = true;
47
+
48
+ // If set false, need add Promise.catch to catch errors.
49
+ this.autoLogError = true;
50
+
51
+ this._parsers = parsers.slice(0);
52
+
53
+ this._dracoLoader = null;
54
+ this._meshoptDecoder = null;
55
+ this._ktx2Loader = null;
56
+
57
+ this._fileLoader = new FileLoader();
58
+
59
+ const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) === true;
60
+ const isFirefox = navigator.userAgent.indexOf('Firefox') > -1;
61
+ const firefoxVersion = isFirefox ? navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1] : -1;
62
+
63
+ if (typeof createImageBitmap === 'undefined' || isSafari || (isFirefox && firefoxVersion < 98)) {
64
+ this._imageLoader = new ImageLoader();
65
+ } else {
66
+ this._imageLoader = new ImageBitmapLoader();
67
+ }
68
+ }
69
+
70
+ load(url, options = {}) {
71
+ this.manager.itemStart(url);
72
+
73
+ return new Promise((resolve, reject) => {
74
+ const resource = new GLTFResource();
75
+ resource.url = url;
76
+ resource.path = GLTFUtils.extractUrlBase(url);
77
+ resource.options = options;
78
+
79
+ this._parse(resource)
80
+ .then(resolve)
81
+ .then(() => this.manager.itemEnd(url))
82
+ .catch(e => {
83
+ if (this.autoLogError) {
84
+ console.error(e);
85
+ }
86
+
87
+ if (this.detailLoadProgress && resource.loadItems) {
88
+ resource.loadItems.forEach(item => {
89
+ this.manager.itemEnd(item);
90
+ });
91
+ }
92
+
93
+ this.manager.itemError(url);
94
+ this.manager.itemEnd(url);
95
+
96
+ reject(`Error loading glTF model from ${url} .`);
97
+ });
98
+ });
99
+ }
100
+
101
+ _parse(context) {
102
+ let lastParser;
103
+ return new Promise((resolve, reject) => {
104
+ this._parsers.forEach(parser => {
105
+ if (lastParser) {
106
+ lastParser = lastParser.then(() => parser.parse(context, this));
107
+ } else {
108
+ lastParser = parser.parse(context, this);
109
+ }
110
+ });
111
+
112
+ if (lastParser) {
113
+ lastParser.then(() => resolve(context)).catch(reject);
114
+ } else {
115
+ resolve(context);
116
+ }
117
+ });
118
+ }
119
+
120
+ setDRACOLoader(dracoLoader) {
121
+ this._dracoLoader = dracoLoader;
122
+ return this;
123
+ }
124
+
125
+ getDRACOLoader() {
126
+ return this._dracoLoader;
127
+ }
128
+
129
+ setMeshoptDecoder(meshoptDecoder) {
130
+ this._meshoptDecoder = meshoptDecoder;
131
+ return this;
132
+ }
133
+ getMeshoptDecoder() {
134
+ return this._meshoptDecoder;
135
+ }
136
+
137
+ setKTX2Loader(ktx2Loader) {
138
+ this._ktx2Loader = ktx2Loader;
139
+ return this;
140
+ }
141
+ getKTX2Loader() {
142
+ return this._ktx2Loader;
143
+ }
144
+
145
+ loadFile(url, type = 'json') {
146
+ this._fileLoader.setResponseType(type);
147
+
148
+ return new Promise((resolve, reject) => {
149
+ url = this.manager.resolveURL(url);
150
+ this._fileLoader.load(url, resolve, undefined, reject);
151
+ });
152
+ }
153
+
154
+ loadImage(url) {
155
+ return new Promise((resolve, reject) => {
156
+ url = this.manager.resolveURL(url);
157
+ this._imageLoader.load(url, resolve, undefined, reject);
158
+ });
159
+ }
160
+
161
+ insertParser(parser, index) {
162
+ this._parsers.splice(index, 0, parser);
163
+ }
164
+
165
+ replaceParser(parser, index) {
166
+ this._parsers.splice(index, 1, parser);
167
+ }
168
+
169
+ }
@@ -0,0 +1,28 @@
1
+ let resourceId = 0;
2
+
3
+ export class GLTFResource {
4
+
5
+ constructor() {
6
+ this.id = ++resourceId;
7
+ this.url = ''; // url string
8
+ this.path = ''; // path string
9
+ this.options = null; // load options
10
+ this.gltf = null; // gltf json after IndexParser
11
+ this.loadItems = null; // String[] after IndexParser. Store all urls that need to load.
12
+ this.buffers = null; // ArrayBuffer[] after BufferParser
13
+ this.bufferViews = null; // ArrayBuffer[] after BufferViewParser
14
+ this.images = null; // Image[] after ImageParser
15
+ this.textures = null; // Texture2D[] after TextureParser
16
+ this.materials = null; // Material[] after MaterialParser
17
+ this.accessors = null; // Attribute[] after AccessorParser
18
+ this.primitives = null; // { mode, geometry, material, weights, skinned }[] after PrimitiveParser
19
+ this.nodes = null; // Object3D[] after NodeParser
20
+ this.cameras = null; // Camera[] after NodeParser
21
+ this.lights = null; // Light[] after NodeParser
22
+ this.skins = null; // Skeleton[] after SkinParser
23
+ this.root = null; // root after SceneParser
24
+ this.roots = null; // root[] after SceneParser
25
+ this.animations = null; // KeyframeClip[] after AnimationParser
26
+ }
27
+
28
+ }
@@ -0,0 +1,131 @@
1
+ // Characters [].:/ are reserved for track binding syntax.
2
+ const RESERVED_CHARS_RE = '\\[\\]\\.:\\/';
3
+ const reservedRe = new RegExp('[' + RESERVED_CHARS_RE + ']', 'g');
4
+
5
+ export class GLTFUtils {
6
+
7
+ constructor() {}
8
+
9
+ // deprecated since v0.2.0
10
+ static sanitizeNodeName(name) {
11
+ return name.replace(/\s/g, '_').replace(reservedRe, '');
12
+ }
13
+
14
+ static extractUrlBase(url) {
15
+ const parts = url.split('/');
16
+ parts.pop();
17
+ return (parts.length < 1 ? '.' : parts.join('/')) + '/';
18
+ }
19
+
20
+ // url: aa.bin ; path:example/resource/model/ (for example)example/resource/model/aa.bin
21
+ static resolveURL(url, path) {
22
+ // Invalid URL
23
+ if (typeof url !== 'string' || url === '') return '';
24
+
25
+ // Absolute URL http://,https://,//
26
+ if (/^(https?:)?\/\//i.test(url)) return url;
27
+
28
+ // Data URI
29
+ if (/^data:/i.test(url)) return url;
30
+
31
+ // Blob URL
32
+ if (/^blob:/i.test(url)) return url;
33
+
34
+ // Relative URL
35
+ return path + url;
36
+ }
37
+
38
+ static decodeText(array) {
39
+ if (typeof TextDecoder !== 'undefined') {
40
+ return new TextDecoder().decode(array);
41
+ }
42
+
43
+ // Avoid the String.fromCharCode.apply(null, array) shortcut, which
44
+ // throws a "maximum call stack size exceeded" error for large arrays.
45
+
46
+ let s = '';
47
+
48
+ for (let i = 0, il = array.length; i < il; i++) {
49
+ // Implicitly assumes little-endian.
50
+ s += String.fromCharCode(array[i]);
51
+ }
52
+
53
+ try {
54
+ // merges multi-byte utf-8 characters.
55
+
56
+ return decodeURIComponent(escape(s));
57
+ } catch (e) { // see #16358
58
+ return s;
59
+ }
60
+ }
61
+
62
+ static parseGLB(glb) {
63
+ const UINT32_LENGTH = 4;
64
+ const GLB_HEADER_MAGIC = 0x46546C67; // 'glTF'
65
+ const GLB_HEADER_LENGTH = 12;
66
+ const GLB_CHUNK_TYPES = { JSON: 0x4E4F534A, BIN: 0x004E4942 };
67
+
68
+ const dataView = new DataView(glb);
69
+
70
+ const header = {
71
+ magic: dataView.getUint32(0, true),
72
+ version: dataView.getUint32(UINT32_LENGTH, true),
73
+ length: dataView.getUint32(2 * UINT32_LENGTH, true)
74
+ };
75
+
76
+ if (header.magic !== GLB_HEADER_MAGIC) {
77
+ console.error('Invalid glb magic number. Expected 0x46546C67, found 0x' + header.magic.toString(16));
78
+ return null;
79
+ } else if (header.version < 2.0) {
80
+ console.error('GLTFLoader: Legacy binary file detected.');
81
+ }
82
+
83
+ let chunkLength = dataView.getUint32(GLB_HEADER_LENGTH, true);
84
+ let chunkType = dataView.getUint32(GLB_HEADER_LENGTH + UINT32_LENGTH, true);
85
+
86
+ if (chunkType !== GLB_CHUNK_TYPES.JSON) {
87
+ console.error('Invalid glb chunk type. Expected 0x4E4F534A, found 0x' + chunkType.toString(16));
88
+ return null;
89
+ }
90
+
91
+ const glTFData = new Uint8Array(glb, GLB_HEADER_LENGTH + 2 * UINT32_LENGTH, chunkLength);
92
+ const gltf = JSON.parse(GLTFUtils.decodeText(glTFData));
93
+
94
+ const buffers = [];
95
+ let byteOffset = GLB_HEADER_LENGTH + 2 * UINT32_LENGTH + chunkLength;
96
+
97
+ while (byteOffset < header.length) {
98
+ chunkLength = dataView.getUint32(byteOffset, true);
99
+ chunkType = dataView.getUint32(byteOffset + UINT32_LENGTH, true);
100
+
101
+ if (chunkType !== GLB_CHUNK_TYPES.BIN) {
102
+ console.error('Invalid glb chunk type. Expected 0x004E4942, found 0x' + chunkType.toString(16));
103
+ return null;
104
+ }
105
+
106
+ const currentOffset = byteOffset + 2 * UINT32_LENGTH;
107
+ const buffer = glb.slice(currentOffset, currentOffset + chunkLength);
108
+ buffers.push(buffer);
109
+
110
+ byteOffset += chunkLength + 2 * UINT32_LENGTH;
111
+ }
112
+
113
+ return { gltf, buffers };
114
+ }
115
+
116
+ // Reference: github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization#encoding-quantized-data
117
+ static getNormalizedComponentScale(constructor) {
118
+ if (constructor === Int8Array) {
119
+ return 1 / 127;
120
+ } else if (constructor === Uint8Array) {
121
+ return 1 / 255;
122
+ } else if (constructor === Int16Array) {
123
+ return 1 / 32767;
124
+ } else if (constructor === Uint16Array) {
125
+ return 1 / 65535;
126
+ } else {
127
+ throw new Error('Unsupported normalized accessor component type.');
128
+ }
129
+ }
130
+
131
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * meshopt BufferView Compression Extension
3
+ *
4
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_meshopt_compression
5
+ */
6
+ export class EXT_meshopt_compression {
7
+
8
+ static loadBufferView(extensionDef, buffers, meshoptDecoder) {
9
+ const buffer = buffers[extensionDef.buffer];
10
+
11
+ if (!meshoptDecoder || !meshoptDecoder.supported) {
12
+ throw new Error('GLTFLoader: setMeshoptDecoder must be called before loading compressed files.');
13
+ }
14
+
15
+ const byteOffset = extensionDef.byteOffset || 0;
16
+ const byteLength = extensionDef.byteLength || 0;
17
+
18
+ const count = extensionDef.count;
19
+ const stride = extensionDef.byteStride;
20
+
21
+ const source = new Uint8Array(buffer, byteOffset, byteLength);
22
+
23
+ if (meshoptDecoder.decodeGltfBufferAsync) {
24
+ return meshoptDecoder.decodeGltfBufferAsync(count, stride, source, extensionDef.mode, extensionDef.filter).then(res => res.buffer);
25
+ } else {
26
+ // Support for MeshoptDecoder 0.18 or earlier, without decodeGltfBufferAsync
27
+ return meshoptDecoder.ready.then(() => {
28
+ const result = new ArrayBuffer(count * stride);
29
+ meshoptDecoder.decodeGltfBuffer(new Uint8Array(result), count, stride, source, extensionDef.mode, extensionDef.filter);
30
+ return result;
31
+ });
32
+ }
33
+ }
34
+
35
+ }
@@ -0,0 +1,54 @@
1
+ import { ATTRIBUTES, ACCESSOR_COMPONENT_TYPES } from '../Constants.js';
2
+
3
+ /**
4
+ * KHR_draco_mesh_compression extension
5
+ * https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression
6
+ */
7
+ export class KHR_draco_mesh_compression {
8
+
9
+ static getGeometry(params, bufferViews, attributes, accessors, dracoLoader) {
10
+ const { bufferView: bufferViewIndex, attributes: gltfAttributeMap } = params;
11
+
12
+ if (!dracoLoader) {
13
+ throw new Error('GLTFLoader: No DRACOLoader instance provided.');
14
+ }
15
+
16
+ const attributeMap = {};
17
+
18
+ for (const attributeSemantic in gltfAttributeMap) {
19
+ const attributeName = ATTRIBUTES[attributeSemantic] === undefined ? attributeSemantic : ATTRIBUTES[attributeSemantic];
20
+ attributeMap[attributeName] = gltfAttributeMap[attributeSemantic];
21
+ }
22
+
23
+ const attributeNormalizedMap = {};
24
+ const attributeTypeMap = {};
25
+
26
+ for (const attributeNameItem in attributes) {
27
+ const attributeName = ATTRIBUTES[attributeNameItem] || attributeNameItem.toLowerCase();
28
+
29
+ if (gltfAttributeMap[attributeNameItem] !== undefined) {
30
+ const accessorDef = accessors[attributes[attributeNameItem]];
31
+ const componentType = ACCESSOR_COMPONENT_TYPES[accessorDef.componentType];
32
+
33
+ attributeTypeMap[attributeName] = componentType.name;
34
+ attributeNormalizedMap[attributeName] = accessorDef.normalized === true;
35
+ }
36
+ }
37
+
38
+ const bufferView = bufferViews[bufferViewIndex];
39
+
40
+ return new Promise(function(resolve) {
41
+ dracoLoader.decodeDracoFile(bufferView, function(geometry) {
42
+ for (const attributeName in geometry.attributes) {
43
+ const attribute = geometry.attributes[attributeName];
44
+ const normalized = attributeNormalizedMap[attributeName];
45
+
46
+ if (normalized !== undefined) attribute.normalized = normalized;
47
+ }
48
+
49
+ resolve(geometry);
50
+ }, attributeMap, attributeTypeMap);
51
+ });
52
+ }
53
+
54
+ }
@@ -0,0 +1,53 @@
1
+ import { DirectionalLight, PointLight, SpotLight } from 't3d';
2
+
3
+ /**
4
+ * KHR_lights_punctual extension
5
+ * https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md
6
+ */
7
+ export class KHR_lights_punctual {
8
+
9
+ static getLight(params) {
10
+ const { color, intensity = 1, type, range, spot } = params;
11
+
12
+ let lightNode;
13
+
14
+ if (type === 'directional') {
15
+ lightNode = new DirectionalLight();
16
+ } else if (type === 'point') {
17
+ lightNode = new PointLight();
18
+
19
+ if (range !== undefined) {
20
+ lightNode.distance = range;
21
+ }
22
+
23
+ // https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md#range-property
24
+ // lightNode.decay = 2;
25
+ } else if (type === 'spot') {
26
+ lightNode = new SpotLight();
27
+
28
+ if (range !== undefined) {
29
+ lightNode.distance = range;
30
+ }
31
+
32
+ // https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md#range-property
33
+ // lightNode.decay = 2;
34
+
35
+ if (spot) {
36
+ const { innerConeAngle = 0, outerConeAngle = Math.PI / 4 } = spot;
37
+ lightNode.angle = outerConeAngle;
38
+ lightNode.penumbra = 1.0 - innerConeAngle / outerConeAngle;
39
+ }
40
+ } else {
41
+ throw new Error('Unexpected light type: ' + type);
42
+ }
43
+
44
+ if (color) {
45
+ lightNode.color.fromArray(color);
46
+ }
47
+
48
+ lightNode.intensity = intensity;
49
+
50
+ return lightNode;
51
+ }
52
+
53
+ }
@@ -0,0 +1,42 @@
1
+ import { PBRMaterial, Vector2 } from 't3d';
2
+ /**
3
+ * Clearcoat Materials Extension
4
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
5
+ */
6
+ export class KHR_materials_clearcoat {
7
+
8
+ static getMaterial() {
9
+ return new PBRMaterial();
10
+ }
11
+
12
+ static parseParams(material, extension, textures) {
13
+ const { clearcoatFactor, clearcoatTexture, clearcoatRoughnessFactor, clearcoatRoughnessTexture, clearcoatNormalTexture } = extension;
14
+
15
+ if (clearcoatFactor) {
16
+ material.clearcoat = clearcoatFactor;
17
+ }
18
+ if (clearcoatTexture) {
19
+ material.clearcoatMap = textures[clearcoatTexture.index];
20
+ // material does not yet support the transform of clearcoatMap.
21
+ // parseTextureTransform(material, 'clearcoatMap', clearcoatTexture.extensions);
22
+ }
23
+ if (clearcoatRoughnessFactor) {
24
+ material.clearcoatRoughness = clearcoatRoughnessFactor;
25
+ }
26
+ if (clearcoatRoughnessTexture) {
27
+ material.clearcoatRoughnessMap = textures[clearcoatRoughnessTexture.index];
28
+ // material does not yet support the transform of clearcoatRoughnessMap.
29
+ // parseTextureTransform(material, 'clearcoatRoughnessMap', clearcoatRoughnessTexture.extensions);
30
+ }
31
+ if (clearcoatNormalTexture) {
32
+ material.clearcoatNormalMap = textures[clearcoatNormalTexture.index];
33
+ // material does not yet support the transform of clearcoatNormalMap.
34
+ // parseTextureTransform(material, 'clearcoatNormalMap', clearcoatNormalTexture.extensions);
35
+ if (clearcoatNormalTexture.scale) {
36
+ const scale = clearcoatNormalTexture.scale;
37
+ material.clearcoatNormalScale = new Vector2(scale, scale);
38
+ }
39
+ }
40
+ }
41
+
42
+ }