@shapediver/viewer.data-engine.geometry-engine 2.7.10 → 2.8.1
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.
- package/dist/GeometryEngine.d.ts +6 -1
- package/dist/GeometryEngine.d.ts.map +1 -1
- package/dist/GeometryEngine.js +89 -95
- package/dist/GeometryEngine.js.map +1 -1
- package/dist/gltfv1/GLTFLoader.d.ts.map +1 -1
- package/dist/gltfv1/GLTFLoader.js +27 -45
- package/dist/gltfv1/GLTFLoader.js.map +1 -1
- package/dist/gltfv1/SDGTFLoader.d.ts.map +1 -1
- package/dist/gltfv1/SDGTFLoader.js +8 -16
- package/dist/gltfv1/SDGTFLoader.js.map +1 -1
- package/dist/gltfv2/GLTFLoader.d.ts.map +1 -1
- package/dist/gltfv2/GLTFLoader.js +58 -71
- package/dist/gltfv2/GLTFLoader.js.map +1 -1
- package/dist/gltfv2/loaders/AccessorLoader.d.ts.map +1 -1
- package/dist/gltfv2/loaders/AccessorLoader.js +2 -3
- package/dist/gltfv2/loaders/AccessorLoader.js.map +1 -1
- package/dist/gltfv2/loaders/BufferLoader.d.ts.map +1 -1
- package/dist/gltfv2/loaders/BufferLoader.js +1 -2
- package/dist/gltfv2/loaders/BufferLoader.js.map +1 -1
- package/dist/gltfv2/loaders/GeometryLoader.d.ts.map +1 -1
- package/dist/gltfv2/loaders/GeometryLoader.js +27 -37
- package/dist/gltfv2/loaders/GeometryLoader.js.map +1 -1
- package/dist/gltfv2/loaders/MaterialLoader.d.ts.map +1 -1
- package/dist/gltfv2/loaders/MaterialLoader.js +2 -3
- package/dist/gltfv2/loaders/MaterialLoader.js.map +1 -1
- package/dist/gltfv2/loaders/TextureLoader.d.ts.map +1 -1
- package/dist/gltfv2/loaders/TextureLoader.js +4 -4
- package/dist/gltfv2/loaders/TextureLoader.js.map +1 -1
- package/package.json +12 -13
- package/src/GeometryEngine.ts +108 -92
- package/src/gltfv1/GLTFLoader.ts +28 -42
- package/src/gltfv1/SDGTFLoader.ts +9 -16
- package/src/gltfv2/GLTFLoader.ts +72 -83
- package/src/gltfv2/loaders/AccessorLoader.ts +4 -10
- package/src/gltfv2/loaders/BufferLoader.ts +1 -2
- package/src/gltfv2/loaders/GeometryLoader.ts +36 -43
- package/src/gltfv2/loaders/MaterialLoader.ts +2 -3
- package/src/gltfv2/loaders/TextureLoader.ts +4 -4
package/src/gltfv1/GLTFLoader.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ITreeNode, TreeNode } from '@shapediver/viewer.shared.node-tree'
|
|
2
|
-
import { Converter, HttpClient, PerformanceEvaluator, UuidGenerator, Logger,
|
|
2
|
+
import { Converter, HttpClient, PerformanceEvaluator, UuidGenerator, Logger, ShapeDiverViewerDataProcessingError } from '@shapediver/viewer.shared.services'
|
|
3
3
|
import {
|
|
4
4
|
ACCESSORCOMPONENTTYPE_V1 as ACCESSOR_COMPONENTTYPE,
|
|
5
5
|
ACCESSORTYPE_V1 as ACCESSORTYPE,
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
MaterialStandardData,
|
|
15
15
|
PrimitiveData,
|
|
16
16
|
} from '@shapediver/viewer.shared.types'
|
|
17
|
-
import { container } from 'tsyringe'
|
|
18
17
|
|
|
19
18
|
import { SDGTFLoader } from './SDGTFLoader'
|
|
20
19
|
|
|
@@ -22,13 +21,13 @@ export class GLTFLoader {
|
|
|
22
21
|
// #region Properties (5)
|
|
23
22
|
|
|
24
23
|
private readonly BINARY_EXTENSION_HEADER_LENGTH = 20;
|
|
25
|
-
private readonly _httpClient: HttpClient =
|
|
26
|
-
private readonly _uuidGenerator: UuidGenerator =
|
|
27
|
-
private readonly _logger: Logger =
|
|
24
|
+
private readonly _httpClient: HttpClient = HttpClient.instance;
|
|
25
|
+
private readonly _uuidGenerator: UuidGenerator = UuidGenerator.instance;
|
|
26
|
+
private readonly _logger: Logger = Logger.instance;
|
|
28
27
|
private readonly _implementedExtensions = ['KHR_materials_common'];
|
|
29
28
|
private readonly _globalTransformation = mat4.fromValues(1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1);
|
|
30
|
-
private readonly _converter: Converter =
|
|
31
|
-
private readonly _performanceEvaluator =
|
|
29
|
+
private readonly _converter: Converter = Converter.instance;
|
|
30
|
+
private readonly _performanceEvaluator = PerformanceEvaluator.instance;
|
|
32
31
|
|
|
33
32
|
private _baseUri: string | undefined;
|
|
34
33
|
private _body: ArrayBuffer | undefined;
|
|
@@ -48,29 +47,22 @@ export class GLTFLoader {
|
|
|
48
47
|
if(gltfBinary && gltfHeader)
|
|
49
48
|
sdgtfNode = await new SDGTFLoader().load(gltfBinary, gltfHeader.length);
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
} catch (e) {
|
|
57
|
-
throw this._logger.handleError(LOGGING_TOPIC.DATA_PROCESSING, `GLTFLoader.loadContent`, e);
|
|
58
|
-
}
|
|
50
|
+
this.validateVersionAndExtensions();
|
|
51
|
+
const node = await this.loadScene();
|
|
52
|
+
if(sdgtfNode) node.addChild(sdgtfNode);
|
|
53
|
+
return node;
|
|
54
|
+
|
|
59
55
|
}
|
|
60
56
|
|
|
61
57
|
public async loadWithUrl(url?: string | undefined): Promise<ITreeNode> {
|
|
62
58
|
this._performanceEvaluator.startSection('gltfProcessing.' + url);
|
|
63
59
|
let binaryGeometry: ArrayBuffer;
|
|
64
60
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
this._performanceEvaluator.endSection('loadGltf.' + url);
|
|
71
|
-
} catch (e) {
|
|
72
|
-
throw this._logger.handleError(LOGGING_TOPIC.DATA_PROCESSING, `GLTFLoader.load`, e);
|
|
73
|
-
}
|
|
61
|
+
this._performanceEvaluator.startSection('loadGltf.' + url);
|
|
62
|
+
binaryGeometry = (await this._httpClient.get(url!, {
|
|
63
|
+
responseType: 'arraybuffer'
|
|
64
|
+
})).data;
|
|
65
|
+
this._performanceEvaluator.endSection('loadGltf.' + url);
|
|
74
66
|
|
|
75
67
|
// create header data
|
|
76
68
|
const headerDataView = new DataView(binaryGeometry, 0, this.BINARY_EXTENSION_HEADER_LENGTH);
|
|
@@ -81,10 +73,8 @@ export class GLTFLoader {
|
|
|
81
73
|
contentLength: headerDataView.getUint32(12, true),
|
|
82
74
|
contentFormat: headerDataView.getUint32(16, true)
|
|
83
75
|
}
|
|
84
|
-
if (header.magic != 'glTF')
|
|
85
|
-
|
|
86
|
-
throw this._logger.handleError(LOGGING_TOPIC.DATA_PROCESSING, `GLTFLoader.load`, error);
|
|
87
|
-
}
|
|
76
|
+
if (header.magic != 'glTF')
|
|
77
|
+
throw new ShapeDiverViewerDataProcessingError('GLTFLoader.load: Invalid data: glTF magic wrong.');
|
|
88
78
|
|
|
89
79
|
// create content
|
|
90
80
|
const contentDataView = new DataView(binaryGeometry, this.BINARY_EXTENSION_HEADER_LENGTH, header.contentLength);
|
|
@@ -96,15 +86,11 @@ export class GLTFLoader {
|
|
|
96
86
|
|
|
97
87
|
const sdgtfNode = await new SDGTFLoader().load(binaryGeometry, header.length);
|
|
98
88
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return node;
|
|
105
|
-
} catch (e) {
|
|
106
|
-
throw this._logger.handleError(LOGGING_TOPIC.DATA_PROCESSING, `GLTFLoader.load`, e);
|
|
107
|
-
}
|
|
89
|
+
this.validateVersionAndExtensions();
|
|
90
|
+
const node = await this.loadScene();
|
|
91
|
+
node.addChild(sdgtfNode);
|
|
92
|
+
this._performanceEvaluator.endSection('gltfProcessing.' + url);
|
|
93
|
+
return node;
|
|
108
94
|
}
|
|
109
95
|
|
|
110
96
|
// #endregion Public Methods (1)
|
|
@@ -124,7 +110,7 @@ export class GLTFLoader {
|
|
|
124
110
|
message += '"' + element + '"' + (index === notSupported.length-1 ? '' : index === notSupported.length-2 ? ' and ' : ', ');
|
|
125
111
|
});
|
|
126
112
|
message += (notSupported.length === 1 ? ' is' : ' are') + ' not supported, but used. Loading glTF regardless.';
|
|
127
|
-
this._logger.info(
|
|
113
|
+
this._logger.info('GLTFLoader.validateVersionAndExtensions: ' + message);
|
|
128
114
|
}
|
|
129
115
|
}
|
|
130
116
|
}
|
|
@@ -135,7 +121,7 @@ export class GLTFLoader {
|
|
|
135
121
|
const bufferView = await this.loadBufferView(accessor.bufferView!);
|
|
136
122
|
|
|
137
123
|
const itemSize = ACCESSORTYPE[<keyof typeof ACCESSORTYPE>accessor.type];
|
|
138
|
-
if(accessor.componentType === 5124) this._logger.warn(
|
|
124
|
+
if(accessor.componentType === 5124) this._logger.warn('GLTFLoader.loadAccessor: The componentType for this accessor is 5124, which is not allowed. Trying to load it anyway.');
|
|
139
125
|
const ArrayType = ACCESSOR_COMPONENTTYPE[<keyof typeof ACCESSOR_COMPONENTTYPE>accessor.componentType];
|
|
140
126
|
const elementBytes = ArrayType.BYTES_PER_ELEMENT;
|
|
141
127
|
const itemBytes = elementBytes * itemSize;
|
|
@@ -186,7 +172,7 @@ export class GLTFLoader {
|
|
|
186
172
|
|
|
187
173
|
if(material.extensions && material.extensions.KHR_materials_common) {
|
|
188
174
|
const technique = material.extensions.KHR_materials_common.technique;
|
|
189
|
-
if(technique && technique !== 'BLINN') this._logger.warn(
|
|
175
|
+
if(technique && technique !== 'BLINN') this._logger.warn('The technique ' + technique + ' is not supported. Trying to load the material either way.')
|
|
190
176
|
const values = material.extensions.KHR_materials_common.values;
|
|
191
177
|
|
|
192
178
|
if (values.hasOwnProperty('doubleSided'))
|
|
@@ -198,7 +184,7 @@ export class GLTFLoader {
|
|
|
198
184
|
materialData.color = diffuseScaled;
|
|
199
185
|
materialData.opacity = Math.max(0.0, Math.min(values.diffuse[3], 1.0));
|
|
200
186
|
} else if(values.hasOwnProperty('diffuse')) {
|
|
201
|
-
this._logger.warn(
|
|
187
|
+
this._logger.warn('GLTFLoader.loadMaterial: The value diffuse was set for a material, but is not supported in that type.')
|
|
202
188
|
}
|
|
203
189
|
|
|
204
190
|
if (!values.hasOwnProperty('diffuse') && values.hasOwnProperty('ambient')) {
|
|
@@ -209,7 +195,7 @@ export class GLTFLoader {
|
|
|
209
195
|
if (values.hasOwnProperty('emission') && Array.isArray(values.emission)) {
|
|
210
196
|
materialData.emissiveness = values.emission;
|
|
211
197
|
} else if (values.hasOwnProperty('emission')) {
|
|
212
|
-
this._logger.warn(
|
|
198
|
+
this._logger.warn('GLTFLoader.loadMaterial: The value emission was set for a material, but is not supported in that type.')
|
|
213
199
|
}
|
|
214
200
|
|
|
215
201
|
if (values.hasOwnProperty('shininess')) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ITreeNode, TreeNode } from '@shapediver/viewer.shared.node-tree'
|
|
2
|
-
import { Logger,
|
|
2
|
+
import { Logger, ShapeDiverViewerDataProcessingError } from '@shapediver/viewer.shared.services'
|
|
3
3
|
import {
|
|
4
4
|
ACCESSORCOMPONENTTYPE_V1 as ACCESSOR_COMPONENTTYPE,
|
|
5
5
|
ACCESSORTYPE_V1 as ACCESSORTYPE,
|
|
@@ -12,14 +12,13 @@ import {
|
|
|
12
12
|
PRIMITIVE_MODE,
|
|
13
13
|
PrimitiveData,
|
|
14
14
|
} from '@shapediver/viewer.shared.types'
|
|
15
|
-
import { container } from 'tsyringe'
|
|
16
15
|
import { mat4, vec3, vec4 } from 'gl-matrix'
|
|
17
16
|
|
|
18
17
|
export class SDGTFLoader {
|
|
19
18
|
// #region Properties (5)
|
|
20
19
|
|
|
21
20
|
private readonly BINARY_EXTENSION_HEADER_LENGTH = 20;
|
|
22
|
-
private readonly _logger: Logger =
|
|
21
|
+
private readonly _logger: Logger = Logger.instance;
|
|
23
22
|
|
|
24
23
|
private _body!: ArrayBuffer;
|
|
25
24
|
private _content!: ISDGTF_v1;
|
|
@@ -38,10 +37,8 @@ export class SDGTFLoader {
|
|
|
38
37
|
contentLength: headerDataView.getUint32(13, true),
|
|
39
38
|
contentFormat: headerDataView.getUint32(17, true)
|
|
40
39
|
}
|
|
41
|
-
if (header.magic != 'sdgTF')
|
|
42
|
-
|
|
43
|
-
throw this._logger.handleError(LOGGING_TOPIC.DATA_PROCESSING, `SDGTFLoader.load`, error);
|
|
44
|
-
}
|
|
40
|
+
if (header.magic != 'sdgTF')
|
|
41
|
+
throw new ShapeDiverViewerDataProcessingError('SDGTFLoader.load: Invalid data: sdgTF magic wrong.');
|
|
45
42
|
|
|
46
43
|
// create content
|
|
47
44
|
const contentDataView = new DataView(binaryGeometry, gltfLength + this.BINARY_EXTENSION_HEADER_LENGTH + 1, header.contentLength);
|
|
@@ -52,11 +49,7 @@ export class SDGTFLoader {
|
|
|
52
49
|
return new TreeNode();
|
|
53
50
|
}
|
|
54
51
|
|
|
55
|
-
|
|
56
|
-
return await this.loadScene();
|
|
57
|
-
} catch (e) {
|
|
58
|
-
throw this._logger.handleError(LOGGING_TOPIC.DATA_PROCESSING, `SDGTFLoader.load`, e);
|
|
59
|
-
}
|
|
52
|
+
return await this.loadScene();
|
|
60
53
|
}
|
|
61
54
|
|
|
62
55
|
// #endregion Public Methods (1)
|
|
@@ -115,7 +108,7 @@ export class SDGTFLoader {
|
|
|
115
108
|
const arcZAxis = vec3.cross(vec3.create(), arcXAxis, arcYAxis)
|
|
116
109
|
|
|
117
110
|
if (arcRadius <= 0) {
|
|
118
|
-
this._logger.warn(
|
|
111
|
+
this._logger.warn('SDGTFLoader.loadArcs: Arc radius is <= 0.');
|
|
119
112
|
continue;
|
|
120
113
|
}
|
|
121
114
|
const points: number[] = [];
|
|
@@ -295,7 +288,7 @@ export class SDGTFLoader {
|
|
|
295
288
|
const circleZAxis = vec3.cross(vec3.create(), circleXAxis, circleYAxis)
|
|
296
289
|
|
|
297
290
|
if (circleRadius <= 0) {
|
|
298
|
-
this._logger.warn(
|
|
291
|
+
this._logger.warn('SDGTFLoader.loadCircles: Circle radius is <= 0.');
|
|
299
292
|
continue;
|
|
300
293
|
}
|
|
301
294
|
|
|
@@ -382,7 +375,7 @@ export class SDGTFLoader {
|
|
|
382
375
|
vec3.normalize(cylinderYAxis, cylinderYAxis);
|
|
383
376
|
|
|
384
377
|
if (cylinderRadius <= 0) {
|
|
385
|
-
this._logger.warn(
|
|
378
|
+
this._logger.warn('SDGTFLoader.loadCylinders: Cylinder radius is <= 0.');
|
|
386
379
|
continue;
|
|
387
380
|
}
|
|
388
381
|
|
|
@@ -505,7 +498,7 @@ export class SDGTFLoader {
|
|
|
505
498
|
const sphereTranslation = vec3.fromValues(data.array[index + 0], data.array[index + 1], data.array[index + 2]);
|
|
506
499
|
const sphereRadius = data.array[index + 3];
|
|
507
500
|
if (sphereRadius <= 0) {
|
|
508
|
-
this._logger.warn(
|
|
501
|
+
this._logger.warn('SDGTFLoader.loadSpheres: Sphere radius is <= 0.');
|
|
509
502
|
continue;
|
|
510
503
|
}
|
|
511
504
|
|
package/src/gltfv2/GLTFLoader.ts
CHANGED
|
@@ -3,12 +3,10 @@ import {
|
|
|
3
3
|
Converter,
|
|
4
4
|
HttpClient,
|
|
5
5
|
Logger,
|
|
6
|
-
LOGGING_TOPIC,
|
|
7
6
|
PerformanceEvaluator,
|
|
8
7
|
ShapeDiverViewerDataProcessingError,
|
|
9
8
|
UuidGenerator,
|
|
10
9
|
} from '@shapediver/viewer.shared.services'
|
|
11
|
-
import { container } from 'tsyringe'
|
|
12
10
|
import { IGLTF_v2 } from '@shapediver/viewer.data-engine.shared-types'
|
|
13
11
|
import { mat4, vec3, vec4 } from 'gl-matrix'
|
|
14
12
|
import {
|
|
@@ -58,12 +56,12 @@ export class GLTFLoader {
|
|
|
58
56
|
// #region Properties (17)
|
|
59
57
|
|
|
60
58
|
private readonly BINARY_EXTENSION_HEADER_LENGTH = 20;
|
|
61
|
-
private readonly _converter: Converter =
|
|
59
|
+
private readonly _converter: Converter = Converter.instance;
|
|
62
60
|
private readonly _globalTransformation = mat4.fromValues(1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1);
|
|
63
|
-
private readonly _httpClient: HttpClient =
|
|
64
|
-
private readonly _logger: Logger =
|
|
65
|
-
private readonly _performanceEvaluator =
|
|
66
|
-
private readonly _uuidGenerator: UuidGenerator =
|
|
61
|
+
private readonly _httpClient: HttpClient = HttpClient.instance;
|
|
62
|
+
private readonly _logger: Logger = Logger.instance;
|
|
63
|
+
private readonly _performanceEvaluator = PerformanceEvaluator.instance;
|
|
64
|
+
private readonly _uuidGenerator: UuidGenerator = UuidGenerator.instance;
|
|
67
65
|
|
|
68
66
|
private _accessorLoader!: AccessorLoader;
|
|
69
67
|
private _baseUri: string | undefined;
|
|
@@ -88,89 +86,81 @@ export class GLTFLoader {
|
|
|
88
86
|
this._body = gltfBinary.slice(this.BINARY_EXTENSION_HEADER_LENGTH + gltfHeader.contentLength + 8, gltfHeader.length);
|
|
89
87
|
this._content = content;
|
|
90
88
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
89
|
+
this.validateVersionAndExtensions();
|
|
90
|
+
|
|
91
|
+
const dracoModule = await new DRACO();
|
|
92
|
+
|
|
93
|
+
this._bufferLoader = new BufferLoader(this._content, this._body, this._baseUri);
|
|
94
|
+
await this._bufferLoader.load();
|
|
95
|
+
this._bufferViewLoader = new BufferViewLoader(this._content, this._bufferLoader);
|
|
96
|
+
this._bufferViewLoader.load();
|
|
97
|
+
this._accessorLoader = new AccessorLoader(this._content, this._bufferViewLoader);
|
|
98
|
+
this._accessorLoader.load();
|
|
99
|
+
this._textureLoader = new TextureLoader(this._content, this._bufferViewLoader, this._baseUri);
|
|
100
|
+
await this._textureLoader.load();
|
|
101
|
+
this._materialLoader = new MaterialLoader(this._content, this._textureLoader);
|
|
102
|
+
await this._materialLoader.load();
|
|
103
|
+
this._geometryLoader = new GeometryLoader(this._content, this._accessorLoader, this._bufferViewLoader, this._materialLoader, dracoModule);
|
|
104
|
+
|
|
105
|
+
const node = this.loadScene();
|
|
106
|
+
|
|
107
|
+
if (this._content.extensions && this._content.extensions[GLTF_EXTENSIONS.KHR_MATERIALS_VARIANTS]) {
|
|
108
|
+
const variants = this._content.extensions[GLTF_EXTENSIONS.KHR_MATERIALS_VARIANTS].variants;
|
|
109
|
+
for (let i = 0; i < variants.length; i++)
|
|
110
|
+
this._geometryLoader.materialVariantsData.variants.push(variants[i].name);
|
|
111
|
+
this._geometryLoader.materialVariantsData.variantIndex = 0;
|
|
112
|
+
node.data.push(this._geometryLoader.materialVariantsData)
|
|
113
|
+
}
|
|
117
114
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const bones: ITreeNode[] = [];
|
|
126
|
-
const boneInverses: mat4[] = [];
|
|
127
|
-
|
|
128
|
-
for (let j = 0; j < skinDef.joints.length; j++) {
|
|
129
|
-
this._nodes[skinDef.joints[j]].data.push(new BoneData())
|
|
130
|
-
bones.push(this._nodes[skinDef.joints[j]]);
|
|
131
|
-
|
|
132
|
-
let mat = mat4.create();
|
|
133
|
-
if (skinDef.inverseBindMatrices !== undefined) {
|
|
134
|
-
const matricesArray = skinDef.inverseBindMatrices!.array;
|
|
135
|
-
mat = mat4.fromValues(matricesArray[j * 16 + 0], matricesArray[j * 16 + 1], matricesArray[j * 16 + 2], matricesArray[j * 16 + 3],
|
|
136
|
-
matricesArray[j * 16 + 4], matricesArray[j * 16 + 5], matricesArray[j * 16 + 6], matricesArray[j * 16 + 7],
|
|
137
|
-
matricesArray[j * 16 + 8], matricesArray[j * 16 + 9], matricesArray[j * 16 + 10], matricesArray[j * 16 + 11],
|
|
138
|
-
matricesArray[j * 16 + 12], matricesArray[j * 16 + 13], matricesArray[j * 16 + 14], matricesArray[j * 16 + 15]);
|
|
139
|
-
}
|
|
140
|
-
boneInverses.push(mat);
|
|
141
|
-
}
|
|
115
|
+
if (this._content.skins !== undefined && this._content.nodes !== undefined) {
|
|
116
|
+
for (let i = 0; i < this._content.nodes?.length; i++) {
|
|
117
|
+
if (this._content.nodes[i].skin !== undefined) {
|
|
118
|
+
const skinDef = this.loadSkin(this._content.nodes[i].skin!);
|
|
119
|
+
|
|
120
|
+
const skinNode = this._nodes[i];
|
|
142
121
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
skinNode.boneInverses = boneInverses;
|
|
122
|
+
const bones: ITreeNode[] = [];
|
|
123
|
+
const boneInverses: mat4[] = [];
|
|
146
124
|
|
|
147
|
-
|
|
125
|
+
for (let j = 0; j < skinDef.joints.length; j++) {
|
|
126
|
+
this._nodes[skinDef.joints[j]].data.push(new BoneData())
|
|
127
|
+
bones.push(this._nodes[skinDef.joints[j]]);
|
|
128
|
+
|
|
129
|
+
let mat = mat4.create();
|
|
130
|
+
if (skinDef.inverseBindMatrices !== undefined) {
|
|
131
|
+
const matricesArray = skinDef.inverseBindMatrices!.array;
|
|
132
|
+
mat = mat4.fromValues(matricesArray[j * 16 + 0], matricesArray[j * 16 + 1], matricesArray[j * 16 + 2], matricesArray[j * 16 + 3],
|
|
133
|
+
matricesArray[j * 16 + 4], matricesArray[j * 16 + 5], matricesArray[j * 16 + 6], matricesArray[j * 16 + 7],
|
|
134
|
+
matricesArray[j * 16 + 8], matricesArray[j * 16 + 9], matricesArray[j * 16 + 10], matricesArray[j * 16 + 11],
|
|
135
|
+
matricesArray[j * 16 + 12], matricesArray[j * 16 + 13], matricesArray[j * 16 + 14], matricesArray[j * 16 + 15]);
|
|
136
|
+
}
|
|
137
|
+
boneInverses.push(mat);
|
|
148
138
|
}
|
|
139
|
+
|
|
140
|
+
skinNode.skinNode = true;
|
|
141
|
+
skinNode.bones = bones;
|
|
142
|
+
skinNode.boneInverses = boneInverses;
|
|
143
|
+
|
|
144
|
+
NodeTreeUtils.addBones(skinNode, skinNode);
|
|
149
145
|
}
|
|
150
146
|
}
|
|
151
|
-
|
|
152
|
-
if (this._content.animations)
|
|
153
|
-
for (let i = 0; i < this._content.animations?.length; i++)
|
|
154
|
-
node.data.push(this.loadAnimation(i));
|
|
155
|
-
return node;
|
|
156
|
-
} catch (e) {
|
|
157
|
-
throw this._logger.handleError(LOGGING_TOPIC.DATA_PROCESSING, `GLTFLoader.load`, e);
|
|
158
147
|
}
|
|
148
|
+
|
|
149
|
+
if (this._content.animations)
|
|
150
|
+
for (let i = 0; i < this._content.animations?.length; i++)
|
|
151
|
+
node.data.push(this.loadAnimation(i));
|
|
152
|
+
return node;
|
|
159
153
|
}
|
|
160
154
|
|
|
161
155
|
public async loadWithUrl(url?: string | undefined): Promise<ITreeNode> {
|
|
162
156
|
this._performanceEvaluator.startSection('gltfProcessing.' + url);
|
|
163
157
|
let axiosResponse;
|
|
164
158
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
this._performanceEvaluator.endSection('loadGltf.' + url);
|
|
171
|
-
} catch (e) {
|
|
172
|
-
throw this._logger.handleError(LOGGING_TOPIC.DATA_PROCESSING, `GLTFLoader.load`, e);
|
|
173
|
-
}
|
|
159
|
+
this._performanceEvaluator.startSection('loadGltf.' + url);
|
|
160
|
+
axiosResponse = await this._httpClient.get(url!, {
|
|
161
|
+
responseType: 'arraybuffer'
|
|
162
|
+
});
|
|
163
|
+
this._performanceEvaluator.endSection('loadGltf.' + url);
|
|
174
164
|
|
|
175
165
|
let gltfContent, gltfBinary, gltfBaseUrl, gltfHeader;
|
|
176
166
|
|
|
@@ -191,10 +181,9 @@ export class GLTFLoader {
|
|
|
191
181
|
contentLength: headerDataView.getUint32(12, true),
|
|
192
182
|
contentFormat: headerDataView.getUint32(16, true)
|
|
193
183
|
}
|
|
194
|
-
if (gltfHeader.magic != 'glTF')
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
184
|
+
if (gltfHeader.magic != 'glTF')
|
|
185
|
+
throw new ShapeDiverViewerDataProcessingError('GLTFLoader.load: Invalid data: sdgTF magic wrong.');
|
|
186
|
+
|
|
198
187
|
// create content
|
|
199
188
|
const contentDataView = new DataView(gltfBinary, this.BINARY_EXTENSION_HEADER_LENGTH, gltfHeader.contentLength);
|
|
200
189
|
const contentDecoded = new TextDecoder().decode(contentDataView);
|
|
@@ -251,7 +240,7 @@ export class GLTFLoader {
|
|
|
251
240
|
const output = this._accessorLoader.getAccessor(sampler.output);
|
|
252
241
|
let interpolation = sampler.interpolation;
|
|
253
242
|
if (interpolation === 'CUBICSPLINE') {
|
|
254
|
-
this._logger.warn(
|
|
243
|
+
this._logger.warn('Animation with CUBICSPLINE interpolation is currently not supported. Assigning linear interpolation instead.')
|
|
255
244
|
interpolation = 'linear';
|
|
256
245
|
}
|
|
257
246
|
|
|
@@ -481,7 +470,7 @@ export class GLTFLoader {
|
|
|
481
470
|
message += '"' + element + '"' + (index === notSupported.length - 1 ? '' : index === notSupported.length - 2 ? ' and ' : ', ');
|
|
482
471
|
});
|
|
483
472
|
message += (notSupported.length === 1 ? ' is' : ' are') + ' not supported, but used. Loading glTF regardless.';
|
|
484
|
-
this._logger.info(
|
|
473
|
+
this._logger.info('GLTFLoader.validateVersionAndExtensions: ' + message);
|
|
485
474
|
}
|
|
486
475
|
}
|
|
487
476
|
|
|
@@ -2,22 +2,16 @@ import { AttributeData } from '@shapediver/viewer.shared.types'
|
|
|
2
2
|
import {
|
|
3
3
|
ACCESSORCOMPONENTTYPE_V2 as ACCESSOR_COMPONENTTYPE,
|
|
4
4
|
ACCESSORTYPE_V2 as ACCESSORTYPE,
|
|
5
|
-
IGLTF_v2
|
|
6
|
-
IGLTF_v2_Material,
|
|
7
|
-
IGLTF_v2_Material_KHR_materials_pbrSpecularGlossiness,
|
|
8
|
-
IGLTF_v2_Primitive,
|
|
9
|
-
ISHAPEDIVER_materials_preset,
|
|
5
|
+
IGLTF_v2
|
|
10
6
|
} from '@shapediver/viewer.data-engine.shared-types'
|
|
11
|
-
import { Logger
|
|
12
|
-
import { container } from 'tsyringe'
|
|
7
|
+
import { Logger } from '@shapediver/viewer.shared.services'
|
|
13
8
|
|
|
14
|
-
import { BufferLoader } from './BufferLoader'
|
|
15
9
|
import { BufferViewLoader } from './BufferViewLoader'
|
|
16
10
|
|
|
17
11
|
export class AccessorLoader {
|
|
18
12
|
// #region Properties (2)
|
|
19
13
|
|
|
20
|
-
private readonly _logger: Logger =
|
|
14
|
+
private readonly _logger: Logger = Logger.instance;
|
|
21
15
|
|
|
22
16
|
private _loaded: {
|
|
23
17
|
[key: string]: AttributeData | null
|
|
@@ -58,7 +52,7 @@ export class AccessorLoader {
|
|
|
58
52
|
const arrayBuffer = this._bufferViewLoader.getBufferView(accessor.bufferView!);
|
|
59
53
|
|
|
60
54
|
const itemSize = ACCESSORTYPE[<keyof typeof ACCESSORTYPE>accessor.type];
|
|
61
|
-
if (accessor.componentType === 5124) this._logger.warn(
|
|
55
|
+
if (accessor.componentType === 5124) this._logger.warn('GLTFLoader.loadAccessor: The componentType for this accessor is 5124, which is not allowed. Trying to load it anyway.');
|
|
62
56
|
const ArrayType = ACCESSOR_COMPONENTTYPE[<keyof typeof ACCESSOR_COMPONENTTYPE>accessor.componentType];
|
|
63
57
|
|
|
64
58
|
const elementBytes = ArrayType.BYTES_PER_ELEMENT;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { container } from 'tsyringe'
|
|
2
1
|
import { IGLTF_v2 } from '@shapediver/viewer.data-engine.shared-types'
|
|
3
2
|
import { HttpClient } from '@shapediver/viewer.shared.services'
|
|
4
3
|
|
|
5
4
|
export class BufferLoader {
|
|
6
5
|
// #region Properties (2)
|
|
7
6
|
|
|
8
|
-
private readonly _httpClient: HttpClient =
|
|
7
|
+
private readonly _httpClient: HttpClient = HttpClient.instance;
|
|
9
8
|
|
|
10
9
|
private _loaded: {
|
|
11
10
|
[key: string]: ArrayBuffer
|
|
@@ -17,12 +17,12 @@ export class GeometryLoader {
|
|
|
17
17
|
// #region Constructors (1)
|
|
18
18
|
|
|
19
19
|
constructor(
|
|
20
|
-
private readonly _content: IGLTF_v2,
|
|
21
|
-
private readonly _accessorLoader: AccessorLoader,
|
|
22
|
-
private readonly _bufferViewLoader: BufferViewLoader,
|
|
20
|
+
private readonly _content: IGLTF_v2,
|
|
21
|
+
private readonly _accessorLoader: AccessorLoader,
|
|
22
|
+
private readonly _bufferViewLoader: BufferViewLoader,
|
|
23
23
|
private readonly _materialLoader: MaterialLoader,
|
|
24
24
|
private readonly _dracoModule: any
|
|
25
|
-
) {}
|
|
25
|
+
) { }
|
|
26
26
|
|
|
27
27
|
// #endregion Constructors (1)
|
|
28
28
|
|
|
@@ -69,19 +69,17 @@ export class GeometryLoader {
|
|
|
69
69
|
const arrayBuffer = this._bufferViewLoader.getBufferView(dracoDef.bufferView!);
|
|
70
70
|
|
|
71
71
|
const decoder = new this._dracoModule.Decoder();
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
const geometryType = decoder.GetEncodedGeometryType(buffer);
|
|
72
|
+
const array = new Int8Array(arrayBuffer);
|
|
73
|
+
const geometryType = decoder.GetEncodedGeometryType(array);
|
|
75
74
|
|
|
76
75
|
let dracoGeometry;
|
|
77
76
|
if (geometryType === this._dracoModule.TRIANGULAR_MESH) {
|
|
78
77
|
dracoGeometry = new this._dracoModule.Mesh();
|
|
79
|
-
decoder.
|
|
78
|
+
decoder.DecodeArrayToMesh(array, array.byteLength, dracoGeometry);
|
|
80
79
|
} else if (geometryType === this._dracoModule.POINT_CLOUD) {
|
|
81
80
|
dracoGeometry = new this._dracoModule.PointCloud();
|
|
82
|
-
decoder.
|
|
81
|
+
decoder.DecodeArrayToPointCloud(array, array.byteLength, dracoGeometry);
|
|
83
82
|
}
|
|
84
|
-
this._dracoModule.destroy(buffer);
|
|
85
83
|
|
|
86
84
|
if (dracoDef.attributes['POSITION'] === undefined) {
|
|
87
85
|
const errorMsg = "No position attribute found in the mesh.";
|
|
@@ -97,51 +95,41 @@ export class GeometryLoader {
|
|
|
97
95
|
|
|
98
96
|
const byteOffset = attribute.byte_offset();
|
|
99
97
|
const normalized = attribute.normalized();
|
|
100
|
-
const
|
|
101
|
-
const count = attributeData.size();
|
|
98
|
+
const numComponents = attribute.num_components();
|
|
102
99
|
|
|
103
|
-
const
|
|
100
|
+
const numPoints = dracoGeometry.num_points();
|
|
101
|
+
const numValues = numPoints * numComponents;
|
|
102
|
+
const byteLength = numValues * Float32Array.BYTES_PER_ELEMENT;
|
|
104
103
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
this._dracoModule.destroy(attributeData);
|
|
104
|
+
const ptr = this._dracoModule._malloc(byteLength);
|
|
105
|
+
decoder.GetAttributeDataArrayForAllPoints(dracoGeometry, attribute, this._dracoModule.DT_FLOAT32, byteLength, ptr);
|
|
106
|
+
const array = new Float32Array(this._dracoModule.HEAPF32.buffer, ptr, numValues).slice();
|
|
107
|
+
this._dracoModule._free(ptr);
|
|
108
|
+
|
|
109
|
+
if(a.includes("COLOR")) array.forEach((n, i) => array[i] = Math.max(0, Math.min(1, n)));
|
|
113
110
|
|
|
114
111
|
attributes[a] = new AttributeData(
|
|
115
112
|
array,
|
|
116
|
-
|
|
117
|
-
array.BYTES_PER_ELEMENT *
|
|
113
|
+
numComponents, // itemSize
|
|
114
|
+
array.BYTES_PER_ELEMENT * numComponents, // itemBytes = elementBytes * itemSize
|
|
118
115
|
byteOffset, // byteOffset
|
|
119
116
|
array.BYTES_PER_ELEMENT, // elementBytes
|
|
120
117
|
normalized, // normalized
|
|
121
|
-
array.length /
|
|
118
|
+
array.length / numComponents
|
|
122
119
|
);
|
|
123
120
|
}
|
|
124
121
|
|
|
125
|
-
const numFaces = geometryType == this._dracoModule.TRIANGULAR_MESH ? dracoGeometry.num_faces() : 0;
|
|
126
|
-
const numIndices = numFaces * 3;
|
|
127
|
-
const indexArray = new Uint32Array(numIndices);
|
|
128
|
-
|
|
129
|
-
// For mesh, we need to generate the faces.
|
|
130
122
|
if (geometryType == this._dracoModule.TRIANGULAR_MESH) {
|
|
131
|
-
const ia = new this._dracoModule.DracoInt32Array();
|
|
132
|
-
for (let i = 0; i < numFaces; ++i) {
|
|
133
|
-
decoder.GetFaceFromMesh(dracoGeometry, i, ia);
|
|
134
|
-
const index = i * 3;
|
|
135
|
-
indexArray[index] = ia.GetValue(0);
|
|
136
|
-
indexArray[index + 1] = ia.GetValue(1);
|
|
137
|
-
indexArray[index + 2] = ia.GetValue(2);
|
|
138
|
-
}
|
|
139
|
-
this._dracoModule.destroy(ia);
|
|
140
|
-
}
|
|
141
|
-
this._dracoModule.destroy(decoder);
|
|
142
|
-
this._dracoModule.destroy(dracoGeometry);
|
|
143
123
|
|
|
144
|
-
|
|
124
|
+
const numFaces = dracoGeometry.num_faces();
|
|
125
|
+
const numIndices = numFaces * 3;
|
|
126
|
+
const byteLength = numIndices * 4;
|
|
127
|
+
|
|
128
|
+
const ptr = this._dracoModule._malloc(byteLength);
|
|
129
|
+
decoder.GetTrianglesUInt32Array(dracoGeometry, byteLength, ptr);
|
|
130
|
+
const indexArray = new Uint32Array(this._dracoModule.HEAPF32.buffer, ptr, numIndices).slice();
|
|
131
|
+
this._dracoModule._free(ptr);
|
|
132
|
+
|
|
145
133
|
indices = new AttributeData(
|
|
146
134
|
indexArray,
|
|
147
135
|
1, // itemSize
|
|
@@ -151,6 +139,10 @@ export class GeometryLoader {
|
|
|
151
139
|
false, // normalized
|
|
152
140
|
indexArray.length // count
|
|
153
141
|
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
this._dracoModule.destroy(decoder);
|
|
145
|
+
this._dracoModule.destroy(dracoGeometry);
|
|
154
146
|
}
|
|
155
147
|
|
|
156
148
|
for (let attribute in primitive.attributes) {
|
|
@@ -159,6 +151,7 @@ export class GeometryLoader {
|
|
|
159
151
|
continue;
|
|
160
152
|
}
|
|
161
153
|
|
|
154
|
+
|
|
162
155
|
let attributeName = attribute;
|
|
163
156
|
// attribute name conversion to be consistent with gltf
|
|
164
157
|
if (/\d/.test(attributeName) && !attributeName.includes('_')) {
|
|
@@ -174,7 +167,7 @@ export class GeometryLoader {
|
|
|
174
167
|
attributes[attributeName] = (this._accessorLoader.getAccessor(primitive.attributes[attribute]))!;
|
|
175
168
|
}
|
|
176
169
|
|
|
177
|
-
if ((primitive.indices || primitive.indices === 0) && !indices)
|
|
170
|
+
if ((primitive.indices || primitive.indices === 0) && !indices)
|
|
178
171
|
indices = this._accessorLoader.getAccessor(primitive.indices);
|
|
179
172
|
|
|
180
173
|
// reading and assigning morph targets
|