@shapediver/viewer.data-engine.geometry-engine 2.10.1-rc.0 → 2.12.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 (37) hide show
  1. package/dist/GeometryEngine.d.ts.map +1 -1
  2. package/dist/GeometryEngine.js +18 -14
  3. package/dist/GeometryEngine.js.map +1 -1
  4. package/dist/gltfv1/GLTFLoader.d.ts.map +1 -1
  5. package/dist/gltfv1/GLTFLoader.js +53 -49
  6. package/dist/gltfv1/GLTFLoader.js.map +1 -1
  7. package/dist/gltfv1/SDGTFLoader.js +98 -94
  8. package/dist/gltfv1/SDGTFLoader.js.map +1 -1
  9. package/dist/gltfv2/GLTFLoader.d.ts +2 -2
  10. package/dist/gltfv2/GLTFLoader.d.ts.map +1 -1
  11. package/dist/gltfv2/GLTFLoader.js +67 -63
  12. package/dist/gltfv2/GLTFLoader.js.map +1 -1
  13. package/dist/gltfv2/loaders/AccessorLoader.js +15 -11
  14. package/dist/gltfv2/loaders/AccessorLoader.js.map +1 -1
  15. package/dist/gltfv2/loaders/BufferLoader.d.ts.map +1 -1
  16. package/dist/gltfv2/loaders/BufferLoader.js +10 -6
  17. package/dist/gltfv2/loaders/BufferLoader.js.map +1 -1
  18. package/dist/gltfv2/loaders/BufferViewLoader.js +5 -1
  19. package/dist/gltfv2/loaders/BufferViewLoader.js.map +1 -1
  20. package/dist/gltfv2/loaders/GeometryLoader.js +19 -15
  21. package/dist/gltfv2/loaders/GeometryLoader.js.map +1 -1
  22. package/dist/gltfv2/loaders/MaterialLoader.d.ts.map +1 -1
  23. package/dist/gltfv2/loaders/MaterialLoader.js +78 -60
  24. package/dist/gltfv2/loaders/MaterialLoader.js.map +1 -1
  25. package/dist/gltfv2/loaders/TextureLoader.d.ts +4 -1
  26. package/dist/gltfv2/loaders/TextureLoader.d.ts.map +1 -1
  27. package/dist/gltfv2/loaders/TextureLoader.js +27 -20
  28. package/dist/gltfv2/loaders/TextureLoader.js.map +1 -1
  29. package/dist/index.js +5 -2
  30. package/dist/index.js.map +1 -1
  31. package/package.json +10 -10
  32. package/src/GeometryEngine.ts +29 -29
  33. package/src/gltfv1/GLTFLoader.ts +31 -31
  34. package/src/gltfv2/GLTFLoader.ts +66 -66
  35. package/src/gltfv2/loaders/BufferLoader.ts +10 -10
  36. package/src/gltfv2/loaders/MaterialLoader.ts +39 -33
  37. package/src/gltfv2/loaders/TextureLoader.ts +41 -30
@@ -1,39 +1,39 @@
1
- import { ITreeNode, TreeNode } from '@shapediver/viewer.shared.node-tree'
1
+ import { ITreeNode, TreeNode } from '@shapediver/viewer.shared.node-tree';
2
2
  import {
3
- Converter,
4
- EventEngine,
5
- EVENTTYPE,
6
- HttpClient,
7
- Logger,
8
- PerformanceEvaluator,
9
- ShapeDiverViewerDataProcessingError,
10
- UuidGenerator,
11
- } from '@shapediver/viewer.shared.services'
12
- import { IGLTF_v2 } from '@shapediver/viewer.data-engine.shared-types'
13
- import { mat4, vec3, vec4 } from 'gl-matrix'
3
+ EventEngine,
4
+ EVENTTYPE,
5
+ HttpClient,
6
+ HttpResponse,
7
+ Logger,
8
+ PerformanceEvaluator,
9
+ ShapeDiverViewerDataProcessingError,
10
+ UuidGenerator,
11
+ } from '@shapediver/viewer.shared.services';
12
+ import { IGLTF_v2 } from '@shapediver/viewer.data-engine.shared-types';
13
+ import { mat4, vec3, vec4 } from 'gl-matrix';
14
14
  import {
15
- AnimationData,
16
- IAnimationTrack,
17
- AttributeData,
18
- BoneData,
19
- Color,
20
- ITaskEvent,
21
- TASK_TYPE
22
- } from '@shapediver/viewer.shared.types'
23
- import { OrthographicCamera, PerspectiveCamera } from '@shapediver/viewer.rendering-engine.camera-engine'
15
+ AnimationData,
16
+ IAnimationTrack,
17
+ AttributeData,
18
+ BoneData,
19
+ Color,
20
+ ITaskEvent,
21
+ TASK_TYPE
22
+ } from '@shapediver/viewer.shared.types';
23
+ import { OrthographicCamera, PerspectiveCamera } from '@shapediver/viewer.rendering-engine.camera-engine';
24
24
  import {
25
- AbstractLight,
26
- DirectionalLight,
27
- PointLight,
28
- SpotLight,
29
- } from '@shapediver/viewer.rendering-engine.light-engine'
30
-
31
- import { BufferLoader } from './loaders/BufferLoader'
32
- import { BufferViewLoader } from './loaders/BufferViewLoader'
33
- import { AccessorLoader } from './loaders/AccessorLoader'
34
- import { TextureLoader } from './loaders/TextureLoader'
35
- import { MaterialLoader } from './loaders/MaterialLoader'
36
- import { GeometryLoader } from './loaders/GeometryLoader'
25
+ AbstractLight,
26
+ DirectionalLight,
27
+ PointLight,
28
+ SpotLight,
29
+ } from '@shapediver/viewer.rendering-engine.light-engine';
30
+
31
+ import { BufferLoader } from './loaders/BufferLoader';
32
+ import { BufferViewLoader } from './loaders/BufferViewLoader';
33
+ import { AccessorLoader } from './loaders/AccessorLoader';
34
+ import { TextureLoader } from './loaders/TextureLoader';
35
+ import { MaterialLoader } from './loaders/MaterialLoader';
36
+ import { GeometryLoader } from './loaders/GeometryLoader';
37
37
 
38
38
  export enum GLTF_EXTENSIONS {
39
39
  KHR_BINARY_GLTF = 'KHR_binary_glTF',
@@ -53,10 +53,11 @@ export enum GLTF_EXTENSIONS {
53
53
  SHAPEDIVER_MATERIALS_PRESET = 'SHAPEDIVER_materials_preset'
54
54
  }
55
55
 
56
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
56
57
  const DRACO = require('./draco/draco_decoder.js');
57
58
 
58
59
  export class GLTFLoader {
59
- // #region Properties (17)
60
+ // #region Properties (22)
60
61
 
61
62
  private readonly BINARY_EXTENSION_HEADER_LENGTH = 20;
62
63
  private readonly _eventEngine: EventEngine = EventEngine.instance;
@@ -73,18 +74,18 @@ export class GLTFLoader {
73
74
  private _bufferLoader!: BufferLoader;
74
75
  private _bufferViewLoader!: BufferViewLoader;
75
76
  private _content!: IGLTF_v2;
76
- private _eventId: string = "";
77
+ private _eventId: string = '';
77
78
  private _geometryLoader!: GeometryLoader;
78
79
  private _materialLoader!: MaterialLoader;
79
80
  private _nodes: {
80
81
  [key: number]: ITreeNode
81
82
  } = {};
82
- private _numberOfNodes = 0;
83
83
  private _numberOfConvertedNodes = 0;
84
- private _textureLoader!: TextureLoader;
84
+ private _numberOfNodes = 0;
85
85
  private _progressTimer = 0;
86
+ private _textureLoader!: TextureLoader;
86
87
 
87
- // #endregion Properties (17)
88
+ // #endregion Properties (22)
88
89
 
89
90
  // #region Public Methods (2)
90
91
 
@@ -92,11 +93,11 @@ export class GLTFLoader {
92
93
  this._eventId = taskEventId || this._uuidGenerator.create();
93
94
  const eventStart: ITaskEvent = { type: TASK_TYPE.GLTF_CONTENT_LOADING, id: this._eventId, progress: 0, status: 'Starting glTF 2.0 loading.' };
94
95
  this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_START, eventStart);
95
-
96
+
96
97
  this._numberOfConvertedNodes = 0;
97
98
  this._numberOfNodes = content.nodes ? content.nodes.length : 0;
98
99
  this._progressTimer = performance.now();
99
-
100
+
100
101
  this._baseUri = baseUri;
101
102
  if (gltfBinary && gltfHeader)
102
103
  this._body = gltfBinary.slice(this.BINARY_EXTENSION_HEADER_LENGTH + gltfHeader.contentLength + 8, gltfHeader.length);
@@ -128,7 +129,7 @@ export class GLTFLoader {
128
129
  for (let i = 0; i < variants.length; i++)
129
130
  this._geometryLoader.materialVariantsData.variants.push(variants[i].name);
130
131
  this._geometryLoader.materialVariantsData.variantIndex = 0;
131
- node.data.push(this._geometryLoader.materialVariantsData)
132
+ node.data.push(this._geometryLoader.materialVariantsData);
132
133
  }
133
134
 
134
135
  if (this._content.skins !== undefined && this._content.nodes !== undefined) {
@@ -142,7 +143,7 @@ export class GLTFLoader {
142
143
  const boneInverses: mat4[] = [];
143
144
 
144
145
  for (let j = 0; j < skinDef.joints.length; j++) {
145
- this._nodes[skinDef.joints[j]].data.push(new BoneData())
146
+ this._nodes[skinDef.joints[j]].data.push(new BoneData());
146
147
  bones.push(this._nodes[skinDef.joints[j]]);
147
148
 
148
149
  let mat = mat4.create();
@@ -174,12 +175,11 @@ export class GLTFLoader {
174
175
 
175
176
  public async loadWithUrl(url?: string | undefined): Promise<ITreeNode> {
176
177
  this._performanceEvaluator.startSection('gltfProcessing.' + url);
177
- let axiosResponse;
178
178
 
179
179
  this._performanceEvaluator.startSection('loadGltf.' + url);
180
- axiosResponse = await this._httpClient.get(url!, {
180
+ const axiosResponse = await this._httpClient.get(url!, {
181
181
  responseType: 'arraybuffer'
182
- });
182
+ }) as HttpResponse<ArrayBuffer>;
183
183
  this._performanceEvaluator.endSection('loadGltf.' + url);
184
184
 
185
185
  let gltfContent, gltfBinary, gltfBaseUrl, gltfHeader;
@@ -200,8 +200,8 @@ export class GLTFLoader {
200
200
  length: headerDataView.getUint32(8, true),
201
201
  contentLength: headerDataView.getUint32(12, true),
202
202
  contentFormat: headerDataView.getUint32(16, true)
203
- }
204
- if (gltfHeader.magic != 'glTF')
203
+ };
204
+ if (gltfHeader.magic != 'glTF')
205
205
  throw new ShapeDiverViewerDataProcessingError('GLTFLoader.load: Invalid data: sdgTF magic wrong.');
206
206
 
207
207
  // create content
@@ -215,11 +215,11 @@ export class GLTFLoader {
215
215
  gltfContent = JSON.parse(new TextDecoder().decode(axiosResponse.data));
216
216
 
217
217
  const removeLastDirectoryPartOf = (the_url: string): string => {
218
- const dir_char = the_url.includes("/") ? "/" : "\\";
218
+ const dir_char = the_url.includes('/') ? '/' : '\\';
219
219
  const the_arr = the_url.split(dir_char);
220
220
  the_arr.pop();
221
221
  return the_arr.join(dir_char);
222
- }
222
+ };
223
223
 
224
224
  gltfBaseUrl = removeLastDirectoryPartOf(url!);
225
225
  if (!gltfBaseUrl && window && window.location && window.location.href)
@@ -239,8 +239,8 @@ export class GLTFLoader {
239
239
  * @return {Promise<AnimationClip>}
240
240
  */
241
241
  private loadAnimation(animationId: number): AnimationData {
242
- if (!this._content.animations) throw new Error('Animations not available.')
243
- if (!this._content.animations[animationId]) throw new Error('Animations not available.')
242
+ if (!this._content.animations) throw new Error('Animations not available.');
243
+ if (!this._content.animations[animationId]) throw new Error('Animations not available.');
244
244
  const animationDef = this._content.animations[animationId];
245
245
  const animationTracks: IAnimationTrack[] = [];
246
246
  let min = Infinity, max = -Infinity;
@@ -260,7 +260,7 @@ export class GLTFLoader {
260
260
  const output = this._accessorLoader.getAccessor(sampler.output);
261
261
  let interpolation = sampler.interpolation;
262
262
  if (interpolation === 'CUBICSPLINE') {
263
- this._logger.warn('Animation with CUBICSPLINE interpolation is currently not supported. Assigning linear interpolation instead.')
263
+ this._logger.warn('Animation with CUBICSPLINE interpolation is currently not supported. Assigning linear interpolation instead.');
264
264
  interpolation = 'linear';
265
265
  }
266
266
 
@@ -277,8 +277,8 @@ export class GLTFLoader {
277
277
  }
278
278
 
279
279
  private loadCamera(cameraId: number): ITreeNode {
280
- if (!this._content.cameras) throw new Error('Cameras not available.')
281
- if (!this._content.cameras[cameraId]) throw new Error('Cameras not available.')
280
+ if (!this._content.cameras) throw new Error('Cameras not available.');
281
+ if (!this._content.cameras[cameraId]) throw new Error('Cameras not available.');
282
282
  const cameraDef = this._content.cameras[cameraId];
283
283
  const cameraNode = new TreeNode(cameraDef.name || 'camera_' + cameraId);
284
284
 
@@ -311,7 +311,7 @@ export class GLTFLoader {
311
311
 
312
312
  private loadLights(lightId: number): ITreeNode {
313
313
  if (!this._content.extensions || !this._content.extensions[GLTF_EXTENSIONS.KHR_LIGHTS_PUNCTUAL] || !this._content.extensions[GLTF_EXTENSIONS.KHR_LIGHTS_PUNCTUAL].lights) throw new Error(`Extension ${GLTF_EXTENSIONS.KHR_LIGHTS_PUNCTUAL} not available.`);
314
- if (!this._content.extensions[GLTF_EXTENSIONS.KHR_LIGHTS_PUNCTUAL].lights[lightId]) throw new Error('Light not available.')
314
+ if (!this._content.extensions[GLTF_EXTENSIONS.KHR_LIGHTS_PUNCTUAL].lights[lightId]) throw new Error('Light not available.');
315
315
  const lightDef = this._content.extensions[GLTF_EXTENSIONS.KHR_LIGHTS_PUNCTUAL].lights[lightId];
316
316
  const lightNode = new TreeNode(lightDef.name || 'light_' + lightId);
317
317
 
@@ -366,8 +366,8 @@ export class GLTFLoader {
366
366
  }
367
367
 
368
368
  private async loadNode(nodeId: number): Promise<ITreeNode> {
369
- if (!this._content.nodes) throw new Error('Nodes not available.')
370
- if (!this._content.nodes[nodeId]) throw new Error('Node not available.')
369
+ if (!this._content.nodes) throw new Error('Nodes not available.');
370
+ if (!this._content.nodes[nodeId]) throw new Error('Node not available.');
371
371
  const node = this._content.nodes[nodeId];
372
372
  const nodeDef = new TreeNode(node.name || 'node_' + nodeId);
373
373
  this._nodes[nodeId] = nodeDef;
@@ -429,7 +429,7 @@ export class GLTFLoader {
429
429
  }
430
430
 
431
431
  this._numberOfConvertedNodes++;
432
- if(performance.now() - this._progressTimer > this._progressUpdateLimit) {
432
+ if (performance.now() - this._progressTimer > this._progressUpdateLimit) {
433
433
  this._progressTimer = performance.now();
434
434
  const eventProgress: ITaskEvent = { type: TASK_TYPE.GLTF_CONTENT_LOADING, id: this._eventId, progress: (this._numberOfConvertedNodes / this._numberOfNodes) / 2 + 0.1, status: `GlTF conversion progress: ${this._numberOfConvertedNodes}/${this._numberOfNodes} nodes.` };
435
435
  this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_PROCESS, eventProgress);
@@ -440,15 +440,15 @@ export class GLTFLoader {
440
440
  }
441
441
 
442
442
  private async loadScene(): Promise<ITreeNode> {
443
- if (!this._content.scenes) throw new Error('Scenes not available.')
443
+ if (!this._content.scenes) throw new Error('Scenes not available.');
444
444
  const sceneId = this._content.scene || 0;
445
- if (!this._content.scenes[sceneId]) throw new Error('Scene not available.')
445
+ if (!this._content.scenes[sceneId]) throw new Error('Scene not available.');
446
446
  const scene = this._content.scenes[sceneId];
447
447
  const sceneDef = new TreeNode(scene.name || 'scene_' + sceneId + '');
448
448
  sceneDef.addTransformation({
449
449
  id: this._uuidGenerator.create(),
450
450
  matrix: this._globalTransformation
451
- })
451
+ });
452
452
  if (scene.nodes)
453
453
  for (let i = 0, len = scene.nodes.length; i < len; i++)
454
454
  sceneDef.addChild(await this.loadNode(scene.nodes[i]));
@@ -459,8 +459,8 @@ export class GLTFLoader {
459
459
  joints: number[],
460
460
  inverseBindMatrices: AttributeData | null
461
461
  } {
462
- if (!this._content.skins) throw new Error('Skins not available.')
463
- if (!this._content.skins[skinId]) throw new Error('Skin not available.')
462
+ if (!this._content.skins) throw new Error('Skins not available.');
463
+ if (!this._content.skins[skinId]) throw new Error('Skin not available.');
464
464
  const skinDef = this._content.skins![skinId];
465
465
 
466
466
  const skinEntry: {
@@ -475,14 +475,14 @@ export class GLTFLoader {
475
475
  return skinEntry;
476
476
  }
477
477
 
478
- skinEntry.inverseBindMatrices = this._accessorLoader.getAccessor(skinDef.inverseBindMatrices)
478
+ skinEntry.inverseBindMatrices = this._accessorLoader.getAccessor(skinDef.inverseBindMatrices);
479
479
  return skinEntry;
480
480
  }
481
481
 
482
482
  private validateVersionAndExtensions(): void {
483
- if (!this._content.asset) throw new Error('Asset not available.')
483
+ if (!this._content.asset) throw new Error('Asset not available.');
484
484
  const asset = this._content.asset;
485
- if (!asset.version) throw new Error('Asset does not have a version.')
485
+ if (!asset.version) throw new Error('Asset does not have a version.');
486
486
  const version: string = asset.minVersion ? asset.minVersion : asset.version;
487
487
  if (!version.startsWith('2')) throw new Error('Version of the glTF not supported.');
488
488
 
@@ -1,5 +1,5 @@
1
- import { IGLTF_v2 } from '@shapediver/viewer.data-engine.shared-types'
2
- import { HttpClient } from '@shapediver/viewer.shared.services'
1
+ import { IGLTF_v2 } from '@shapediver/viewer.data-engine.shared-types';
2
+ import { HttpClient, HttpResponse } from '@shapediver/viewer.shared.services';
3
3
 
4
4
  export class BufferLoader {
5
5
  // #region Properties (2)
@@ -21,16 +21,16 @@ export class BufferLoader {
21
21
  // #region Public Methods (2)
22
22
 
23
23
  public getBuffer(bufferId: number): ArrayBuffer {
24
- if (!this._content.buffers) throw new Error('BufferLoader.getBuffer: Buffers not available.')
25
- if (!this._content.buffers[bufferId]) throw new Error('BufferLoader.getBuffer: Buffer not available.')
26
- if (!this._loaded[bufferId]) throw new Error('BufferLoader.getBuffer: Buffer not loaded.')
24
+ if (!this._content.buffers) throw new Error('BufferLoader.getBuffer: Buffers not available.');
25
+ if (!this._content.buffers[bufferId]) throw new Error('BufferLoader.getBuffer: Buffer not available.');
26
+ if (!this._loaded[bufferId]) throw new Error('BufferLoader.getBuffer: Buffer not loaded.');
27
27
  return this._loaded[bufferId];
28
28
  }
29
29
 
30
30
  public async load(): Promise<void> {
31
31
  if (!this._content.buffers) return;
32
32
 
33
- let promises: Promise<void>[] = [];
33
+ const promises: Promise<void>[] = [];
34
34
 
35
35
  for (let i = 0; i < this._content.buffers.length; i++) {
36
36
  const bufferId = i;
@@ -42,7 +42,7 @@ export class BufferLoader {
42
42
 
43
43
  // If present, GLB container is required to be the first buffer.
44
44
  if (buffer.uri === undefined && bufferId === 0) {
45
- if (!this._body) throw new Error(`BufferLoader.load: Buffer not available.`);
45
+ if (!this._body) throw new Error('BufferLoader.load: Buffer not available.');
46
46
  this._loaded[bufferId] = this._body;
47
47
  return;
48
48
  }
@@ -63,10 +63,10 @@ export class BufferLoader {
63
63
  }
64
64
  this._loaded[bufferId] = view.buffer;
65
65
  } else {
66
- let httpResultPromise = this._httpClient.get(this._baseUri + '/' + buffer.uri!, {
66
+ const httpResultPromise = (this._httpClient.get(this._baseUri + '/' + buffer.uri!, {
67
67
  responseType: 'arraybuffer'
68
- }).then(response => { this._loaded[bufferId] = response.data; });
69
- promises.push(httpResultPromise)
68
+ }) as Promise<HttpResponse<ArrayBuffer>>).then(response => { this._loaded[bufferId] = response.data; });
69
+ promises.push(httpResultPromise);
70
70
  }
71
71
  }
72
72
  await Promise.all(promises);
@@ -1,11 +1,11 @@
1
- import { Converter, HttpClient } from '@shapediver/viewer.shared.services'
1
+ import { Converter, HttpClient } from '@shapediver/viewer.shared.services';
2
2
  import {
3
3
  IGLTF_v2,
4
4
  IGLTF_v2_Material,
5
5
  IGLTF_v2_Material_KHR_materials_pbrSpecularGlossiness,
6
6
  ISHAPEDIVER_materials_preset,
7
- } from '@shapediver/viewer.data-engine.shared-types'
8
- import { vec2 } from 'gl-matrix'
7
+ } from '@shapediver/viewer.data-engine.shared-types';
8
+ import { vec2 } from 'gl-matrix';
9
9
  import {
10
10
  MATERIAL_ALPHA,
11
11
  MATERIAL_SIDE,
@@ -19,11 +19,13 @@ import {
19
19
  IMaterialUnlitDataProperties,
20
20
  MapData,
21
21
  IMapData,
22
- } from '@shapediver/viewer.shared.types'
23
- import { MaterialEngine } from '@shapediver/viewer.data-engine.material-engine'
22
+ TEXTURE_WRAPPING,
23
+ TEXTURE_FILTERING,
24
+ } from '@shapediver/viewer.shared.types';
25
+ import { MaterialEngine } from '@shapediver/viewer.data-engine.material-engine';
24
26
 
25
- import { GLTF_EXTENSIONS } from '../GLTFLoader'
26
- import { TextureLoader } from './TextureLoader'
27
+ import { GLTF_EXTENSIONS } from '../GLTFLoader';
28
+ import { TextureLoader } from './TextureLoader';
27
29
 
28
30
  export class MaterialLoader {
29
31
  // #region Properties (4)
@@ -44,9 +46,9 @@ export class MaterialLoader {
44
46
  // #region Public Methods (2)
45
47
 
46
48
  public getMaterial(materialId: number): IMaterialAbstractData {
47
- if (!this._content.materials) throw new Error('MaterialLoader.getMaterial: Materials not available.')
48
- if (!this._content.materials[materialId]) throw new Error('MaterialLoader.getMaterial: Material not available.')
49
- if (!this._loaded[materialId]) throw new Error('MaterialLoader.getMaterial: Material not loaded.')
49
+ if (!this._content.materials) throw new Error('MaterialLoader.getMaterial: Materials not available.');
50
+ if (!this._content.materials[materialId]) throw new Error('MaterialLoader.getMaterial: Material not available.');
51
+ if (!this._loaded[materialId]) throw new Error('MaterialLoader.getMaterial: Material not loaded.');
50
52
  return this._loaded[materialId];
51
53
  }
52
54
 
@@ -54,7 +56,7 @@ export class MaterialLoader {
54
56
  this._loaded = {};
55
57
  if (!this._content.materials) return;
56
58
 
57
- let promises: Promise<void>[] = [];
59
+ const promises: Promise<void>[] = [];
58
60
  for (let i = 0; i < this._content.materials.length; i++) {
59
61
  const materialId = i;
60
62
  const material: IGLTF_v2_Material = this._content.materials[materialId];
@@ -66,18 +68,21 @@ export class MaterialLoader {
66
68
  if (materialExtensions[GLTF_EXTENSIONS.SHAPEDIVER_MATERIALS_PRESET]) {
67
69
  const materialPreset: ISHAPEDIVER_materials_preset = materialExtensions[GLTF_EXTENSIONS.SHAPEDIVER_MATERIALS_PRESET];
68
70
  promises.push(
69
- new Promise<void>(async (resolve, reject) => {
71
+ new Promise<void>((resolve, reject) => {
70
72
  try {
71
- const materialData = await this._materialEngine.loadPresetMaterial(materialPreset.materialpreset);
72
- materialData.name = material.name;
73
- materialData.color = materialPreset.color;
74
- this._loaded[materialId] = materialData;
75
- resolve();
73
+ this._materialEngine.loadPresetMaterial(materialPreset.materialpreset)
74
+ .then(materialData => {
75
+ materialData.name = material.name;
76
+ materialData.color = materialPreset.color;
77
+ this._loaded[materialId] = materialData;
78
+ resolve();
79
+ })
80
+ .catch(reject);
76
81
  } catch (e) {
77
82
  reject(e);
78
83
  }
79
84
  })
80
- )
85
+ );
81
86
  continue;
82
87
  }
83
88
 
@@ -345,25 +350,26 @@ export class MaterialLoader {
345
350
  // #region Private Methods (1)
346
351
 
347
352
  private loadMap(textureId: number, properties?: { offset?: number[], scale?: number[], rotation?: number, texCoord?: number }): IMapData {
348
- if (!this._content.textures) throw new Error('Textures not available.')
353
+ if (!this._content.textures) throw new Error('Textures not available.');
349
354
  const texture = this._content.textures[textureId];
350
- if (!this._content.images) throw new Error('Images not available.')
355
+ if (!this._content.images) throw new Error('Images not available.');
351
356
  const sampler = this._content.samplers && texture.sampler && this._content.samplers[texture.sampler] ? this._content.samplers[texture.sampler] : {};
352
- const htmlImage = this._textureLoader.getTexture(textureId);
357
+ const loadedTexture = this._textureLoader.getTexture(textureId);
353
358
 
354
359
  return new MapData(
355
- htmlImage,
356
- sampler.wrapS,
357
- sampler.wrapT,
358
- sampler.minFilter,
359
- sampler.magFilter,
360
- undefined,
361
- undefined,
362
- properties && properties.offset ? vec2.fromValues(properties.offset[0], properties.offset[1]) : undefined,
363
- properties && properties.scale ? vec2.fromValues(properties.scale[0], properties.scale[1]) : undefined,
364
- properties && properties.rotation !== undefined ? properties.rotation : 0,
365
- properties?.texCoord,
366
- false
360
+ loadedTexture.image,
361
+ {
362
+ blob: loadedTexture.blob,
363
+ wrapS: sampler.wrapS as TEXTURE_WRAPPING,
364
+ wrapT: sampler.wrapT as TEXTURE_WRAPPING,
365
+ minFilter: sampler.minFilter as TEXTURE_FILTERING,
366
+ magFilter: sampler.magFilter as TEXTURE_FILTERING,
367
+ offset: properties && properties.offset ? vec2.fromValues(properties.offset[0], properties.offset[1]) : vec2.create(),
368
+ repeat: properties && properties.scale ? vec2.fromValues(properties.scale[0], properties.scale[1]) : vec2.fromValues(1, 1),
369
+ rotation: properties && properties.rotation !== undefined ? properties.rotation : 0,
370
+ texCoord: properties?.texCoord,
371
+ flipY: false
372
+ }
367
373
  );
368
374
  }
369
375
 
@@ -1,19 +1,22 @@
1
- import { IGLTF_v2 } from '@shapediver/viewer.data-engine.shared-types'
2
- import { Converter, HttpClient } from '@shapediver/viewer.shared.services'
1
+ import { IGLTF_v2 } from '@shapediver/viewer.data-engine.shared-types';
2
+ import { Converter, HttpClient } from '@shapediver/viewer.shared.services';
3
3
 
4
- import { BufferViewLoader } from './BufferViewLoader'
4
+ import { BufferViewLoader } from './BufferViewLoader';
5
5
 
6
6
  export class TextureLoader {
7
- // #region Properties (4)
7
+ // #region Properties (3)
8
8
 
9
9
  private readonly _converter: Converter = Converter.instance;
10
10
  private readonly _httpClient: HttpClient = HttpClient.instance;
11
11
 
12
12
  private _loaded: {
13
- [key: string]: HTMLImageElement
13
+ [key: string]: {
14
+ image: HTMLImageElement,
15
+ blob: Blob
16
+ }
14
17
  } = {};
15
18
 
16
- // #endregion Properties (4)
19
+ // #endregion Properties (3)
17
20
 
18
21
  // #region Constructors (1)
19
22
 
@@ -23,59 +26,67 @@ export class TextureLoader {
23
26
 
24
27
  // #region Public Methods (2)
25
28
 
26
- public getTexture(textureId: number): HTMLImageElement {
27
- if (!this._content.textures) throw new Error('TextureLoader.getTexture: Textures not available.')
28
- if (!this._content.textures[textureId]) throw new Error('TextureLoader.getTexture: Texture not available.')
29
- if (!this._loaded[textureId]) throw new Error('TextureLoader.getTexture: Texture not loaded.')
29
+ public getTexture(textureId: number): {
30
+ image: HTMLImageElement,
31
+ blob: Blob
32
+ } {
33
+ if (!this._content.textures) throw new Error('TextureLoader.getTexture: Textures not available.');
34
+ if (!this._content.textures[textureId]) throw new Error('TextureLoader.getTexture: Texture not available.');
35
+ if (!this._loaded[textureId]) throw new Error('TextureLoader.getTexture: Texture not loaded.');
30
36
  return this._loaded[textureId];
31
37
  }
32
38
 
33
39
  public async load(): Promise<void> {
34
40
  if (!this._content.textures) return;
35
41
 
36
- let promises: Promise<void>[] = [];
37
- for(let i = 0; i < this._content.textures.length; i++) {
42
+ const promises: Promise<void>[] = [];
43
+ for (let i = 0; i < this._content.textures.length; i++) {
38
44
  const textureId = i;
39
45
  const texture = this._content.textures[textureId];
40
- if (!this._content.images) throw new Error('TextureLoader.load: Images not available.')
46
+ if (!this._content.images) throw new Error('TextureLoader.load: Images not available.');
41
47
  const image = this._content.images[texture.source];
42
-
48
+
43
49
  const DATA_URI_REGEX = /^data:(.*?)(;base64)?,(.*)$/;
44
50
  const HTTPS_URI_REGEX = /^https:\/\//;
45
-
51
+
46
52
  if (image.bufferView !== undefined) {
47
53
  const bufferView = this._bufferViewLoader.getBufferView(image.bufferView);
48
54
  const dataView = new DataView(bufferView);
49
55
  const array: Array<number> = [];
50
56
  for (let i = 0; i < dataView.byteLength; i += 1)
51
57
  array[i] = dataView.getUint8(i);
52
-
58
+
53
59
  const blob = new Blob([new Uint8Array(array)], { type: image.mimeType });
54
60
  const dataUri = URL.createObjectURL(blob);
55
-
61
+
62
+ const img = new Image();
63
+
56
64
  promises.push(
57
65
  new Promise<void>((resolve, reject) => {
58
- this._httpClient.loadTexture(dataUri)
59
- .then(response => {
60
- this._converter.responseToImage(response).then(img => {
61
- this._loaded[textureId] = img;
62
- URL.revokeObjectURL(dataUri)
63
- resolve()
64
- }).catch(e => reject(e));
65
- })
66
+ img.onload = () => {
67
+ this._loaded[textureId] = {
68
+ image: img,
69
+ blob
70
+ };
71
+ URL.revokeObjectURL(dataUri);
72
+ resolve();
73
+ };
74
+ img.onerror = reject;
66
75
  })
67
76
  );
77
+
78
+ img.crossOrigin = 'anonymous';
79
+ img.src = dataUri;
68
80
  } else {
69
81
  const url = DATA_URI_REGEX.test(image.uri!) || HTTPS_URI_REGEX.test(image.uri!) ? image.uri : `${this._baseUri}/${image.uri}`;
70
82
  promises.push(
71
83
  new Promise<void>((resolve, reject) => {
72
84
  this._httpClient.loadTexture(url!)
73
85
  .then(response => {
74
- this._converter.responseToImage(response).then(img => {
75
- this._loaded[textureId] = img;
76
- resolve()
77
- });
78
- }).catch(e => reject(e));
86
+ this._loaded[textureId] = response.data;
87
+ resolve();
88
+ })
89
+ .catch(e => reject(e));
79
90
  })
80
91
  );
81
92
  }