@babylonjs/serializers 5.0.0-rc.6 → 5.0.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 (74) hide show
  1. package/OBJ/index.d.ts +1 -1
  2. package/OBJ/index.js +1 -1
  3. package/OBJ/objSerializer.d.ts +21 -21
  4. package/OBJ/objSerializer.js +174 -174
  5. package/OBJ/objSerializer.js.map +1 -1
  6. package/glTF/2.0/Extensions/KHR_lights_punctual.d.ts +41 -41
  7. package/glTF/2.0/Extensions/KHR_lights_punctual.js +189 -189
  8. package/glTF/2.0/Extensions/KHR_lights_punctual.js.map +1 -1
  9. package/glTF/2.0/Extensions/KHR_materials_clearcoat.d.ts +24 -24
  10. package/glTF/2.0/Extensions/KHR_materials_clearcoat.js +90 -90
  11. package/glTF/2.0/Extensions/KHR_materials_clearcoat.js.map +1 -1
  12. package/glTF/2.0/Extensions/KHR_materials_sheen.d.ts +24 -24
  13. package/glTF/2.0/Extensions/KHR_materials_sheen.js +73 -73
  14. package/glTF/2.0/Extensions/KHR_materials_sheen.js.map +1 -1
  15. package/glTF/2.0/Extensions/KHR_materials_unlit.d.ts +20 -20
  16. package/glTF/2.0/Extensions/KHR_materials_unlit.js +51 -51
  17. package/glTF/2.0/Extensions/KHR_materials_unlit.js.map +1 -1
  18. package/glTF/2.0/Extensions/KHR_texture_transform.d.ts +30 -30
  19. package/glTF/2.0/Extensions/KHR_texture_transform.js +137 -137
  20. package/glTF/2.0/Extensions/KHR_texture_transform.js.map +1 -1
  21. package/glTF/2.0/Extensions/index.d.ts +5 -5
  22. package/glTF/2.0/Extensions/index.js +5 -5
  23. package/glTF/2.0/glTFAnimation.d.ts +206 -205
  24. package/glTF/2.0/glTFAnimation.js +852 -852
  25. package/glTF/2.0/glTFAnimation.js.map +1 -1
  26. package/glTF/2.0/glTFData.d.ts +19 -19
  27. package/glTF/2.0/glTFData.js +52 -52
  28. package/glTF/2.0/glTFExporter.d.ts +456 -455
  29. package/glTF/2.0/glTFExporter.js +1975 -1972
  30. package/glTF/2.0/glTFExporter.js.map +1 -1
  31. package/glTF/2.0/glTFExporterExtension.d.ts +74 -74
  32. package/glTF/2.0/glTFExporterExtension.js +3 -3
  33. package/glTF/2.0/glTFExporterExtension.js.map +1 -1
  34. package/glTF/2.0/glTFMaterialExporter.d.ts +208 -207
  35. package/glTF/2.0/glTFMaterialExporter.js +1114 -1110
  36. package/glTF/2.0/glTFMaterialExporter.js.map +1 -1
  37. package/glTF/2.0/glTFSerializer.d.ts +60 -60
  38. package/glTF/2.0/glTFSerializer.js +62 -62
  39. package/glTF/2.0/glTFSerializer.js.map +1 -1
  40. package/glTF/2.0/glTFUtilities.d.ts +99 -97
  41. package/glTF/2.0/glTFUtilities.js +196 -196
  42. package/glTF/2.0/glTFUtilities.js.map +1 -1
  43. package/glTF/2.0/index.d.ts +8 -8
  44. package/glTF/2.0/index.js +9 -8
  45. package/glTF/2.0/index.js.map +1 -1
  46. package/glTF/2.0/shaders/textureTransform.fragment.d.ts +5 -5
  47. package/glTF/2.0/shaders/textureTransform.fragment.js +8 -8
  48. package/glTF/glTFFileExporter.d.ts +20 -20
  49. package/glTF/glTFFileExporter.js +3 -3
  50. package/glTF/index.d.ts +2 -2
  51. package/glTF/index.js +3 -2
  52. package/glTF/index.js.map +1 -1
  53. package/index.d.ts +3 -3
  54. package/index.js +4 -3
  55. package/index.js.map +1 -1
  56. package/legacy/legacy-glTF2Serializer.d.ts +2 -2
  57. package/legacy/legacy-glTF2Serializer.js +44 -43
  58. package/legacy/legacy-glTF2Serializer.js.map +1 -1
  59. package/legacy/legacy-objSerializer.d.ts +1 -1
  60. package/legacy/legacy-objSerializer.js +13 -12
  61. package/legacy/legacy-objSerializer.js.map +1 -1
  62. package/legacy/legacy-stlSerializer.d.ts +1 -1
  63. package/legacy/legacy-stlSerializer.js +13 -12
  64. package/legacy/legacy-stlSerializer.js.map +1 -1
  65. package/legacy/legacy.d.ts +4 -4
  66. package/legacy/legacy.js +6 -5
  67. package/legacy/legacy.js.map +1 -1
  68. package/license.md +71 -0
  69. package/package.json +25 -6
  70. package/stl/index.d.ts +1 -1
  71. package/stl/index.js +1 -1
  72. package/stl/stlSerializer.d.ts +17 -17
  73. package/stl/stlSerializer.js +107 -107
  74. package/stl/stlSerializer.js.map +1 -1
@@ -1,1973 +1,1976 @@
1
- import { __spreadArray } from "tslib";
2
- import { Vector2, Vector3, Vector4, Quaternion } from "@babylonjs/core/Maths/math.vector.js";
3
- import { Color3, Color4 } from "@babylonjs/core/Maths/math.color.js";
4
- import { Tools } from "@babylonjs/core/Misc/tools.js";
5
- import { VertexBuffer } from "@babylonjs/core/Buffers/buffer.js";
6
- import { TransformNode } from "@babylonjs/core/Meshes/transformNode.js";
7
- import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh.js";
8
- import { Mesh } from "@babylonjs/core/Meshes/mesh.js";
9
- import { LinesMesh } from "@babylonjs/core/Meshes/linesMesh.js";
10
- import { InstancedMesh } from "@babylonjs/core/Meshes/instancedMesh.js";
11
- import { Material } from "@babylonjs/core/Materials/material.js";
12
- import { _GLTFMaterialExporter } from "./glTFMaterialExporter.js";
13
- import { _GLTFUtilities } from "./glTFUtilities.js";
14
- import { GLTFData } from "./glTFData.js";
15
- import { _GLTFAnimation } from "./glTFAnimation.js";
16
- import { Camera } from "@babylonjs/core/Cameras/camera.js";
17
- import { EngineStore } from "@babylonjs/core/Engines/engineStore.js";
18
- import { MultiMaterial } from "@babylonjs/core/Materials/multiMaterial.js";
19
- /**
20
- * Converts Babylon Scene into glTF 2.0.
21
- * @hidden
22
- */
23
- var _Exporter = /** @class */ (function () {
24
- /**
25
- * Creates a glTF Exporter instance, which can accept optional exporter options
26
- * @param babylonScene Babylon scene object
27
- * @param options Options to modify the behavior of the exporter
28
- */
29
- function _Exporter(babylonScene, options) {
30
- /*
31
- * Specifies if root Babylon empty nodes that act as a coordinate space transform should be included in export
32
- */
33
- this._includeCoordinateSystemConversionNodes = false;
34
- this._extensions = {};
35
- this._glTF = {
36
- asset: { generator: "BabylonJS", version: "2.0" },
37
- };
38
- babylonScene = babylonScene || EngineStore.LastCreatedScene;
39
- if (!babylonScene) {
40
- return;
41
- }
42
- this._babylonScene = babylonScene;
43
- this._bufferViews = [];
44
- this._accessors = [];
45
- this._meshes = [];
46
- this._scenes = [];
47
- this._cameras = [];
48
- this._nodes = [];
49
- this._images = [];
50
- this._materials = [];
51
- this._materialMap = [];
52
- this._textures = [];
53
- this._samplers = [];
54
- this._skins = [];
55
- this._animations = [];
56
- this._imageData = {};
57
- this._orderedImageData = [];
58
- this._options = options || {};
59
- this._animationSampleRate = options && options.animationSampleRate ? options.animationSampleRate : 1 / 60;
60
- this._includeCoordinateSystemConversionNodes = options && options.includeCoordinateSystemConversionNodes ? true : false;
61
- this._glTFMaterialExporter = new _GLTFMaterialExporter(this);
62
- this._loadExtensions();
63
- }
64
- _Exporter.prototype._applyExtension = function (node, extensions, index, actionAsync) {
65
- var _this = this;
66
- if (index >= extensions.length) {
67
- return Promise.resolve(node);
68
- }
69
- var currentPromise = actionAsync(extensions[index], node);
70
- if (!currentPromise) {
71
- return this._applyExtension(node, extensions, index + 1, actionAsync);
72
- }
73
- return currentPromise.then(function (newNode) { return _this._applyExtension(newNode, extensions, index + 1, actionAsync); });
74
- };
75
- _Exporter.prototype._applyExtensions = function (node, actionAsync) {
76
- var extensions = [];
77
- for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
78
- var name_1 = _a[_i];
79
- extensions.push(this._extensions[name_1]);
80
- }
81
- return this._applyExtension(node, extensions, 0, actionAsync);
82
- };
83
- _Exporter.prototype._extensionsPreExportTextureAsync = function (context, babylonTexture, mimeType) {
84
- return this._applyExtensions(babylonTexture, function (extension, node) { return extension.preExportTextureAsync && extension.preExportTextureAsync(context, node, mimeType); });
85
- };
86
- _Exporter.prototype._extensionsPostExportMeshPrimitiveAsync = function (context, meshPrimitive, babylonSubMesh, binaryWriter) {
87
- return this._applyExtensions(meshPrimitive, function (extension, node) { return extension.postExportMeshPrimitiveAsync && extension.postExportMeshPrimitiveAsync(context, node, babylonSubMesh, binaryWriter); });
88
- };
89
- _Exporter.prototype._extensionsPostExportNodeAsync = function (context, node, babylonNode, nodeMap) {
90
- return this._applyExtensions(node, function (extension, node) { return extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode, nodeMap); });
91
- };
92
- _Exporter.prototype._extensionsPostExportMaterialAsync = function (context, material, babylonMaterial) {
93
- return this._applyExtensions(material, function (extension, node) { return extension.postExportMaterialAsync && extension.postExportMaterialAsync(context, node, babylonMaterial); });
94
- };
95
- _Exporter.prototype._extensionsPostExportMaterialAdditionalTextures = function (context, material, babylonMaterial) {
96
- var output = [];
97
- for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
98
- var name_2 = _a[_i];
99
- var extension = this._extensions[name_2];
100
- if (extension.postExportMaterialAdditionalTextures) {
101
- output.push.apply(output, extension.postExportMaterialAdditionalTextures(context, material, babylonMaterial));
102
- }
103
- }
104
- return output;
105
- };
106
- _Exporter.prototype._extensionsPostExportTextures = function (context, textureInfo, babylonTexture) {
107
- for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
108
- var name_3 = _a[_i];
109
- var extension = this._extensions[name_3];
110
- if (extension.postExportTexture) {
111
- extension.postExportTexture(context, textureInfo, babylonTexture);
112
- }
113
- }
114
- };
115
- _Exporter.prototype._forEachExtensions = function (action) {
116
- for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
117
- var name_4 = _a[_i];
118
- var extension = this._extensions[name_4];
119
- if (extension.enabled) {
120
- action(extension);
121
- }
122
- }
123
- };
124
- _Exporter.prototype._extensionsOnExporting = function () {
125
- var _this = this;
126
- this._forEachExtensions(function (extension) {
127
- if (extension.wasUsed) {
128
- if (_this._glTF.extensionsUsed == null) {
129
- _this._glTF.extensionsUsed = [];
130
- }
131
- if (_this._glTF.extensionsUsed.indexOf(extension.name) === -1) {
132
- _this._glTF.extensionsUsed.push(extension.name);
133
- }
134
- if (extension.required) {
135
- if (_this._glTF.extensionsRequired == null) {
136
- _this._glTF.extensionsRequired = [];
137
- }
138
- if (_this._glTF.extensionsRequired.indexOf(extension.name) === -1) {
139
- _this._glTF.extensionsRequired.push(extension.name);
140
- }
141
- }
142
- if (_this._glTF.extensions == null) {
143
- _this._glTF.extensions = {};
144
- }
145
- if (extension.onExporting) {
146
- extension.onExporting();
147
- }
148
- }
149
- });
150
- };
151
- /**
152
- * Load glTF serializer extensions
153
- */
154
- _Exporter.prototype._loadExtensions = function () {
155
- for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
156
- var name_5 = _a[_i];
157
- var extension = _Exporter._ExtensionFactories[name_5](this);
158
- this._extensions[name_5] = extension;
159
- }
160
- };
161
- _Exporter.prototype.dispose = function () {
162
- for (var extensionKey in this._extensions) {
163
- var extension = this._extensions[extensionKey];
164
- extension.dispose();
165
- }
166
- };
167
- /**
168
- * Registers a glTF exporter extension
169
- * @param name Name of the extension to export
170
- * @param factory The factory function that creates the exporter extension
171
- */
172
- _Exporter.RegisterExtension = function (name, factory) {
173
- if (_Exporter.UnregisterExtension(name)) {
174
- Tools.Warn("Extension with the name ".concat(name, " already exists"));
175
- }
176
- _Exporter._ExtensionFactories[name] = factory;
177
- _Exporter._ExtensionNames.push(name);
178
- };
179
- /**
180
- * Un-registers an exporter extension
181
- * @param name The name fo the exporter extension
182
- * @returns A boolean indicating whether the extension has been un-registered
183
- */
184
- _Exporter.UnregisterExtension = function (name) {
185
- if (!_Exporter._ExtensionFactories[name]) {
186
- return false;
187
- }
188
- delete _Exporter._ExtensionFactories[name];
189
- var index = _Exporter._ExtensionNames.indexOf(name);
190
- if (index !== -1) {
191
- _Exporter._ExtensionNames.splice(index, 1);
192
- }
193
- return true;
194
- };
195
- _Exporter.prototype._reorderIndicesBasedOnPrimitiveMode = function (submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter) {
196
- switch (primitiveMode) {
197
- case Material.TriangleFillMode: {
198
- if (!byteOffset) {
199
- byteOffset = 0;
200
- }
201
- for (var i = submesh.indexStart, length_1 = submesh.indexStart + submesh.indexCount; i < length_1; i = i + 3) {
202
- var index = byteOffset + i * 4;
203
- // swap the second and third indices
204
- var secondIndex = binaryWriter.getUInt32(index + 4);
205
- var thirdIndex = binaryWriter.getUInt32(index + 8);
206
- binaryWriter.setUInt32(thirdIndex, index + 4);
207
- binaryWriter.setUInt32(secondIndex, index + 8);
208
- }
209
- break;
210
- }
211
- case Material.TriangleFanDrawMode: {
212
- for (var i = submesh.indexStart + submesh.indexCount - 1, start = submesh.indexStart; i >= start; --i) {
213
- binaryWriter.setUInt32(babylonIndices[i], byteOffset);
214
- byteOffset += 4;
215
- }
216
- break;
217
- }
218
- case Material.TriangleStripDrawMode: {
219
- if (submesh.indexCount >= 3) {
220
- binaryWriter.setUInt32(babylonIndices[submesh.indexStart + 2], byteOffset + 4);
221
- binaryWriter.setUInt32(babylonIndices[submesh.indexStart + 1], byteOffset + 8);
222
- }
223
- break;
224
- }
225
- }
226
- };
227
- /**
228
- * Reorders the vertex attribute data based on the primitive mode. This is necessary when indices are not available and the winding order is
229
- * clock-wise during export to glTF
230
- * @param submesh BabylonJS submesh
231
- * @param primitiveMode Primitive mode of the mesh
232
- * @param sideOrientation the winding order of the submesh
233
- * @param vertexBufferKind The type of vertex attribute
234
- * @param meshAttributeArray The vertex attribute data
235
- * @param byteOffset The offset to the binary data
236
- * @param binaryWriter The binary data for the glTF file
237
- * @param convertToRightHandedSystem Converts the values to right-handed
238
- */
239
- _Exporter.prototype._reorderVertexAttributeDataBasedOnPrimitiveMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
240
- if (convertToRightHandedSystem && sideOrientation === Material.ClockWiseSideOrientation) {
241
- switch (primitiveMode) {
242
- case Material.TriangleFillMode: {
243
- this._reorderTriangleFillMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
244
- break;
245
- }
246
- case Material.TriangleStripDrawMode: {
247
- this._reorderTriangleStripDrawMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
248
- break;
249
- }
250
- case Material.TriangleFanDrawMode: {
251
- this._reorderTriangleFanMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
252
- break;
253
- }
254
- }
255
- }
256
- };
257
- /**
258
- * Reorders the vertex attributes in the correct triangle mode order . This is necessary when indices are not available and the winding order is
259
- * clock-wise during export to glTF
260
- * @param submesh BabylonJS submesh
261
- * @param primitiveMode Primitive mode of the mesh
262
- * @param sideOrientation the winding order of the submesh
263
- * @param vertexBufferKind The type of vertex attribute
264
- * @param meshAttributeArray The vertex attribute data
265
- * @param byteOffset The offset to the binary data
266
- * @param binaryWriter The binary data for the glTF file
267
- * @param convertToRightHandedSystem Converts the values to right-handed
268
- */
269
- _Exporter.prototype._reorderTriangleFillMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
270
- var vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
271
- if (vertexBuffer) {
272
- var stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);
273
- if (submesh.verticesCount % 3 !== 0) {
274
- Tools.Error("The submesh vertices for the triangle fill mode is not divisible by 3!");
275
- }
276
- else {
277
- var vertexData = [];
278
- var index = 0;
279
- switch (vertexBufferKind) {
280
- case VertexBuffer.PositionKind:
281
- case VertexBuffer.NormalKind: {
282
- for (var x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) {
283
- index = x * stride;
284
- vertexData.push(Vector3.FromArray(meshAttributeArray, index));
285
- vertexData.push(Vector3.FromArray(meshAttributeArray, index + 2 * stride));
286
- vertexData.push(Vector3.FromArray(meshAttributeArray, index + stride));
287
- }
288
- break;
289
- }
290
- case VertexBuffer.TangentKind: {
291
- for (var x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) {
292
- index = x * stride;
293
- vertexData.push(Vector4.FromArray(meshAttributeArray, index));
294
- vertexData.push(Vector4.FromArray(meshAttributeArray, index + 2 * stride));
295
- vertexData.push(Vector4.FromArray(meshAttributeArray, index + stride));
296
- }
297
- break;
298
- }
299
- case VertexBuffer.ColorKind: {
300
- var size = vertexBuffer.getSize();
301
- for (var x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + size) {
302
- index = x * stride;
303
- if (size === 4) {
304
- vertexData.push(Vector4.FromArray(meshAttributeArray, index));
305
- vertexData.push(Vector4.FromArray(meshAttributeArray, index + 2 * stride));
306
- vertexData.push(Vector4.FromArray(meshAttributeArray, index + stride));
307
- }
308
- else {
309
- vertexData.push(Vector3.FromArray(meshAttributeArray, index));
310
- vertexData.push(Vector3.FromArray(meshAttributeArray, index + 2 * stride));
311
- vertexData.push(Vector3.FromArray(meshAttributeArray, index + stride));
312
- }
313
- }
314
- break;
315
- }
316
- case VertexBuffer.UVKind:
317
- case VertexBuffer.UV2Kind: {
318
- for (var x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) {
319
- index = x * stride;
320
- vertexData.push(Vector2.FromArray(meshAttributeArray, index));
321
- vertexData.push(Vector2.FromArray(meshAttributeArray, index + 2 * stride));
322
- vertexData.push(Vector2.FromArray(meshAttributeArray, index + stride));
323
- }
324
- break;
325
- }
326
- default: {
327
- Tools.Error("Unsupported Vertex Buffer type: ".concat(vertexBufferKind));
328
- }
329
- }
330
- this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
331
- }
332
- }
333
- else {
334
- Tools.Warn("reorderTriangleFillMode: Vertex Buffer Kind ".concat(vertexBufferKind, " not present!"));
335
- }
336
- };
337
- /**
338
- * Reorders the vertex attributes in the correct triangle strip order. This is necessary when indices are not available and the winding order is
339
- * clock-wise during export to glTF
340
- * @param submesh BabylonJS submesh
341
- * @param primitiveMode Primitive mode of the mesh
342
- * @param sideOrientation the winding order of the submesh
343
- * @param vertexBufferKind The type of vertex attribute
344
- * @param meshAttributeArray The vertex attribute data
345
- * @param byteOffset The offset to the binary data
346
- * @param binaryWriter The binary data for the glTF file
347
- * @param convertToRightHandedSystem Converts the values to right-handed
348
- */
349
- _Exporter.prototype._reorderTriangleStripDrawMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
350
- var vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
351
- if (vertexBuffer) {
352
- var stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);
353
- var vertexData = [];
354
- var index = 0;
355
- switch (vertexBufferKind) {
356
- case VertexBuffer.PositionKind:
357
- case VertexBuffer.NormalKind: {
358
- index = submesh.verticesStart;
359
- vertexData.push(Vector3.FromArray(meshAttributeArray, index + 2 * stride));
360
- vertexData.push(Vector3.FromArray(meshAttributeArray, index + stride));
361
- break;
362
- }
363
- case VertexBuffer.TangentKind: {
364
- for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
365
- index = x * stride;
366
- vertexData.push(Vector4.FromArray(meshAttributeArray, index));
367
- }
368
- break;
369
- }
370
- case VertexBuffer.ColorKind: {
371
- for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
372
- index = x * stride;
373
- vertexBuffer.getSize() === 4
374
- ? vertexData.push(Vector4.FromArray(meshAttributeArray, index))
375
- : vertexData.push(Vector3.FromArray(meshAttributeArray, index));
376
- }
377
- break;
378
- }
379
- case VertexBuffer.UVKind:
380
- case VertexBuffer.UV2Kind: {
381
- for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
382
- index = x * stride;
383
- vertexData.push(Vector2.FromArray(meshAttributeArray, index));
384
- }
385
- break;
386
- }
387
- default: {
388
- Tools.Error("Unsupported Vertex Buffer type: ".concat(vertexBufferKind));
389
- }
390
- }
391
- this._writeVertexAttributeData(vertexData, byteOffset + 12, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
392
- }
393
- else {
394
- Tools.Warn("reorderTriangleStripDrawMode: Vertex buffer kind ".concat(vertexBufferKind, " not present!"));
395
- }
396
- };
397
- /**
398
- * Reorders the vertex attributes in the correct triangle fan order. This is necessary when indices are not available and the winding order is
399
- * clock-wise during export to glTF
400
- * @param submesh BabylonJS submesh
401
- * @param primitiveMode Primitive mode of the mesh
402
- * @param sideOrientation the winding order of the submesh
403
- * @param vertexBufferKind The type of vertex attribute
404
- * @param meshAttributeArray The vertex attribute data
405
- * @param byteOffset The offset to the binary data
406
- * @param binaryWriter The binary data for the glTF file
407
- * @param convertToRightHandedSystem Converts the values to right-handed
408
- */
409
- _Exporter.prototype._reorderTriangleFanMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
410
- var vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
411
- if (vertexBuffer) {
412
- var stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);
413
- var vertexData = [];
414
- var index = 0;
415
- switch (vertexBufferKind) {
416
- case VertexBuffer.PositionKind:
417
- case VertexBuffer.NormalKind: {
418
- for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
419
- index = x * stride;
420
- vertexData.push(Vector3.FromArray(meshAttributeArray, index));
421
- }
422
- break;
423
- }
424
- case VertexBuffer.TangentKind: {
425
- for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
426
- index = x * stride;
427
- vertexData.push(Vector4.FromArray(meshAttributeArray, index));
428
- }
429
- break;
430
- }
431
- case VertexBuffer.ColorKind: {
432
- for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
433
- index = x * stride;
434
- vertexData.push(Vector4.FromArray(meshAttributeArray, index));
435
- vertexBuffer.getSize() === 4
436
- ? vertexData.push(Vector4.FromArray(meshAttributeArray, index))
437
- : vertexData.push(Vector3.FromArray(meshAttributeArray, index));
438
- }
439
- break;
440
- }
441
- case VertexBuffer.UVKind:
442
- case VertexBuffer.UV2Kind: {
443
- for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
444
- index = x * stride;
445
- vertexData.push(Vector2.FromArray(meshAttributeArray, index));
446
- }
447
- break;
448
- }
449
- default: {
450
- Tools.Error("Unsupported Vertex Buffer type: ".concat(vertexBufferKind));
451
- }
452
- }
453
- this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
454
- }
455
- else {
456
- Tools.Warn("reorderTriangleFanMode: Vertex buffer kind ".concat(vertexBufferKind, " not present!"));
457
- }
458
- };
459
- /**
460
- * Writes the vertex attribute data to binary
461
- * @param vertices The vertices to write to the binary writer
462
- * @param byteOffset The offset into the binary writer to overwrite binary data
463
- * @param vertexAttributeKind The vertex attribute type
464
- * @param meshAttributeArray The vertex attribute data
465
- * @param binaryWriter The writer containing the binary data
466
- * @param convertToRightHandedSystem Converts the values to right-handed
467
- */
468
- _Exporter.prototype._writeVertexAttributeData = function (vertices, byteOffset, vertexAttributeKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem) {
469
- for (var _i = 0, vertices_1 = vertices; _i < vertices_1.length; _i++) {
470
- var vertex = vertices_1[_i];
471
- if (convertToRightHandedSystem && !(vertexAttributeKind === VertexBuffer.ColorKind) && !(vertex instanceof Vector2)) {
472
- if (vertex instanceof Vector3) {
473
- if (vertexAttributeKind === VertexBuffer.NormalKind) {
474
- _GLTFUtilities._GetRightHandedNormalVector3FromRef(vertex);
475
- }
476
- else if (vertexAttributeKind === VertexBuffer.PositionKind) {
477
- _GLTFUtilities._GetRightHandedPositionVector3FromRef(vertex);
478
- }
479
- else {
480
- Tools.Error("Unsupported vertex attribute kind!");
481
- }
482
- }
483
- else {
484
- _GLTFUtilities._GetRightHandedVector4FromRef(vertex);
485
- }
486
- }
487
- if (vertexAttributeKind === VertexBuffer.NormalKind) {
488
- vertex.normalize();
489
- }
490
- else if (vertexAttributeKind === VertexBuffer.TangentKind && vertex instanceof Vector4) {
491
- _GLTFUtilities._NormalizeTangentFromRef(vertex);
492
- }
493
- for (var _a = 0, _b = vertex.asArray(); _a < _b.length; _a++) {
494
- var component = _b[_a];
495
- binaryWriter.setFloat32(component, byteOffset);
496
- byteOffset += 4;
497
- }
498
- }
499
- };
500
- /**
501
- * Writes mesh attribute data to a data buffer
502
- * Returns the bytelength of the data
503
- * @param vertexBufferKind Indicates what kind of vertex data is being passed in
504
- * @param attributeComponentKind
505
- * @param meshAttributeArray Array containing the attribute data
506
- * @param stride Specifies the space between data
507
- * @param binaryWriter The buffer to write the binary data to
508
- * @param convertToRightHandedSystem Converts the values to right-handed
509
- * @param babylonTransformNode
510
- */
511
- _Exporter.prototype._writeAttributeData = function (vertexBufferKind, attributeComponentKind, meshAttributeArray, stride, binaryWriter, convertToRightHandedSystem, babylonTransformNode) {
512
- var vertexAttributes = [];
513
- var index;
514
- switch (vertexBufferKind) {
515
- case VertexBuffer.PositionKind: {
516
- for (var k = 0, length_2 = meshAttributeArray.length / stride; k < length_2; ++k) {
517
- index = k * stride;
518
- var vertexData = Vector3.FromArray(meshAttributeArray, index);
519
- if (convertToRightHandedSystem) {
520
- _GLTFUtilities._GetRightHandedPositionVector3FromRef(vertexData);
521
- }
522
- vertexAttributes.push(vertexData.asArray());
523
- }
524
- break;
525
- }
526
- case VertexBuffer.NormalKind: {
527
- for (var k = 0, length_3 = meshAttributeArray.length / stride; k < length_3; ++k) {
528
- index = k * stride;
529
- var vertexData = Vector3.FromArray(meshAttributeArray, index);
530
- if (convertToRightHandedSystem) {
531
- _GLTFUtilities._GetRightHandedNormalVector3FromRef(vertexData);
532
- }
533
- vertexData.normalize();
534
- vertexAttributes.push(vertexData.asArray());
535
- }
536
- break;
537
- }
538
- case VertexBuffer.TangentKind: {
539
- for (var k = 0, length_4 = meshAttributeArray.length / stride; k < length_4; ++k) {
540
- index = k * stride;
541
- var vertexData = Vector4.FromArray(meshAttributeArray, index);
542
- if (convertToRightHandedSystem) {
543
- _GLTFUtilities._GetRightHandedVector4FromRef(vertexData);
544
- }
545
- _GLTFUtilities._NormalizeTangentFromRef(vertexData);
546
- vertexAttributes.push(vertexData.asArray());
547
- }
548
- break;
549
- }
550
- case VertexBuffer.ColorKind: {
551
- var meshMaterial = babylonTransformNode.material;
552
- var convertToLinear = meshMaterial ? meshMaterial.getClassName() === "StandardMaterial" : true;
553
- var vertexData = stride === 3 ? new Color3() : new Color4();
554
- for (var k = 0, length_5 = meshAttributeArray.length / stride; k < length_5; ++k) {
555
- index = k * stride;
556
- if (stride === 3) {
557
- Color3.FromArrayToRef(meshAttributeArray, index, vertexData);
558
- if (convertToLinear) {
559
- vertexData.toLinearSpaceToRef(vertexData);
560
- }
561
- }
562
- else {
563
- Color4.FromArrayToRef(meshAttributeArray, index, vertexData);
564
- if (convertToLinear) {
565
- vertexData.toLinearSpaceToRef(vertexData);
566
- }
567
- }
568
- vertexAttributes.push(vertexData.asArray());
569
- }
570
- break;
571
- }
572
- case VertexBuffer.UVKind:
573
- case VertexBuffer.UV2Kind: {
574
- for (var k = 0, length_6 = meshAttributeArray.length / stride; k < length_6; ++k) {
575
- index = k * stride;
576
- vertexAttributes.push(convertToRightHandedSystem ? [meshAttributeArray[index], meshAttributeArray[index + 1]] : [meshAttributeArray[index], meshAttributeArray[index + 1]]);
577
- }
578
- break;
579
- }
580
- case VertexBuffer.MatricesIndicesKind:
581
- case VertexBuffer.MatricesIndicesExtraKind: {
582
- for (var k = 0, length_7 = meshAttributeArray.length / stride; k < length_7; ++k) {
583
- index = k * stride;
584
- var vertexData = Vector4.FromArray(meshAttributeArray, index);
585
- vertexAttributes.push(vertexData.asArray());
586
- }
587
- break;
588
- }
589
- case VertexBuffer.MatricesWeightsKind:
590
- case VertexBuffer.MatricesWeightsExtraKind: {
591
- for (var k = 0, length_8 = meshAttributeArray.length / stride; k < length_8; ++k) {
592
- index = k * stride;
593
- var vertexData = Vector4.FromArray(meshAttributeArray, index);
594
- vertexAttributes.push(vertexData.asArray());
595
- }
596
- break;
597
- }
598
- default: {
599
- Tools.Warn("Unsupported Vertex Buffer Type: " + vertexBufferKind);
600
- vertexAttributes = [];
601
- }
602
- }
603
- var writeBinaryFunc;
604
- switch (attributeComponentKind) {
605
- case 5121 /* UNSIGNED_BYTE */: {
606
- writeBinaryFunc = binaryWriter.setUInt8.bind(binaryWriter);
607
- break;
608
- }
609
- case 5123 /* UNSIGNED_SHORT */: {
610
- writeBinaryFunc = binaryWriter.setUInt16.bind(binaryWriter);
611
- break;
612
- }
613
- case 5125 /* UNSIGNED_INT */: {
614
- writeBinaryFunc = binaryWriter.setUInt32.bind(binaryWriter);
615
- break;
616
- }
617
- case 5126 /* FLOAT */: {
618
- writeBinaryFunc = binaryWriter.setFloat32.bind(binaryWriter);
619
- break;
620
- }
621
- default: {
622
- Tools.Warn("Unsupported Attribute Component kind: " + attributeComponentKind);
623
- return;
624
- }
625
- }
626
- for (var _i = 0, vertexAttributes_1 = vertexAttributes; _i < vertexAttributes_1.length; _i++) {
627
- var vertexAttribute = vertexAttributes_1[_i];
628
- for (var _a = 0, vertexAttribute_1 = vertexAttribute; _a < vertexAttribute_1.length; _a++) {
629
- var component = vertexAttribute_1[_a];
630
- writeBinaryFunc(component);
631
- }
632
- }
633
- };
634
- /**
635
- * Writes mesh attribute data to a data buffer
636
- * Returns the bytelength of the data
637
- * @param vertexBufferKind Indicates what kind of vertex data is being passed in
638
- * @param attributeComponentKind
639
- * @param meshPrimitive
640
- * @param morphTarget
641
- * @param meshAttributeArray Array containing the attribute data
642
- * @param morphTargetAttributeArray
643
- * @param stride Specifies the space between data
644
- * @param binaryWriter The buffer to write the binary data to
645
- * @param convertToRightHandedSystem Converts the values to right-handed
646
- * @param minMax
647
- */
648
- _Exporter.prototype.writeMorphTargetAttributeData = function (vertexBufferKind, attributeComponentKind, meshPrimitive, morphTarget, meshAttributeArray, morphTargetAttributeArray, stride, binaryWriter, convertToRightHandedSystem, minMax) {
649
- var vertexAttributes = [];
650
- var index;
651
- var difference = new Vector3();
652
- var difference4 = new Vector4(0, 0, 0, 0);
653
- switch (vertexBufferKind) {
654
- case VertexBuffer.PositionKind: {
655
- for (var k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
656
- index = meshPrimitive.indexStart + k * stride;
657
- var vertexData = Vector3.FromArray(meshAttributeArray, index);
658
- var morphData = Vector3.FromArray(morphTargetAttributeArray, index);
659
- difference = morphData.subtractToRef(vertexData, difference);
660
- if (convertToRightHandedSystem) {
661
- _GLTFUtilities._GetRightHandedPositionVector3FromRef(difference);
662
- }
663
- if (minMax) {
664
- minMax.min.copyFromFloats(Math.min(difference.x, minMax.min.x), Math.min(difference.y, minMax.min.y), Math.min(difference.z, minMax.min.z));
665
- minMax.max.copyFromFloats(Math.max(difference.x, minMax.max.x), Math.max(difference.y, minMax.max.y), Math.max(difference.z, minMax.max.z));
666
- }
667
- vertexAttributes.push(difference.asArray());
668
- }
669
- break;
670
- }
671
- case VertexBuffer.NormalKind: {
672
- for (var k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
673
- index = meshPrimitive.indexStart + k * stride;
674
- var vertexData = Vector3.FromArray(meshAttributeArray, index);
675
- vertexData.normalize();
676
- var morphData = Vector3.FromArray(morphTargetAttributeArray, index);
677
- morphData.normalize();
678
- difference = morphData.subtractToRef(vertexData, difference);
679
- if (convertToRightHandedSystem) {
680
- _GLTFUtilities._GetRightHandedNormalVector3FromRef(difference);
681
- }
682
- vertexAttributes.push(difference.asArray());
683
- }
684
- break;
685
- }
686
- case VertexBuffer.TangentKind: {
687
- for (var k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
688
- index = meshPrimitive.indexStart + k * (stride + 1);
689
- var vertexData = Vector4.FromArray(meshAttributeArray, index);
690
- _GLTFUtilities._NormalizeTangentFromRef(vertexData);
691
- var morphData = Vector4.FromArray(morphTargetAttributeArray, index);
692
- _GLTFUtilities._NormalizeTangentFromRef(morphData);
693
- difference4 = morphData.subtractToRef(vertexData, difference4);
694
- if (convertToRightHandedSystem) {
695
- _GLTFUtilities._GetRightHandedVector4FromRef(difference4);
696
- }
697
- vertexAttributes.push([difference4.x, difference4.y, difference4.z]);
698
- }
699
- break;
700
- }
701
- default: {
702
- Tools.Warn("Unsupported Vertex Buffer Type: " + vertexBufferKind);
703
- vertexAttributes = [];
704
- }
705
- }
706
- var writeBinaryFunc;
707
- switch (attributeComponentKind) {
708
- case 5121 /* UNSIGNED_BYTE */: {
709
- writeBinaryFunc = binaryWriter.setUInt8.bind(binaryWriter);
710
- break;
711
- }
712
- case 5123 /* UNSIGNED_SHORT */: {
713
- writeBinaryFunc = binaryWriter.setUInt16.bind(binaryWriter);
714
- break;
715
- }
716
- case 5125 /* UNSIGNED_INT */: {
717
- writeBinaryFunc = binaryWriter.setUInt32.bind(binaryWriter);
718
- break;
719
- }
720
- case 5126 /* FLOAT */: {
721
- writeBinaryFunc = binaryWriter.setFloat32.bind(binaryWriter);
722
- break;
723
- }
724
- default: {
725
- Tools.Warn("Unsupported Attribute Component kind: " + attributeComponentKind);
726
- return;
727
- }
728
- }
729
- for (var _i = 0, vertexAttributes_2 = vertexAttributes; _i < vertexAttributes_2.length; _i++) {
730
- var vertexAttribute = vertexAttributes_2[_i];
731
- for (var _a = 0, vertexAttribute_2 = vertexAttribute; _a < vertexAttribute_2.length; _a++) {
732
- var component = vertexAttribute_2[_a];
733
- writeBinaryFunc(component);
734
- }
735
- }
736
- };
737
- /**
738
- * Generates glTF json data
739
- * @param shouldUseGlb Indicates whether the json should be written for a glb file
740
- * @param glTFPrefix Text to use when prefixing a glTF file
741
- * @param prettyPrint Indicates whether the json file should be pretty printed (true) or not (false)
742
- * @returns json data as string
743
- */
744
- _Exporter.prototype._generateJSON = function (shouldUseGlb, glTFPrefix, prettyPrint) {
745
- var _this = this;
746
- var buffer = { byteLength: this._totalByteLength };
747
- var imageName;
748
- var imageData;
749
- var bufferView;
750
- var byteOffset = this._totalByteLength;
751
- if (buffer.byteLength) {
752
- this._glTF.buffers = [buffer];
753
- }
754
- if (this._nodes && this._nodes.length) {
755
- this._glTF.nodes = this._nodes;
756
- }
757
- if (this._meshes && this._meshes.length) {
758
- this._glTF.meshes = this._meshes;
759
- }
760
- if (this._scenes && this._scenes.length) {
761
- this._glTF.scenes = this._scenes;
762
- this._glTF.scene = 0;
763
- }
764
- if (this._cameras && this._cameras.length) {
765
- this._glTF.cameras = this._cameras;
766
- }
767
- if (this._bufferViews && this._bufferViews.length) {
768
- this._glTF.bufferViews = this._bufferViews;
769
- }
770
- if (this._accessors && this._accessors.length) {
771
- this._glTF.accessors = this._accessors;
772
- }
773
- if (this._animations && this._animations.length) {
774
- this._glTF.animations = this._animations;
775
- }
776
- if (this._materials && this._materials.length) {
777
- this._glTF.materials = this._materials;
778
- }
779
- if (this._textures && this._textures.length) {
780
- this._glTF.textures = this._textures;
781
- }
782
- if (this._samplers && this._samplers.length) {
783
- this._glTF.samplers = this._samplers;
784
- }
785
- if (this._skins && this._skins.length) {
786
- this._glTF.skins = this._skins;
787
- }
788
- if (this._images && this._images.length) {
789
- if (!shouldUseGlb) {
790
- this._glTF.images = this._images;
791
- }
792
- else {
793
- this._glTF.images = [];
794
- this._images.forEach(function (image) {
795
- if (image.uri) {
796
- imageData = _this._imageData[image.uri];
797
- _this._orderedImageData.push(imageData);
798
- imageName = image.uri.split(".")[0] + " image";
799
- bufferView = _GLTFUtilities._CreateBufferView(0, byteOffset, imageData.data.length, undefined, imageName);
800
- byteOffset += imageData.data.buffer.byteLength;
801
- _this._bufferViews.push(bufferView);
802
- image.bufferView = _this._bufferViews.length - 1;
803
- image.name = imageName;
804
- image.mimeType = imageData.mimeType;
805
- image.uri = undefined;
806
- if (!_this._glTF.images) {
807
- _this._glTF.images = [];
808
- }
809
- _this._glTF.images.push(image);
810
- }
811
- });
812
- // Replace uri with bufferview and mime type for glb
813
- buffer.byteLength = byteOffset;
814
- }
815
- }
816
- if (!shouldUseGlb) {
817
- buffer.uri = glTFPrefix + ".bin";
818
- }
819
- var jsonText = prettyPrint ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF);
820
- return jsonText;
821
- };
822
- /**
823
- * Generates data for .gltf and .bin files based on the glTF prefix string
824
- * @param glTFPrefix Text to use when prefixing a glTF file
825
- * @param dispose Dispose the exporter
826
- * @returns GLTFData with glTF file data
827
- */
828
- _Exporter.prototype._generateGLTFAsync = function (glTFPrefix, dispose) {
829
- var _this = this;
830
- if (dispose === void 0) { dispose = true; }
831
- return this._generateBinaryAsync().then(function (binaryBuffer) {
832
- _this._extensionsOnExporting();
833
- var jsonText = _this._generateJSON(false, glTFPrefix, true);
834
- var bin = new Blob([binaryBuffer], { type: "application/octet-stream" });
835
- var glTFFileName = glTFPrefix + ".gltf";
836
- var glTFBinFile = glTFPrefix + ".bin";
837
- var container = new GLTFData();
838
- container.glTFFiles[glTFFileName] = jsonText;
839
- container.glTFFiles[glTFBinFile] = bin;
840
- if (_this._imageData) {
841
- for (var image in _this._imageData) {
842
- container.glTFFiles[image] = new Blob([_this._imageData[image].data], { type: _this._imageData[image].mimeType });
843
- }
844
- }
845
- if (dispose) {
846
- _this.dispose();
847
- }
848
- return container;
849
- });
850
- };
851
- /**
852
- * Creates a binary buffer for glTF
853
- * @returns array buffer for binary data
854
- */
855
- _Exporter.prototype._generateBinaryAsync = function () {
856
- var _this = this;
857
- var binaryWriter = new _BinaryWriter(4);
858
- return this._createSceneAsync(this._babylonScene, binaryWriter).then(function () {
859
- if (_this._localEngine) {
860
- _this._localEngine.dispose();
861
- }
862
- return binaryWriter.getArrayBuffer();
863
- });
864
- };
865
- /**
866
- * Pads the number to a multiple of 4
867
- * @param num number to pad
868
- * @returns padded number
869
- */
870
- _Exporter.prototype._getPadding = function (num) {
871
- var remainder = num % 4;
872
- var padding = remainder === 0 ? remainder : 4 - remainder;
873
- return padding;
874
- };
875
- /**
876
- * @param glTFPrefix
877
- * @param dispose
878
- * @hidden
879
- */
880
- _Exporter.prototype._generateGLBAsync = function (glTFPrefix, dispose) {
881
- var _this = this;
882
- if (dispose === void 0) { dispose = true; }
883
- return this._generateBinaryAsync().then(function (binaryBuffer) {
884
- _this._extensionsOnExporting();
885
- var jsonText = _this._generateJSON(true);
886
- var glbFileName = glTFPrefix + ".glb";
887
- var headerLength = 12;
888
- var chunkLengthPrefix = 8;
889
- var jsonLength = jsonText.length;
890
- var encodedJsonText;
891
- var imageByteLength = 0;
892
- // make use of TextEncoder when available
893
- if (typeof TextEncoder !== "undefined") {
894
- var encoder = new TextEncoder();
895
- encodedJsonText = encoder.encode(jsonText);
896
- jsonLength = encodedJsonText.length;
897
- }
898
- for (var i = 0; i < _this._orderedImageData.length; ++i) {
899
- imageByteLength += _this._orderedImageData[i].data.byteLength;
900
- }
901
- var jsonPadding = _this._getPadding(jsonLength);
902
- var binPadding = _this._getPadding(binaryBuffer.byteLength);
903
- var imagePadding = _this._getPadding(imageByteLength);
904
- var byteLength = headerLength + 2 * chunkLengthPrefix + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength + imagePadding;
905
- //header
906
- var headerBuffer = new ArrayBuffer(headerLength);
907
- var headerBufferView = new DataView(headerBuffer);
908
- headerBufferView.setUint32(0, 0x46546c67, true); //glTF
909
- headerBufferView.setUint32(4, 2, true); // version
910
- headerBufferView.setUint32(8, byteLength, true); // total bytes in file
911
- //json chunk
912
- var jsonChunkBuffer = new ArrayBuffer(chunkLengthPrefix + jsonLength + jsonPadding);
913
- var jsonChunkBufferView = new DataView(jsonChunkBuffer);
914
- jsonChunkBufferView.setUint32(0, jsonLength + jsonPadding, true);
915
- jsonChunkBufferView.setUint32(4, 0x4e4f534a, true);
916
- //json chunk bytes
917
- var jsonData = new Uint8Array(jsonChunkBuffer, chunkLengthPrefix);
918
- // if TextEncoder was available, we can simply copy the encoded array
919
- if (encodedJsonText) {
920
- jsonData.set(encodedJsonText);
921
- }
922
- else {
923
- var blankCharCode = "_".charCodeAt(0);
924
- for (var i = 0; i < jsonLength; ++i) {
925
- var charCode = jsonText.charCodeAt(i);
926
- // if the character doesn't fit into a single UTF-16 code unit, just put a blank character
927
- if (charCode != jsonText.codePointAt(i)) {
928
- jsonData[i] = blankCharCode;
929
- }
930
- else {
931
- jsonData[i] = charCode;
932
- }
933
- }
934
- }
935
- //json padding
936
- var jsonPaddingView = new Uint8Array(jsonChunkBuffer, chunkLengthPrefix + jsonLength);
937
- for (var i = 0; i < jsonPadding; ++i) {
938
- jsonPaddingView[i] = 0x20;
939
- }
940
- //binary chunk
941
- var binaryChunkBuffer = new ArrayBuffer(chunkLengthPrefix);
942
- var binaryChunkBufferView = new DataView(binaryChunkBuffer);
943
- binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + imageByteLength + imagePadding, true);
944
- binaryChunkBufferView.setUint32(4, 0x004e4942, true);
945
- // binary padding
946
- var binPaddingBuffer = new ArrayBuffer(binPadding);
947
- var binPaddingView = new Uint8Array(binPaddingBuffer);
948
- for (var i = 0; i < binPadding; ++i) {
949
- binPaddingView[i] = 0;
950
- }
951
- var imagePaddingBuffer = new ArrayBuffer(imagePadding);
952
- var imagePaddingView = new Uint8Array(imagePaddingBuffer);
953
- for (var i = 0; i < imagePadding; ++i) {
954
- imagePaddingView[i] = 0;
955
- }
956
- var glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer];
957
- // binary data
958
- for (var i = 0; i < _this._orderedImageData.length; ++i) {
959
- glbData.push(_this._orderedImageData[i].data.buffer);
960
- }
961
- glbData.push(binPaddingBuffer);
962
- glbData.push(imagePaddingBuffer);
963
- var glbFile = new Blob(glbData, { type: "application/octet-stream" });
964
- var container = new GLTFData();
965
- container.glTFFiles[glbFileName] = glbFile;
966
- if (_this._localEngine != null) {
967
- _this._localEngine.dispose();
968
- }
969
- if (dispose) {
970
- _this.dispose();
971
- }
972
- return container;
973
- });
974
- };
975
- /**
976
- * Sets the TRS for each node
977
- * @param node glTF Node for storing the transformation data
978
- * @param babylonTransformNode Babylon mesh used as the source for the transformation data
979
- * @param convertToRightHandedSystem Converts the values to right-handed
980
- */
981
- _Exporter.prototype._setNodeTransformation = function (node, babylonTransformNode, convertToRightHandedSystem) {
982
- if (!babylonTransformNode.getPivotPoint().equalsToFloats(0, 0, 0)) {
983
- Tools.Warn("Pivot points are not supported in the glTF serializer");
984
- }
985
- if (!babylonTransformNode.position.equalsToFloats(0, 0, 0)) {
986
- node.translation = convertToRightHandedSystem
987
- ? _GLTFUtilities._GetRightHandedPositionVector3(babylonTransformNode.position).asArray()
988
- : babylonTransformNode.position.asArray();
989
- }
990
- if (!babylonTransformNode.scaling.equalsToFloats(1, 1, 1)) {
991
- node.scale = babylonTransformNode.scaling.asArray();
992
- }
993
- var rotationQuaternion = Quaternion.RotationYawPitchRoll(babylonTransformNode.rotation.y, babylonTransformNode.rotation.x, babylonTransformNode.rotation.z);
994
- if (babylonTransformNode.rotationQuaternion) {
995
- rotationQuaternion.multiplyInPlace(babylonTransformNode.rotationQuaternion);
996
- }
997
- if (!Quaternion.IsIdentity(rotationQuaternion)) {
998
- if (convertToRightHandedSystem) {
999
- _GLTFUtilities._GetRightHandedQuaternionFromRef(rotationQuaternion);
1000
- }
1001
- node.rotation = rotationQuaternion.normalize().asArray();
1002
- }
1003
- };
1004
- _Exporter.prototype._setCameraTransformation = function (node, babylonCamera, convertToRightHandedSystem) {
1005
- if (!babylonCamera.position.equalsToFloats(0, 0, 0)) {
1006
- node.translation = convertToRightHandedSystem ? _GLTFUtilities._GetRightHandedPositionVector3(babylonCamera.position).asArray() : babylonCamera.position.asArray();
1007
- }
1008
- var rotationQuaternion = babylonCamera.absoluteRotation;
1009
- if (!Quaternion.IsIdentity(rotationQuaternion)) {
1010
- if (convertToRightHandedSystem) {
1011
- _GLTFUtilities._GetRightHandedQuaternionFromRef(rotationQuaternion);
1012
- }
1013
- node.rotation = rotationQuaternion.normalize().asArray();
1014
- }
1015
- };
1016
- _Exporter.prototype._getVertexBufferFromMesh = function (attributeKind, bufferMesh) {
1017
- if (bufferMesh.isVerticesDataPresent(attributeKind)) {
1018
- var vertexBuffer = bufferMesh.getVertexBuffer(attributeKind);
1019
- if (vertexBuffer) {
1020
- return vertexBuffer;
1021
- }
1022
- }
1023
- return null;
1024
- };
1025
- /**
1026
- * Creates a bufferview based on the vertices type for the Babylon mesh
1027
- * @param kind Indicates the type of vertices data
1028
- * @param attributeComponentKind Indicates the numerical type used to store the data
1029
- * @param babylonTransformNode The Babylon mesh to get the vertices data from
1030
- * @param binaryWriter The buffer to write the bufferview data to
1031
- * @param byteStride
1032
- * @param convertToRightHandedSystem Converts the values to right-handed
1033
- */
1034
- _Exporter.prototype._createBufferViewKind = function (kind, attributeComponentKind, babylonTransformNode, binaryWriter, byteStride, convertToRightHandedSystem) {
1035
- var bufferMesh = babylonTransformNode instanceof Mesh
1036
- ? babylonTransformNode
1037
- : babylonTransformNode instanceof InstancedMesh
1038
- ? babylonTransformNode.sourceMesh
1039
- : null;
1040
- if (bufferMesh) {
1041
- var vertexBuffer = bufferMesh.getVertexBuffer(kind);
1042
- var vertexData = bufferMesh.getVerticesData(kind);
1043
- if (vertexBuffer && vertexData) {
1044
- var typeByteLength = VertexBuffer.GetTypeByteLength(attributeComponentKind);
1045
- var byteLength = vertexData.length * typeByteLength;
1046
- var bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, kind + " - " + bufferMesh.name);
1047
- this._bufferViews.push(bufferView);
1048
- this._writeAttributeData(kind, attributeComponentKind, vertexData, byteStride / typeByteLength, binaryWriter, convertToRightHandedSystem, babylonTransformNode);
1049
- }
1050
- }
1051
- };
1052
- /**
1053
- * Creates a bufferview based on the vertices type for the Babylon mesh
1054
- * @param babylonSubMesh The Babylon submesh that the morph target is applied to
1055
- * @param meshPrimitive
1056
- * @param babylonMorphTarget the morph target to be exported
1057
- * @param binaryWriter The buffer to write the bufferview data to
1058
- * @param convertToRightHandedSystem Converts the values to right-handed
1059
- */
1060
- _Exporter.prototype._setMorphTargetAttributes = function (babylonSubMesh, meshPrimitive, babylonMorphTarget, binaryWriter, convertToRightHandedSystem) {
1061
- if (babylonMorphTarget) {
1062
- if (!meshPrimitive.targets) {
1063
- meshPrimitive.targets = [];
1064
- }
1065
- var target = {};
1066
- if (babylonMorphTarget.hasNormals) {
1067
- var vertexNormals = babylonSubMesh.getMesh().getVerticesData(VertexBuffer.NormalKind);
1068
- var morphNormals = babylonMorphTarget.getNormals();
1069
- var count = babylonSubMesh.verticesCount;
1070
- var byteStride = 12; // 3 x 4 byte floats
1071
- var byteLength = count * byteStride;
1072
- var bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_NORMAL");
1073
- this._bufferViews.push(bufferView);
1074
- var bufferViewIndex = this._bufferViews.length - 1;
1075
- var accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "NORMAL", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
1076
- this._accessors.push(accessor);
1077
- target.NORMAL = this._accessors.length - 1;
1078
- this.writeMorphTargetAttributeData(VertexBuffer.NormalKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexNormals, morphNormals, byteStride / 4, binaryWriter, convertToRightHandedSystem);
1079
- }
1080
- if (babylonMorphTarget.hasPositions) {
1081
- var vertexPositions = babylonSubMesh.getMesh().getVerticesData(VertexBuffer.PositionKind);
1082
- var morphPositions = babylonMorphTarget.getPositions();
1083
- var count = babylonSubMesh.verticesCount;
1084
- var byteStride = 12; // 3 x 4 byte floats
1085
- var byteLength = count * byteStride;
1086
- var bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_POSITION");
1087
- this._bufferViews.push(bufferView);
1088
- var bufferViewIndex = this._bufferViews.length - 1;
1089
- var minMax = { min: new Vector3(Infinity, Infinity, Infinity), max: new Vector3(-Infinity, -Infinity, -Infinity) };
1090
- var accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "POSITION", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
1091
- this._accessors.push(accessor);
1092
- target.POSITION = this._accessors.length - 1;
1093
- this.writeMorphTargetAttributeData(VertexBuffer.PositionKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexPositions, morphPositions, byteStride / 4, binaryWriter, convertToRightHandedSystem, minMax);
1094
- accessor.min = minMax.min.asArray();
1095
- accessor.max = minMax.max.asArray();
1096
- }
1097
- if (babylonMorphTarget.hasTangents) {
1098
- var vertexTangents = babylonSubMesh.getMesh().getVerticesData(VertexBuffer.TangentKind);
1099
- var morphTangents = babylonMorphTarget.getTangents();
1100
- var count = babylonSubMesh.verticesCount;
1101
- var byteStride = 12; // 3 x 4 byte floats
1102
- var byteLength = count * byteStride;
1103
- var bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_NORMAL");
1104
- this._bufferViews.push(bufferView);
1105
- var bufferViewIndex = this._bufferViews.length - 1;
1106
- var accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "TANGENT", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
1107
- this._accessors.push(accessor);
1108
- target.TANGENT = this._accessors.length - 1;
1109
- this.writeMorphTargetAttributeData(VertexBuffer.TangentKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexTangents, morphTangents, byteStride / 4, binaryWriter, convertToRightHandedSystem);
1110
- }
1111
- meshPrimitive.targets.push(target);
1112
- }
1113
- };
1114
- /**
1115
- * The primitive mode of the Babylon mesh
1116
- * @param babylonMesh The BabylonJS mesh
1117
- */
1118
- _Exporter.prototype._getMeshPrimitiveMode = function (babylonMesh) {
1119
- if (babylonMesh instanceof LinesMesh) {
1120
- return Material.LineListDrawMode;
1121
- }
1122
- return babylonMesh.material ? babylonMesh.material.fillMode : Material.TriangleFillMode;
1123
- };
1124
- /**
1125
- * Sets the primitive mode of the glTF mesh primitive
1126
- * @param meshPrimitive glTF mesh primitive
1127
- * @param primitiveMode The primitive mode
1128
- */
1129
- _Exporter.prototype._setPrimitiveMode = function (meshPrimitive, primitiveMode) {
1130
- switch (primitiveMode) {
1131
- case Material.TriangleFillMode: {
1132
- // glTF defaults to using Triangle Mode
1133
- break;
1134
- }
1135
- case Material.TriangleStripDrawMode: {
1136
- meshPrimitive.mode = 5 /* TRIANGLE_STRIP */;
1137
- break;
1138
- }
1139
- case Material.TriangleFanDrawMode: {
1140
- meshPrimitive.mode = 6 /* TRIANGLE_FAN */;
1141
- break;
1142
- }
1143
- case Material.PointListDrawMode: {
1144
- meshPrimitive.mode = 0 /* POINTS */;
1145
- break;
1146
- }
1147
- case Material.PointFillMode: {
1148
- meshPrimitive.mode = 0 /* POINTS */;
1149
- break;
1150
- }
1151
- case Material.LineLoopDrawMode: {
1152
- meshPrimitive.mode = 2 /* LINE_LOOP */;
1153
- break;
1154
- }
1155
- case Material.LineListDrawMode: {
1156
- meshPrimitive.mode = 1 /* LINES */;
1157
- break;
1158
- }
1159
- case Material.LineStripDrawMode: {
1160
- meshPrimitive.mode = 3 /* LINE_STRIP */;
1161
- break;
1162
- }
1163
- }
1164
- };
1165
- /**
1166
- * Sets the vertex attribute accessor based of the glTF mesh primitive
1167
- * @param meshPrimitive glTF mesh primitive
1168
- * @param attributeKind vertex attribute
1169
- * @returns boolean specifying if uv coordinates are present
1170
- */
1171
- _Exporter.prototype._setAttributeKind = function (meshPrimitive, attributeKind) {
1172
- switch (attributeKind) {
1173
- case VertexBuffer.PositionKind: {
1174
- meshPrimitive.attributes.POSITION = this._accessors.length - 1;
1175
- break;
1176
- }
1177
- case VertexBuffer.NormalKind: {
1178
- meshPrimitive.attributes.NORMAL = this._accessors.length - 1;
1179
- break;
1180
- }
1181
- case VertexBuffer.ColorKind: {
1182
- meshPrimitive.attributes.COLOR_0 = this._accessors.length - 1;
1183
- break;
1184
- }
1185
- case VertexBuffer.TangentKind: {
1186
- meshPrimitive.attributes.TANGENT = this._accessors.length - 1;
1187
- break;
1188
- }
1189
- case VertexBuffer.UVKind: {
1190
- meshPrimitive.attributes.TEXCOORD_0 = this._accessors.length - 1;
1191
- break;
1192
- }
1193
- case VertexBuffer.UV2Kind: {
1194
- meshPrimitive.attributes.TEXCOORD_1 = this._accessors.length - 1;
1195
- break;
1196
- }
1197
- case VertexBuffer.MatricesIndicesKind: {
1198
- meshPrimitive.attributes.JOINTS_0 = this._accessors.length - 1;
1199
- break;
1200
- }
1201
- case VertexBuffer.MatricesIndicesExtraKind: {
1202
- meshPrimitive.attributes.JOINTS_1 = this._accessors.length - 1;
1203
- break;
1204
- }
1205
- case VertexBuffer.MatricesWeightsKind: {
1206
- meshPrimitive.attributes.WEIGHTS_0 = this._accessors.length - 1;
1207
- break;
1208
- }
1209
- case VertexBuffer.MatricesWeightsExtraKind: {
1210
- meshPrimitive.attributes.WEIGHTS_1 = this._accessors.length - 1;
1211
- break;
1212
- }
1213
- default: {
1214
- Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
1215
- }
1216
- }
1217
- };
1218
- /**
1219
- * Sets data for the primitive attributes of each submesh
1220
- * @param mesh glTF Mesh object to store the primitive attribute information
1221
- * @param babylonTransformNode Babylon mesh to get the primitive attribute data from
1222
- * @param binaryWriter Buffer to write the attribute data to
1223
- * @param convertToRightHandedSystem Converts the values to right-handed
1224
- */
1225
- _Exporter.prototype._setPrimitiveAttributesAsync = function (mesh, babylonTransformNode, binaryWriter, convertToRightHandedSystem) {
1226
- var _a;
1227
- var promises = [];
1228
- var bufferMesh = null;
1229
- var bufferView;
1230
- var minMax;
1231
- if (babylonTransformNode instanceof Mesh) {
1232
- bufferMesh = babylonTransformNode;
1233
- }
1234
- else if (babylonTransformNode instanceof InstancedMesh) {
1235
- bufferMesh = babylonTransformNode.sourceMesh;
1236
- }
1237
- var attributeData = [
1238
- { kind: VertexBuffer.PositionKind, accessorType: "VEC3" /* VEC3 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 12 },
1239
- { kind: VertexBuffer.NormalKind, accessorType: "VEC3" /* VEC3 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 12 },
1240
- { kind: VertexBuffer.ColorKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 16 },
1241
- { kind: VertexBuffer.TangentKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 16 },
1242
- { kind: VertexBuffer.UVKind, accessorType: "VEC2" /* VEC2 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 8 },
1243
- { kind: VertexBuffer.UV2Kind, accessorType: "VEC2" /* VEC2 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 8 },
1244
- { kind: VertexBuffer.MatricesIndicesKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5123 /* UNSIGNED_SHORT */, byteStride: 8 },
1245
- { kind: VertexBuffer.MatricesIndicesExtraKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5123 /* UNSIGNED_SHORT */, byteStride: 8 },
1246
- { kind: VertexBuffer.MatricesWeightsKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 16 },
1247
- { kind: VertexBuffer.MatricesWeightsExtraKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 16 },
1248
- ];
1249
- if (bufferMesh) {
1250
- var indexBufferViewIndex = null;
1251
- var primitiveMode = this._getMeshPrimitiveMode(bufferMesh);
1252
- var vertexAttributeBufferViews = {};
1253
- var morphTargetManager = bufferMesh.morphTargetManager;
1254
- // For each BabylonMesh, create bufferviews for each 'kind'
1255
- for (var _i = 0, attributeData_1 = attributeData; _i < attributeData_1.length; _i++) {
1256
- var attribute = attributeData_1[_i];
1257
- var attributeKind = attribute.kind;
1258
- var attributeComponentKind = attribute.accessorComponentType;
1259
- if (bufferMesh.isVerticesDataPresent(attributeKind)) {
1260
- var vertexBuffer = this._getVertexBufferFromMesh(attributeKind, bufferMesh);
1261
- attribute.byteStride = vertexBuffer
1262
- ? vertexBuffer.getSize() * VertexBuffer.GetTypeByteLength(attribute.accessorComponentType)
1263
- : VertexBuffer.DeduceStride(attributeKind) * 4;
1264
- if (attribute.byteStride === 12) {
1265
- attribute.accessorType = "VEC3" /* VEC3 */;
1266
- }
1267
- this._createBufferViewKind(attributeKind, attributeComponentKind, babylonTransformNode, binaryWriter, attribute.byteStride, convertToRightHandedSystem);
1268
- attribute.bufferViewIndex = this._bufferViews.length - 1;
1269
- vertexAttributeBufferViews[attributeKind] = attribute.bufferViewIndex;
1270
- }
1271
- }
1272
- if (bufferMesh.getTotalIndices()) {
1273
- var indices = bufferMesh.getIndices();
1274
- if (indices) {
1275
- var byteLength = indices.length * 4;
1276
- bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, undefined, "Indices - " + bufferMesh.name);
1277
- this._bufferViews.push(bufferView);
1278
- indexBufferViewIndex = this._bufferViews.length - 1;
1279
- for (var k = 0, length_9 = indices.length; k < length_9; ++k) {
1280
- binaryWriter.setUInt32(indices[k]);
1281
- }
1282
- }
1283
- }
1284
- if (bufferMesh.subMeshes) {
1285
- // go through all mesh primitives (submeshes)
1286
- for (var _b = 0, _c = bufferMesh.subMeshes; _b < _c.length; _b++) {
1287
- var submesh = _c[_b];
1288
- var babylonMaterial = submesh.getMaterial() || bufferMesh.getScene().defaultMaterial;
1289
- var materialIndex = null;
1290
- if (babylonMaterial) {
1291
- if (bufferMesh instanceof LinesMesh) {
1292
- // get the color from the lines mesh and set it in the material
1293
- var material = {
1294
- name: bufferMesh.name + " material",
1295
- };
1296
- if (!bufferMesh.color.equals(Color3.White()) || bufferMesh.alpha < 1) {
1297
- material.pbrMetallicRoughness = {
1298
- baseColorFactor: bufferMesh.color.asArray().concat([bufferMesh.alpha]),
1299
- };
1300
- }
1301
- this._materials.push(material);
1302
- materialIndex = this._materials.length - 1;
1303
- }
1304
- else if (babylonMaterial instanceof MultiMaterial) {
1305
- var subMaterial = babylonMaterial.subMaterials[submesh.materialIndex];
1306
- if (subMaterial) {
1307
- babylonMaterial = subMaterial;
1308
- materialIndex = this._materialMap[babylonMaterial.uniqueId];
1309
- }
1310
- }
1311
- else {
1312
- materialIndex = this._materialMap[babylonMaterial.uniqueId];
1313
- }
1314
- }
1315
- var glTFMaterial = materialIndex != null ? this._materials[materialIndex] : null;
1316
- var meshPrimitive = { attributes: {} };
1317
- this._setPrimitiveMode(meshPrimitive, primitiveMode);
1318
- for (var _d = 0, attributeData_2 = attributeData; _d < attributeData_2.length; _d++) {
1319
- var attribute = attributeData_2[_d];
1320
- var attributeKind = attribute.kind;
1321
- if ((attributeKind === VertexBuffer.UVKind || attributeKind === VertexBuffer.UV2Kind) && !this._options.exportUnusedUVs) {
1322
- if (!glTFMaterial || !this._glTFMaterialExporter._hasTexturesPresent(glTFMaterial)) {
1323
- continue;
1324
- }
1325
- }
1326
- var vertexData = bufferMesh.getVerticesData(attributeKind);
1327
- if (vertexData) {
1328
- var vertexBuffer = this._getVertexBufferFromMesh(attributeKind, bufferMesh);
1329
- if (vertexBuffer) {
1330
- var stride = vertexBuffer.getSize();
1331
- var bufferViewIndex = attribute.bufferViewIndex;
1332
- if (bufferViewIndex != undefined) {
1333
- // check to see if bufferviewindex has a numeric value assigned.
1334
- minMax = { min: null, max: null };
1335
- if (attributeKind == VertexBuffer.PositionKind) {
1336
- minMax = _GLTFUtilities._CalculateMinMaxPositions(vertexData, 0, vertexData.length / stride, convertToRightHandedSystem);
1337
- }
1338
- var accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, attributeKind + " - " + babylonTransformNode.name, attribute.accessorType, attribute.accessorComponentType, vertexData.length / stride, 0, minMax.min, minMax.max);
1339
- this._accessors.push(accessor);
1340
- this._setAttributeKind(meshPrimitive, attributeKind);
1341
- }
1342
- }
1343
- }
1344
- }
1345
- if (indexBufferViewIndex) {
1346
- // Create accessor
1347
- var accessor = _GLTFUtilities._CreateAccessor(indexBufferViewIndex, "indices - " + babylonTransformNode.name, "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4, null, null);
1348
- this._accessors.push(accessor);
1349
- meshPrimitive.indices = this._accessors.length - 1;
1350
- }
1351
- if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
1352
- var sideOrientation = bufferMesh.overrideMaterialSideOrientation !== null ? bufferMesh.overrideMaterialSideOrientation : babylonMaterial.sideOrientation;
1353
- if ((sideOrientation == Material.ClockWiseSideOrientation && this._babylonScene.useRightHandedSystem) ||
1354
- (sideOrientation == Material.ClockWiseSideOrientation &&
1355
- convertToRightHandedSystem &&
1356
- bufferMesh.overrideMaterialSideOrientation !== ((_a = bufferMesh.material) === null || _a === void 0 ? void 0 : _a.sideOrientation))) {
1357
- var byteOffset = indexBufferViewIndex != null ? this._bufferViews[indexBufferViewIndex].byteOffset : null;
1358
- if (byteOffset == null) {
1359
- byteOffset = 0;
1360
- }
1361
- var babylonIndices = null;
1362
- if (indexBufferViewIndex != null) {
1363
- babylonIndices = bufferMesh.getIndices();
1364
- }
1365
- if (babylonIndices) {
1366
- this._reorderIndicesBasedOnPrimitiveMode(submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter);
1367
- }
1368
- else {
1369
- for (var _e = 0, attributeData_3 = attributeData; _e < attributeData_3.length; _e++) {
1370
- var attribute = attributeData_3[_e];
1371
- var vertexData = bufferMesh.getVerticesData(attribute.kind);
1372
- if (vertexData) {
1373
- var byteOffset_1 = this._bufferViews[vertexAttributeBufferViews[attribute.kind]].byteOffset;
1374
- if (!byteOffset_1) {
1375
- byteOffset_1 = 0;
1376
- }
1377
- this._reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData, byteOffset_1, binaryWriter, convertToRightHandedSystem);
1378
- }
1379
- }
1380
- }
1381
- }
1382
- meshPrimitive.material = materialIndex;
1383
- }
1384
- if (morphTargetManager) {
1385
- var target = void 0;
1386
- for (var i = 0; i < morphTargetManager.numTargets; ++i) {
1387
- target = morphTargetManager.getTarget(i);
1388
- this._setMorphTargetAttributes(submesh, meshPrimitive, target, binaryWriter, convertToRightHandedSystem);
1389
- }
1390
- }
1391
- mesh.primitives.push(meshPrimitive);
1392
- this._extensionsPostExportMeshPrimitiveAsync("postExport", meshPrimitive, submesh, binaryWriter);
1393
- promises.push();
1394
- }
1395
- }
1396
- }
1397
- return Promise.all(promises).then(function () {
1398
- /* do nothing */
1399
- });
1400
- };
1401
- /**
1402
- * Check if the node is used to convert its descendants from a right handed coordinate system to the Babylon scene's coordinate system.
1403
- * @param node The node to check
1404
- * @returns True if the node is used to convert its descendants from right-handed to left-handed. False otherwise
1405
- */
1406
- _Exporter.prototype._isBabylonCoordinateSystemConvertingNode = function (node) {
1407
- if (node instanceof TransformNode) {
1408
- if (node.name !== "__root__") {
1409
- return false;
1410
- }
1411
- // Transform
1412
- var matrix = node.getWorldMatrix();
1413
- if (matrix.determinant() === 1) {
1414
- return false;
1415
- }
1416
- // Geometry
1417
- if ((node instanceof Mesh && node.geometry !== null) || (node instanceof InstancedMesh && node.sourceMesh.geometry !== null)) {
1418
- return false;
1419
- }
1420
- if (this._includeCoordinateSystemConversionNodes) {
1421
- return false;
1422
- }
1423
- return true;
1424
- }
1425
- return false;
1426
- };
1427
- /**
1428
- * Creates a glTF scene based on the array of meshes
1429
- * Returns the the total byte offset
1430
- * @param babylonScene Babylon scene to get the mesh data from
1431
- * @param binaryWriter Buffer to write binary data to
1432
- */
1433
- _Exporter.prototype._createSceneAsync = function (babylonScene, binaryWriter) {
1434
- var _this = this;
1435
- var scene = { nodes: [] };
1436
- var glTFNodeIndex;
1437
- var glTFNode;
1438
- var directDescendents;
1439
- var nodes = __spreadArray(__spreadArray(__spreadArray(__spreadArray([], babylonScene.transformNodes, true), babylonScene.meshes, true), babylonScene.lights, true), babylonScene.cameras, true);
1440
- var rootNodesToLeftHanded = [];
1441
- this._convertToRightHandedSystem = !babylonScene.useRightHandedSystem;
1442
- this._convertToRightHandedSystemMap = {};
1443
- // Set default values for all nodes
1444
- babylonScene.rootNodes.forEach(function (rootNode) {
1445
- _this._convertToRightHandedSystemMap[rootNode.uniqueId] = _this._convertToRightHandedSystem;
1446
- rootNode.getDescendants(false).forEach(function (descendant) {
1447
- _this._convertToRightHandedSystemMap[descendant.uniqueId] = _this._convertToRightHandedSystem;
1448
- });
1449
- });
1450
- // Check if root nodes converting to left-handed are present
1451
- babylonScene.rootNodes.forEach(function (rootNode) {
1452
- if (_this._isBabylonCoordinateSystemConvertingNode(rootNode)) {
1453
- rootNodesToLeftHanded.push(rootNode);
1454
- // Exclude the node from list of nodes to export
1455
- var indexRootNode = nodes.indexOf(rootNode);
1456
- if (indexRootNode !== -1) {
1457
- // should always be true
1458
- nodes.splice(indexRootNode, 1);
1459
- }
1460
- // Cancel conversion to right handed system
1461
- rootNode.getDescendants(false).forEach(function (descendant) {
1462
- _this._convertToRightHandedSystemMap[descendant.uniqueId] = false;
1463
- });
1464
- }
1465
- });
1466
- // Export babylon cameras to glTFCamera
1467
- var cameraHash = new Map();
1468
- babylonScene.cameras.forEach(function (camera) {
1469
- var glTFCamera = {
1470
- type: camera.mode === Camera.PERSPECTIVE_CAMERA ? "perspective" /* PERSPECTIVE */ : "orthographic" /* ORTHOGRAPHIC */,
1471
- };
1472
- if (camera.name) {
1473
- glTFCamera.name = camera.name;
1474
- }
1475
- if (glTFCamera.type === "perspective" /* PERSPECTIVE */) {
1476
- glTFCamera.perspective = {
1477
- aspectRatio: camera.getEngine().getAspectRatio(camera),
1478
- yfov: camera._cache.fovMode === Camera.FOVMODE_VERTICAL_FIXED ? camera.fov : camera.fov * camera._cache.aspectRatio,
1479
- znear: camera.minZ,
1480
- zfar: camera.maxZ,
1481
- };
1482
- }
1483
- else if (glTFCamera.type === "orthographic" /* ORTHOGRAPHIC */) {
1484
- var halfWidth = camera.orthoLeft && camera.orthoRight ? 0.5 * (camera.orthoRight - camera.orthoLeft) : camera.getEngine().getRenderWidth() * 0.5;
1485
- var halfHeight = camera.orthoBottom && camera.orthoTop ? 0.5 * (camera.orthoTop - camera.orthoBottom) : camera.getEngine().getRenderHeight() * 0.5;
1486
- glTFCamera.orthographic = {
1487
- xmag: halfWidth,
1488
- ymag: halfHeight,
1489
- znear: camera.minZ,
1490
- zfar: camera.maxZ,
1491
- };
1492
- }
1493
- cameraHash.set(camera, _this._cameras.length);
1494
- _this._cameras.push(glTFCamera);
1495
- });
1496
- var _a = this._getExportNodes(nodes), exportNodes = _a[0], exportMaterials = _a[1];
1497
- return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(exportMaterials, "image/png" /* PNG */, true).then(function () {
1498
- return _this._createNodeMapAndAnimationsAsync(babylonScene, exportNodes, binaryWriter).then(function (nodeMap) {
1499
- return _this._createSkinsAsync(babylonScene, nodeMap, binaryWriter).then(function (skinMap) {
1500
- _this._nodeMap = nodeMap;
1501
- _this._totalByteLength = binaryWriter.getByteOffset();
1502
- if (_this._totalByteLength == undefined) {
1503
- throw new Error("undefined byte length!");
1504
- }
1505
- // Build Hierarchy with the node map.
1506
- for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
1507
- var babylonNode = nodes_1[_i];
1508
- glTFNodeIndex = _this._nodeMap[babylonNode.uniqueId];
1509
- if (glTFNodeIndex !== undefined) {
1510
- glTFNode = _this._nodes[glTFNodeIndex];
1511
- if (babylonNode.metadata) {
1512
- if (_this._options.metadataSelector) {
1513
- glTFNode.extras = _this._options.metadataSelector(babylonNode.metadata);
1514
- }
1515
- else if (babylonNode.metadata.gltf) {
1516
- glTFNode.extras = babylonNode.metadata.gltf.extras;
1517
- }
1518
- }
1519
- if (babylonNode instanceof Camera) {
1520
- glTFNode.camera = cameraHash.get(babylonNode);
1521
- }
1522
- if (!babylonNode.parent || rootNodesToLeftHanded.indexOf(babylonNode.parent) !== -1) {
1523
- if (_this._options.shouldExportNode && !_this._options.shouldExportNode(babylonNode)) {
1524
- Tools.Log("Omitting " + babylonNode.name + " from scene.");
1525
- }
1526
- else {
1527
- var convertToRightHandedSystem = _this._convertToRightHandedSystemMap[babylonNode.uniqueId];
1528
- if (convertToRightHandedSystem) {
1529
- if (glTFNode.translation) {
1530
- glTFNode.translation[2] *= -1;
1531
- glTFNode.translation[0] *= -1;
1532
- }
1533
- glTFNode.rotation = glTFNode.rotation
1534
- ? Quaternion.FromArray([0, 1, 0, 0]).multiply(Quaternion.FromArray(glTFNode.rotation)).asArray()
1535
- : Quaternion.FromArray([0, 1, 0, 0]).asArray();
1536
- }
1537
- scene.nodes.push(glTFNodeIndex);
1538
- }
1539
- }
1540
- if (babylonNode instanceof Mesh) {
1541
- var babylonMesh = babylonNode;
1542
- if (babylonMesh.skeleton) {
1543
- glTFNode.skin = skinMap[babylonMesh.skeleton.uniqueId];
1544
- }
1545
- }
1546
- directDescendents = babylonNode.getDescendants(true);
1547
- if (!glTFNode.children && directDescendents && directDescendents.length) {
1548
- var children = [];
1549
- for (var _a = 0, directDescendents_1 = directDescendents; _a < directDescendents_1.length; _a++) {
1550
- var descendent = directDescendents_1[_a];
1551
- if (_this._nodeMap[descendent.uniqueId] != null) {
1552
- children.push(_this._nodeMap[descendent.uniqueId]);
1553
- }
1554
- }
1555
- if (children.length) {
1556
- glTFNode.children = children;
1557
- }
1558
- }
1559
- }
1560
- }
1561
- if (scene.nodes.length) {
1562
- _this._scenes.push(scene);
1563
- }
1564
- });
1565
- });
1566
- });
1567
- };
1568
- /**
1569
- * Getting the nodes and materials that would be exported.
1570
- * @param nodes Babylon transform nodes
1571
- * @returns Array of nodes which would be exported.
1572
- * @returns Set of materials which would be exported.
1573
- */
1574
- _Exporter.prototype._getExportNodes = function (nodes) {
1575
- var exportNodes = [];
1576
- var exportMaterials = new Set();
1577
- for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
1578
- var babylonNode = nodes_2[_i];
1579
- if (!this._options.shouldExportNode || this._options.shouldExportNode(babylonNode)) {
1580
- exportNodes.push(babylonNode);
1581
- if (babylonNode instanceof AbstractMesh) {
1582
- var material = babylonNode.material || babylonNode.getScene().defaultMaterial;
1583
- if (material instanceof MultiMaterial) {
1584
- for (var _a = 0, _b = material.subMaterials; _a < _b.length; _a++) {
1585
- var subMaterial = _b[_a];
1586
- if (subMaterial) {
1587
- exportMaterials.add(subMaterial);
1588
- }
1589
- }
1590
- }
1591
- else {
1592
- exportMaterials.add(material);
1593
- }
1594
- }
1595
- }
1596
- else {
1597
- "Excluding node ".concat(babylonNode.name);
1598
- }
1599
- }
1600
- return [exportNodes, exportMaterials];
1601
- };
1602
- /**
1603
- * Creates a mapping of Node unique id to node index and handles animations
1604
- * @param babylonScene Babylon Scene
1605
- * @param nodes Babylon transform nodes
1606
- * @param binaryWriter Buffer to write binary data to
1607
- * @returns Node mapping of unique id to index
1608
- */
1609
- _Exporter.prototype._createNodeMapAndAnimationsAsync = function (babylonScene, nodes, binaryWriter) {
1610
- var _this = this;
1611
- var promiseChain = Promise.resolve();
1612
- var nodeMap = {};
1613
- var nodeIndex;
1614
- var runtimeGLTFAnimation = {
1615
- name: "runtime animations",
1616
- channels: [],
1617
- samplers: [],
1618
- };
1619
- var idleGLTFAnimations = [];
1620
- var _loop_1 = function (babylonNode) {
1621
- promiseChain = promiseChain.then(function () {
1622
- var convertToRightHandedSystem = _this._convertToRightHandedSystemMap[babylonNode.uniqueId];
1623
- return _this._createNodeAsync(babylonNode, binaryWriter, convertToRightHandedSystem).then(function (node) {
1624
- var promise = _this._extensionsPostExportNodeAsync("createNodeAsync", node, babylonNode, nodeMap);
1625
- if (promise == null) {
1626
- Tools.Warn("Not exporting node ".concat(babylonNode.name));
1627
- return Promise.resolve();
1628
- }
1629
- else {
1630
- return promise.then(function (node) {
1631
- if (!node) {
1632
- return;
1633
- }
1634
- _this._nodes.push(node);
1635
- nodeIndex = _this._nodes.length - 1;
1636
- nodeMap[babylonNode.uniqueId] = nodeIndex;
1637
- if (!babylonScene.animationGroups.length) {
1638
- _GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, convertToRightHandedSystem, _this._animationSampleRate);
1639
- if (babylonNode.animations.length) {
1640
- _GLTFAnimation._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, convertToRightHandedSystem, _this._animationSampleRate);
1641
- }
1642
- }
1643
- });
1644
- }
1645
- });
1646
- });
1647
- };
1648
- for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) {
1649
- var babylonNode = nodes_3[_i];
1650
- _loop_1(babylonNode);
1651
- }
1652
- return promiseChain.then(function () {
1653
- if (runtimeGLTFAnimation.channels.length && runtimeGLTFAnimation.samplers.length) {
1654
- _this._animations.push(runtimeGLTFAnimation);
1655
- }
1656
- idleGLTFAnimations.forEach(function (idleGLTFAnimation) {
1657
- if (idleGLTFAnimation.channels.length && idleGLTFAnimation.samplers.length) {
1658
- _this._animations.push(idleGLTFAnimation);
1659
- }
1660
- });
1661
- if (babylonScene.animationGroups.length) {
1662
- _GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(babylonScene, _this._animations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._convertToRightHandedSystemMap, _this._animationSampleRate);
1663
- }
1664
- return nodeMap;
1665
- });
1666
- };
1667
- /**
1668
- * Creates a glTF node from a Babylon mesh
1669
- * @param babylonNode Source Babylon mesh
1670
- * @param binaryWriter Buffer for storing geometry data
1671
- * @param convertToRightHandedSystem Converts the values to right-handed
1672
- * @returns glTF node
1673
- */
1674
- _Exporter.prototype._createNodeAsync = function (babylonNode, binaryWriter, convertToRightHandedSystem) {
1675
- var _this = this;
1676
- return Promise.resolve().then(function () {
1677
- // create node to hold translation/rotation/scale and the mesh
1678
- var node = {};
1679
- // create mesh
1680
- var mesh = { primitives: [] };
1681
- if (babylonNode.name) {
1682
- node.name = babylonNode.name;
1683
- }
1684
- if (babylonNode instanceof TransformNode) {
1685
- // Set transformation
1686
- _this._setNodeTransformation(node, babylonNode, convertToRightHandedSystem);
1687
- if (babylonNode instanceof Mesh) {
1688
- var morphTargetManager = babylonNode.morphTargetManager;
1689
- if (morphTargetManager && morphTargetManager.numTargets > 0) {
1690
- mesh.weights = [];
1691
- for (var i = 0; i < morphTargetManager.numTargets; ++i) {
1692
- mesh.weights.push(morphTargetManager.getTarget(i).influence);
1693
- }
1694
- }
1695
- }
1696
- return _this._setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter, convertToRightHandedSystem).then(function () {
1697
- if (mesh.primitives.length) {
1698
- _this._meshes.push(mesh);
1699
- node.mesh = _this._meshes.length - 1;
1700
- }
1701
- return node;
1702
- });
1703
- }
1704
- else if (babylonNode instanceof Camera) {
1705
- _this._setCameraTransformation(node, babylonNode, convertToRightHandedSystem);
1706
- return node;
1707
- }
1708
- else {
1709
- return node;
1710
- }
1711
- });
1712
- };
1713
- /**
1714
- * Creates a glTF skin from a Babylon skeleton
1715
- * @param babylonScene Babylon Scene
1716
- * @param nodeMap Babylon transform nodes
1717
- * @param binaryWriter Buffer to write binary data to
1718
- * @returns Node mapping of unique id to index
1719
- */
1720
- _Exporter.prototype._createSkinsAsync = function (babylonScene, nodeMap, binaryWriter) {
1721
- var _a;
1722
- var promiseChain = Promise.resolve();
1723
- var skinMap = {};
1724
- for (var _i = 0, _b = babylonScene.skeletons; _i < _b.length; _i++) {
1725
- var skeleton = _b[_i];
1726
- // create skin
1727
- var skin = { joints: [] };
1728
- var inverseBindMatrices = [];
1729
- var boneIndexMap = {};
1730
- var maxBoneIndex = -1;
1731
- for (var i = 0; i < skeleton.bones.length; ++i) {
1732
- var bone = skeleton.bones[i];
1733
- var boneIndex = (_a = bone.getIndex()) !== null && _a !== void 0 ? _a : i;
1734
- if (boneIndex !== -1) {
1735
- boneIndexMap[boneIndex] = bone;
1736
- if (boneIndex > maxBoneIndex) {
1737
- maxBoneIndex = boneIndex;
1738
- }
1739
- }
1740
- }
1741
- for (var boneIndex = 0; boneIndex <= maxBoneIndex; ++boneIndex) {
1742
- var bone = boneIndexMap[boneIndex];
1743
- inverseBindMatrices.push(bone.getInvertedAbsoluteTransform());
1744
- var transformNode = bone.getTransformNode();
1745
- if (transformNode) {
1746
- skin.joints.push(nodeMap[transformNode.uniqueId]);
1747
- }
1748
- else {
1749
- Tools.Warn("Exporting a bone without a linked transform node is currently unsupported");
1750
- }
1751
- }
1752
- // create buffer view for inverse bind matrices
1753
- var byteStride = 64; // 4 x 4 matrix of 32 bit float
1754
- var byteLength = inverseBindMatrices.length * byteStride;
1755
- var bufferViewOffset = binaryWriter.getByteOffset();
1756
- var bufferView = _GLTFUtilities._CreateBufferView(0, bufferViewOffset, byteLength, undefined, "InverseBindMatrices" + " - " + skeleton.name);
1757
- this._bufferViews.push(bufferView);
1758
- var bufferViewIndex = this._bufferViews.length - 1;
1759
- var bindMatrixAccessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, "InverseBindMatrices" + " - " + skeleton.name, "MAT4" /* MAT4 */, 5126 /* FLOAT */, inverseBindMatrices.length, null, null, null);
1760
- var inverseBindAccessorIndex = this._accessors.push(bindMatrixAccessor) - 1;
1761
- skin.inverseBindMatrices = inverseBindAccessorIndex;
1762
- this._skins.push(skin);
1763
- skinMap[skeleton.uniqueId] = this._skins.length - 1;
1764
- inverseBindMatrices.forEach(function (mat) {
1765
- mat.m.forEach(function (cell) {
1766
- binaryWriter.setFloat32(cell);
1767
- });
1768
- });
1769
- }
1770
- return promiseChain.then(function () {
1771
- return skinMap;
1772
- });
1773
- };
1774
- _Exporter._ExtensionNames = new Array();
1775
- _Exporter._ExtensionFactories = {};
1776
- return _Exporter;
1777
- }());
1778
- export { _Exporter };
1779
- /**
1780
- * @hidden
1781
- *
1782
- * Stores glTF binary data. If the array buffer byte length is exceeded, it doubles in size dynamically
1783
- */
1784
- var _BinaryWriter = /** @class */ (function () {
1785
- /**
1786
- * Initialize binary writer with an initial byte length
1787
- * @param byteLength Initial byte length of the array buffer
1788
- */
1789
- function _BinaryWriter(byteLength) {
1790
- this._arrayBuffer = new ArrayBuffer(byteLength);
1791
- this._dataView = new DataView(this._arrayBuffer);
1792
- this._byteOffset = 0;
1793
- }
1794
- /**
1795
- * Resize the array buffer to the specified byte length
1796
- * @param byteLength
1797
- */
1798
- _BinaryWriter.prototype._resizeBuffer = function (byteLength) {
1799
- var newBuffer = new ArrayBuffer(byteLength);
1800
- var oldUint8Array = new Uint8Array(this._arrayBuffer);
1801
- var newUint8Array = new Uint8Array(newBuffer);
1802
- for (var i = 0, length_10 = newUint8Array.byteLength; i < length_10; ++i) {
1803
- newUint8Array[i] = oldUint8Array[i];
1804
- }
1805
- this._arrayBuffer = newBuffer;
1806
- this._dataView = new DataView(this._arrayBuffer);
1807
- return newBuffer;
1808
- };
1809
- /**
1810
- * Get an array buffer with the length of the byte offset
1811
- * @returns ArrayBuffer resized to the byte offset
1812
- */
1813
- _BinaryWriter.prototype.getArrayBuffer = function () {
1814
- return this._resizeBuffer(this.getByteOffset());
1815
- };
1816
- /**
1817
- * Get the byte offset of the array buffer
1818
- * @returns byte offset
1819
- */
1820
- _BinaryWriter.prototype.getByteOffset = function () {
1821
- if (this._byteOffset == undefined) {
1822
- throw new Error("Byte offset is undefined!");
1823
- }
1824
- return this._byteOffset;
1825
- };
1826
- /**
1827
- * Stores an UInt8 in the array buffer
1828
- * @param entry
1829
- * @param byteOffset If defined, specifies where to set the value as an offset.
1830
- */
1831
- _BinaryWriter.prototype.setUInt8 = function (entry, byteOffset) {
1832
- if (byteOffset != null) {
1833
- if (byteOffset < this._byteOffset) {
1834
- this._dataView.setUint8(byteOffset, entry);
1835
- }
1836
- else {
1837
- Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1838
- }
1839
- }
1840
- else {
1841
- if (this._byteOffset + 1 > this._arrayBuffer.byteLength) {
1842
- this._resizeBuffer(this._arrayBuffer.byteLength * 2);
1843
- }
1844
- this._dataView.setUint8(this._byteOffset, entry);
1845
- this._byteOffset += 1;
1846
- }
1847
- };
1848
- /**
1849
- * Stores an UInt16 in the array buffer
1850
- * @param entry
1851
- * @param byteOffset If defined, specifies where to set the value as an offset.
1852
- */
1853
- _BinaryWriter.prototype.setUInt16 = function (entry, byteOffset) {
1854
- if (byteOffset != null) {
1855
- if (byteOffset < this._byteOffset) {
1856
- this._dataView.setUint16(byteOffset, entry, true);
1857
- }
1858
- else {
1859
- Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1860
- }
1861
- }
1862
- else {
1863
- if (this._byteOffset + 2 > this._arrayBuffer.byteLength) {
1864
- this._resizeBuffer(this._arrayBuffer.byteLength * 2);
1865
- }
1866
- this._dataView.setUint16(this._byteOffset, entry, true);
1867
- this._byteOffset += 2;
1868
- }
1869
- };
1870
- /**
1871
- * Gets an UInt32 in the array buffer
1872
- * @param byteOffset If defined, specifies where to set the value as an offset.
1873
- */
1874
- _BinaryWriter.prototype.getUInt32 = function (byteOffset) {
1875
- if (byteOffset < this._byteOffset) {
1876
- return this._dataView.getUint32(byteOffset, true);
1877
- }
1878
- else {
1879
- Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1880
- throw new Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1881
- }
1882
- };
1883
- _BinaryWriter.prototype.getVector3Float32FromRef = function (vector3, byteOffset) {
1884
- if (byteOffset + 8 > this._byteOffset) {
1885
- Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1886
- }
1887
- else {
1888
- vector3.x = this._dataView.getFloat32(byteOffset, true);
1889
- vector3.y = this._dataView.getFloat32(byteOffset + 4, true);
1890
- vector3.z = this._dataView.getFloat32(byteOffset + 8, true);
1891
- }
1892
- };
1893
- _BinaryWriter.prototype.setVector3Float32FromRef = function (vector3, byteOffset) {
1894
- if (byteOffset + 8 > this._byteOffset) {
1895
- Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1896
- }
1897
- else {
1898
- this._dataView.setFloat32(byteOffset, vector3.x, true);
1899
- this._dataView.setFloat32(byteOffset + 4, vector3.y, true);
1900
- this._dataView.setFloat32(byteOffset + 8, vector3.z, true);
1901
- }
1902
- };
1903
- _BinaryWriter.prototype.getVector4Float32FromRef = function (vector4, byteOffset) {
1904
- if (byteOffset + 12 > this._byteOffset) {
1905
- Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1906
- }
1907
- else {
1908
- vector4.x = this._dataView.getFloat32(byteOffset, true);
1909
- vector4.y = this._dataView.getFloat32(byteOffset + 4, true);
1910
- vector4.z = this._dataView.getFloat32(byteOffset + 8, true);
1911
- vector4.w = this._dataView.getFloat32(byteOffset + 12, true);
1912
- }
1913
- };
1914
- _BinaryWriter.prototype.setVector4Float32FromRef = function (vector4, byteOffset) {
1915
- if (byteOffset + 12 > this._byteOffset) {
1916
- Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1917
- }
1918
- else {
1919
- this._dataView.setFloat32(byteOffset, vector4.x, true);
1920
- this._dataView.setFloat32(byteOffset + 4, vector4.y, true);
1921
- this._dataView.setFloat32(byteOffset + 8, vector4.z, true);
1922
- this._dataView.setFloat32(byteOffset + 12, vector4.w, true);
1923
- }
1924
- };
1925
- /**
1926
- * Stores a Float32 in the array buffer
1927
- * @param entry
1928
- * @param byteOffset
1929
- */
1930
- _BinaryWriter.prototype.setFloat32 = function (entry, byteOffset) {
1931
- if (isNaN(entry)) {
1932
- Tools.Error("Invalid data being written!");
1933
- }
1934
- if (byteOffset != null) {
1935
- if (byteOffset < this._byteOffset) {
1936
- this._dataView.setFloat32(byteOffset, entry, true);
1937
- }
1938
- else {
1939
- Tools.Error("BinaryWriter: byteoffset is greater than the current binary length!");
1940
- }
1941
- }
1942
- if (this._byteOffset + 4 > this._arrayBuffer.byteLength) {
1943
- this._resizeBuffer(this._arrayBuffer.byteLength * 2);
1944
- }
1945
- this._dataView.setFloat32(this._byteOffset, entry, true);
1946
- this._byteOffset += 4;
1947
- };
1948
- /**
1949
- * Stores an UInt32 in the array buffer
1950
- * @param entry
1951
- * @param byteOffset If defined, specifies where to set the value as an offset.
1952
- */
1953
- _BinaryWriter.prototype.setUInt32 = function (entry, byteOffset) {
1954
- if (byteOffset != null) {
1955
- if (byteOffset < this._byteOffset) {
1956
- this._dataView.setUint32(byteOffset, entry, true);
1957
- }
1958
- else {
1959
- Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1960
- }
1961
- }
1962
- else {
1963
- if (this._byteOffset + 4 > this._arrayBuffer.byteLength) {
1964
- this._resizeBuffer(this._arrayBuffer.byteLength * 2);
1965
- }
1966
- this._dataView.setUint32(this._byteOffset, entry, true);
1967
- this._byteOffset += 4;
1968
- }
1969
- };
1970
- return _BinaryWriter;
1971
- }());
1972
- export { _BinaryWriter };
1
+ import { __spreadArray } from "tslib";
2
+ import { Vector2, Vector3, Vector4, Quaternion } from "@babylonjs/core/Maths/math.vector.js";
3
+ import { Color3, Color4 } from "@babylonjs/core/Maths/math.color.js";
4
+ import { Tools } from "@babylonjs/core/Misc/tools.js";
5
+ import { VertexBuffer } from "@babylonjs/core/Buffers/buffer.js";
6
+ import { TransformNode } from "@babylonjs/core/Meshes/transformNode.js";
7
+ import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh.js";
8
+ import { Mesh } from "@babylonjs/core/Meshes/mesh.js";
9
+ import { LinesMesh } from "@babylonjs/core/Meshes/linesMesh.js";
10
+ import { InstancedMesh } from "@babylonjs/core/Meshes/instancedMesh.js";
11
+ import { Material } from "@babylonjs/core/Materials/material.js";
12
+ import { Engine } from "@babylonjs/core/Engines/engine.js";
13
+ import { _GLTFMaterialExporter } from "./glTFMaterialExporter.js";
14
+ import { _GLTFUtilities } from "./glTFUtilities.js";
15
+ import { GLTFData } from "./glTFData.js";
16
+ import { _GLTFAnimation } from "./glTFAnimation.js";
17
+ import { Camera } from "@babylonjs/core/Cameras/camera.js";
18
+ import { EngineStore } from "@babylonjs/core/Engines/engineStore.js";
19
+ import { MultiMaterial } from "@babylonjs/core/Materials/multiMaterial.js";
20
+ /**
21
+ * Converts Babylon Scene into glTF 2.0.
22
+ * @hidden
23
+ */
24
+ var _Exporter = /** @class */ (function () {
25
+ /**
26
+ * Creates a glTF Exporter instance, which can accept optional exporter options
27
+ * @param babylonScene Babylon scene object
28
+ * @param options Options to modify the behavior of the exporter
29
+ */
30
+ function _Exporter(babylonScene, options) {
31
+ /*
32
+ * Specifies if root Babylon empty nodes that act as a coordinate space transform should be included in export
33
+ */
34
+ this._includeCoordinateSystemConversionNodes = false;
35
+ this._extensions = {};
36
+ this._glTF = {
37
+ asset: { generator: "Babylon.js v".concat(Engine.Version), version: "2.0" },
38
+ };
39
+ babylonScene = babylonScene || EngineStore.LastCreatedScene;
40
+ if (!babylonScene) {
41
+ return;
42
+ }
43
+ this._babylonScene = babylonScene;
44
+ this._bufferViews = [];
45
+ this._accessors = [];
46
+ this._meshes = [];
47
+ this._scenes = [];
48
+ this._cameras = [];
49
+ this._nodes = [];
50
+ this._images = [];
51
+ this._materials = [];
52
+ this._materialMap = [];
53
+ this._textures = [];
54
+ this._samplers = [];
55
+ this._skins = [];
56
+ this._animations = [];
57
+ this._imageData = {};
58
+ this._orderedImageData = [];
59
+ this._options = options || {};
60
+ this._animationSampleRate = options && options.animationSampleRate ? options.animationSampleRate : 1 / 60;
61
+ this._includeCoordinateSystemConversionNodes = options && options.includeCoordinateSystemConversionNodes ? true : false;
62
+ this._glTFMaterialExporter = new _GLTFMaterialExporter(this);
63
+ this._loadExtensions();
64
+ }
65
+ _Exporter.prototype._applyExtension = function (node, extensions, index, actionAsync) {
66
+ var _this = this;
67
+ if (index >= extensions.length) {
68
+ return Promise.resolve(node);
69
+ }
70
+ var currentPromise = actionAsync(extensions[index], node);
71
+ if (!currentPromise) {
72
+ return this._applyExtension(node, extensions, index + 1, actionAsync);
73
+ }
74
+ return currentPromise.then(function (newNode) { return _this._applyExtension(newNode, extensions, index + 1, actionAsync); });
75
+ };
76
+ _Exporter.prototype._applyExtensions = function (node, actionAsync) {
77
+ var extensions = [];
78
+ for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
79
+ var name_1 = _a[_i];
80
+ extensions.push(this._extensions[name_1]);
81
+ }
82
+ return this._applyExtension(node, extensions, 0, actionAsync);
83
+ };
84
+ _Exporter.prototype._extensionsPreExportTextureAsync = function (context, babylonTexture, mimeType) {
85
+ return this._applyExtensions(babylonTexture, function (extension, node) { return extension.preExportTextureAsync && extension.preExportTextureAsync(context, node, mimeType); });
86
+ };
87
+ _Exporter.prototype._extensionsPostExportMeshPrimitiveAsync = function (context, meshPrimitive, babylonSubMesh, binaryWriter) {
88
+ return this._applyExtensions(meshPrimitive, function (extension, node) { return extension.postExportMeshPrimitiveAsync && extension.postExportMeshPrimitiveAsync(context, node, babylonSubMesh, binaryWriter); });
89
+ };
90
+ _Exporter.prototype._extensionsPostExportNodeAsync = function (context, node, babylonNode, nodeMap) {
91
+ return this._applyExtensions(node, function (extension, node) { return extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode, nodeMap); });
92
+ };
93
+ _Exporter.prototype._extensionsPostExportMaterialAsync = function (context, material, babylonMaterial) {
94
+ return this._applyExtensions(material, function (extension, node) { return extension.postExportMaterialAsync && extension.postExportMaterialAsync(context, node, babylonMaterial); });
95
+ };
96
+ _Exporter.prototype._extensionsPostExportMaterialAdditionalTextures = function (context, material, babylonMaterial) {
97
+ var output = [];
98
+ for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
99
+ var name_2 = _a[_i];
100
+ var extension = this._extensions[name_2];
101
+ if (extension.postExportMaterialAdditionalTextures) {
102
+ output.push.apply(output, extension.postExportMaterialAdditionalTextures(context, material, babylonMaterial));
103
+ }
104
+ }
105
+ return output;
106
+ };
107
+ _Exporter.prototype._extensionsPostExportTextures = function (context, textureInfo, babylonTexture) {
108
+ for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
109
+ var name_3 = _a[_i];
110
+ var extension = this._extensions[name_3];
111
+ if (extension.postExportTexture) {
112
+ extension.postExportTexture(context, textureInfo, babylonTexture);
113
+ }
114
+ }
115
+ };
116
+ _Exporter.prototype._forEachExtensions = function (action) {
117
+ for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
118
+ var name_4 = _a[_i];
119
+ var extension = this._extensions[name_4];
120
+ if (extension.enabled) {
121
+ action(extension);
122
+ }
123
+ }
124
+ };
125
+ _Exporter.prototype._extensionsOnExporting = function () {
126
+ var _this = this;
127
+ this._forEachExtensions(function (extension) {
128
+ if (extension.wasUsed) {
129
+ if (_this._glTF.extensionsUsed == null) {
130
+ _this._glTF.extensionsUsed = [];
131
+ }
132
+ if (_this._glTF.extensionsUsed.indexOf(extension.name) === -1) {
133
+ _this._glTF.extensionsUsed.push(extension.name);
134
+ }
135
+ if (extension.required) {
136
+ if (_this._glTF.extensionsRequired == null) {
137
+ _this._glTF.extensionsRequired = [];
138
+ }
139
+ if (_this._glTF.extensionsRequired.indexOf(extension.name) === -1) {
140
+ _this._glTF.extensionsRequired.push(extension.name);
141
+ }
142
+ }
143
+ if (_this._glTF.extensions == null) {
144
+ _this._glTF.extensions = {};
145
+ }
146
+ if (extension.onExporting) {
147
+ extension.onExporting();
148
+ }
149
+ }
150
+ });
151
+ };
152
+ /**
153
+ * Load glTF serializer extensions
154
+ */
155
+ _Exporter.prototype._loadExtensions = function () {
156
+ for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
157
+ var name_5 = _a[_i];
158
+ var extension = _Exporter._ExtensionFactories[name_5](this);
159
+ this._extensions[name_5] = extension;
160
+ }
161
+ };
162
+ _Exporter.prototype.dispose = function () {
163
+ for (var extensionKey in this._extensions) {
164
+ var extension = this._extensions[extensionKey];
165
+ extension.dispose();
166
+ }
167
+ };
168
+ /**
169
+ * Registers a glTF exporter extension
170
+ * @param name Name of the extension to export
171
+ * @param factory The factory function that creates the exporter extension
172
+ */
173
+ _Exporter.RegisterExtension = function (name, factory) {
174
+ if (_Exporter.UnregisterExtension(name)) {
175
+ Tools.Warn("Extension with the name ".concat(name, " already exists"));
176
+ }
177
+ _Exporter._ExtensionFactories[name] = factory;
178
+ _Exporter._ExtensionNames.push(name);
179
+ };
180
+ /**
181
+ * Un-registers an exporter extension
182
+ * @param name The name fo the exporter extension
183
+ * @returns A boolean indicating whether the extension has been un-registered
184
+ */
185
+ _Exporter.UnregisterExtension = function (name) {
186
+ if (!_Exporter._ExtensionFactories[name]) {
187
+ return false;
188
+ }
189
+ delete _Exporter._ExtensionFactories[name];
190
+ var index = _Exporter._ExtensionNames.indexOf(name);
191
+ if (index !== -1) {
192
+ _Exporter._ExtensionNames.splice(index, 1);
193
+ }
194
+ return true;
195
+ };
196
+ _Exporter.prototype._reorderIndicesBasedOnPrimitiveMode = function (submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter) {
197
+ switch (primitiveMode) {
198
+ case Material.TriangleFillMode: {
199
+ if (!byteOffset) {
200
+ byteOffset = 0;
201
+ }
202
+ for (var i = submesh.indexStart, length_1 = submesh.indexStart + submesh.indexCount; i < length_1; i = i + 3) {
203
+ var index = byteOffset + i * 4;
204
+ // swap the second and third indices
205
+ var secondIndex = binaryWriter.getUInt32(index + 4);
206
+ var thirdIndex = binaryWriter.getUInt32(index + 8);
207
+ binaryWriter.setUInt32(thirdIndex, index + 4);
208
+ binaryWriter.setUInt32(secondIndex, index + 8);
209
+ }
210
+ break;
211
+ }
212
+ case Material.TriangleFanDrawMode: {
213
+ for (var i = submesh.indexStart + submesh.indexCount - 1, start = submesh.indexStart; i >= start; --i) {
214
+ binaryWriter.setUInt32(babylonIndices[i], byteOffset);
215
+ byteOffset += 4;
216
+ }
217
+ break;
218
+ }
219
+ case Material.TriangleStripDrawMode: {
220
+ if (submesh.indexCount >= 3) {
221
+ binaryWriter.setUInt32(babylonIndices[submesh.indexStart + 2], byteOffset + 4);
222
+ binaryWriter.setUInt32(babylonIndices[submesh.indexStart + 1], byteOffset + 8);
223
+ }
224
+ break;
225
+ }
226
+ }
227
+ };
228
+ /**
229
+ * Reorders the vertex attribute data based on the primitive mode. This is necessary when indices are not available and the winding order is
230
+ * clock-wise during export to glTF
231
+ * @param submesh BabylonJS submesh
232
+ * @param primitiveMode Primitive mode of the mesh
233
+ * @param sideOrientation the winding order of the submesh
234
+ * @param vertexBufferKind The type of vertex attribute
235
+ * @param meshAttributeArray The vertex attribute data
236
+ * @param byteOffset The offset to the binary data
237
+ * @param binaryWriter The binary data for the glTF file
238
+ * @param convertToRightHandedSystem Converts the values to right-handed
239
+ */
240
+ _Exporter.prototype._reorderVertexAttributeDataBasedOnPrimitiveMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
241
+ if (convertToRightHandedSystem && sideOrientation === Material.ClockWiseSideOrientation) {
242
+ switch (primitiveMode) {
243
+ case Material.TriangleFillMode: {
244
+ this._reorderTriangleFillMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
245
+ break;
246
+ }
247
+ case Material.TriangleStripDrawMode: {
248
+ this._reorderTriangleStripDrawMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
249
+ break;
250
+ }
251
+ case Material.TriangleFanDrawMode: {
252
+ this._reorderTriangleFanMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
253
+ break;
254
+ }
255
+ }
256
+ }
257
+ };
258
+ /**
259
+ * Reorders the vertex attributes in the correct triangle mode order . This is necessary when indices are not available and the winding order is
260
+ * clock-wise during export to glTF
261
+ * @param submesh BabylonJS submesh
262
+ * @param primitiveMode Primitive mode of the mesh
263
+ * @param sideOrientation the winding order of the submesh
264
+ * @param vertexBufferKind The type of vertex attribute
265
+ * @param meshAttributeArray The vertex attribute data
266
+ * @param byteOffset The offset to the binary data
267
+ * @param binaryWriter The binary data for the glTF file
268
+ * @param convertToRightHandedSystem Converts the values to right-handed
269
+ */
270
+ _Exporter.prototype._reorderTriangleFillMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
271
+ var vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
272
+ if (vertexBuffer) {
273
+ var stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);
274
+ if (submesh.verticesCount % 3 !== 0) {
275
+ Tools.Error("The submesh vertices for the triangle fill mode is not divisible by 3!");
276
+ }
277
+ else {
278
+ var vertexData = [];
279
+ var index = 0;
280
+ switch (vertexBufferKind) {
281
+ case VertexBuffer.PositionKind:
282
+ case VertexBuffer.NormalKind: {
283
+ for (var x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) {
284
+ index = x * stride;
285
+ vertexData.push(Vector3.FromArray(meshAttributeArray, index));
286
+ vertexData.push(Vector3.FromArray(meshAttributeArray, index + 2 * stride));
287
+ vertexData.push(Vector3.FromArray(meshAttributeArray, index + stride));
288
+ }
289
+ break;
290
+ }
291
+ case VertexBuffer.TangentKind: {
292
+ for (var x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) {
293
+ index = x * stride;
294
+ vertexData.push(Vector4.FromArray(meshAttributeArray, index));
295
+ vertexData.push(Vector4.FromArray(meshAttributeArray, index + 2 * stride));
296
+ vertexData.push(Vector4.FromArray(meshAttributeArray, index + stride));
297
+ }
298
+ break;
299
+ }
300
+ case VertexBuffer.ColorKind: {
301
+ var size = vertexBuffer.getSize();
302
+ for (var x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + size) {
303
+ index = x * stride;
304
+ if (size === 4) {
305
+ vertexData.push(Vector4.FromArray(meshAttributeArray, index));
306
+ vertexData.push(Vector4.FromArray(meshAttributeArray, index + 2 * stride));
307
+ vertexData.push(Vector4.FromArray(meshAttributeArray, index + stride));
308
+ }
309
+ else {
310
+ vertexData.push(Vector3.FromArray(meshAttributeArray, index));
311
+ vertexData.push(Vector3.FromArray(meshAttributeArray, index + 2 * stride));
312
+ vertexData.push(Vector3.FromArray(meshAttributeArray, index + stride));
313
+ }
314
+ }
315
+ break;
316
+ }
317
+ case VertexBuffer.UVKind:
318
+ case VertexBuffer.UV2Kind: {
319
+ for (var x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) {
320
+ index = x * stride;
321
+ vertexData.push(Vector2.FromArray(meshAttributeArray, index));
322
+ vertexData.push(Vector2.FromArray(meshAttributeArray, index + 2 * stride));
323
+ vertexData.push(Vector2.FromArray(meshAttributeArray, index + stride));
324
+ }
325
+ break;
326
+ }
327
+ default: {
328
+ Tools.Error("Unsupported Vertex Buffer type: ".concat(vertexBufferKind));
329
+ }
330
+ }
331
+ this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
332
+ }
333
+ }
334
+ else {
335
+ Tools.Warn("reorderTriangleFillMode: Vertex Buffer Kind ".concat(vertexBufferKind, " not present!"));
336
+ }
337
+ };
338
+ /**
339
+ * Reorders the vertex attributes in the correct triangle strip order. This is necessary when indices are not available and the winding order is
340
+ * clock-wise during export to glTF
341
+ * @param submesh BabylonJS submesh
342
+ * @param primitiveMode Primitive mode of the mesh
343
+ * @param sideOrientation the winding order of the submesh
344
+ * @param vertexBufferKind The type of vertex attribute
345
+ * @param meshAttributeArray The vertex attribute data
346
+ * @param byteOffset The offset to the binary data
347
+ * @param binaryWriter The binary data for the glTF file
348
+ * @param convertToRightHandedSystem Converts the values to right-handed
349
+ */
350
+ _Exporter.prototype._reorderTriangleStripDrawMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
351
+ var vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
352
+ if (vertexBuffer) {
353
+ var stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);
354
+ var vertexData = [];
355
+ var index = 0;
356
+ switch (vertexBufferKind) {
357
+ case VertexBuffer.PositionKind:
358
+ case VertexBuffer.NormalKind: {
359
+ index = submesh.verticesStart;
360
+ vertexData.push(Vector3.FromArray(meshAttributeArray, index + 2 * stride));
361
+ vertexData.push(Vector3.FromArray(meshAttributeArray, index + stride));
362
+ break;
363
+ }
364
+ case VertexBuffer.TangentKind: {
365
+ for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
366
+ index = x * stride;
367
+ vertexData.push(Vector4.FromArray(meshAttributeArray, index));
368
+ }
369
+ break;
370
+ }
371
+ case VertexBuffer.ColorKind: {
372
+ for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
373
+ index = x * stride;
374
+ vertexBuffer.getSize() === 4
375
+ ? vertexData.push(Vector4.FromArray(meshAttributeArray, index))
376
+ : vertexData.push(Vector3.FromArray(meshAttributeArray, index));
377
+ }
378
+ break;
379
+ }
380
+ case VertexBuffer.UVKind:
381
+ case VertexBuffer.UV2Kind: {
382
+ for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
383
+ index = x * stride;
384
+ vertexData.push(Vector2.FromArray(meshAttributeArray, index));
385
+ }
386
+ break;
387
+ }
388
+ default: {
389
+ Tools.Error("Unsupported Vertex Buffer type: ".concat(vertexBufferKind));
390
+ }
391
+ }
392
+ this._writeVertexAttributeData(vertexData, byteOffset + 12, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
393
+ }
394
+ else {
395
+ Tools.Warn("reorderTriangleStripDrawMode: Vertex buffer kind ".concat(vertexBufferKind, " not present!"));
396
+ }
397
+ };
398
+ /**
399
+ * Reorders the vertex attributes in the correct triangle fan order. This is necessary when indices are not available and the winding order is
400
+ * clock-wise during export to glTF
401
+ * @param submesh BabylonJS submesh
402
+ * @param primitiveMode Primitive mode of the mesh
403
+ * @param sideOrientation the winding order of the submesh
404
+ * @param vertexBufferKind The type of vertex attribute
405
+ * @param meshAttributeArray The vertex attribute data
406
+ * @param byteOffset The offset to the binary data
407
+ * @param binaryWriter The binary data for the glTF file
408
+ * @param convertToRightHandedSystem Converts the values to right-handed
409
+ */
410
+ _Exporter.prototype._reorderTriangleFanMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
411
+ var vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
412
+ if (vertexBuffer) {
413
+ var stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);
414
+ var vertexData = [];
415
+ var index = 0;
416
+ switch (vertexBufferKind) {
417
+ case VertexBuffer.PositionKind:
418
+ case VertexBuffer.NormalKind: {
419
+ for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
420
+ index = x * stride;
421
+ vertexData.push(Vector3.FromArray(meshAttributeArray, index));
422
+ }
423
+ break;
424
+ }
425
+ case VertexBuffer.TangentKind: {
426
+ for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
427
+ index = x * stride;
428
+ vertexData.push(Vector4.FromArray(meshAttributeArray, index));
429
+ }
430
+ break;
431
+ }
432
+ case VertexBuffer.ColorKind: {
433
+ for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
434
+ index = x * stride;
435
+ vertexData.push(Vector4.FromArray(meshAttributeArray, index));
436
+ vertexBuffer.getSize() === 4
437
+ ? vertexData.push(Vector4.FromArray(meshAttributeArray, index))
438
+ : vertexData.push(Vector3.FromArray(meshAttributeArray, index));
439
+ }
440
+ break;
441
+ }
442
+ case VertexBuffer.UVKind:
443
+ case VertexBuffer.UV2Kind: {
444
+ for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {
445
+ index = x * stride;
446
+ vertexData.push(Vector2.FromArray(meshAttributeArray, index));
447
+ }
448
+ break;
449
+ }
450
+ default: {
451
+ Tools.Error("Unsupported Vertex Buffer type: ".concat(vertexBufferKind));
452
+ }
453
+ }
454
+ this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
455
+ }
456
+ else {
457
+ Tools.Warn("reorderTriangleFanMode: Vertex buffer kind ".concat(vertexBufferKind, " not present!"));
458
+ }
459
+ };
460
+ /**
461
+ * Writes the vertex attribute data to binary
462
+ * @param vertices The vertices to write to the binary writer
463
+ * @param byteOffset The offset into the binary writer to overwrite binary data
464
+ * @param vertexAttributeKind The vertex attribute type
465
+ * @param meshAttributeArray The vertex attribute data
466
+ * @param binaryWriter The writer containing the binary data
467
+ * @param convertToRightHandedSystem Converts the values to right-handed
468
+ */
469
+ _Exporter.prototype._writeVertexAttributeData = function (vertices, byteOffset, vertexAttributeKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem) {
470
+ for (var _i = 0, vertices_1 = vertices; _i < vertices_1.length; _i++) {
471
+ var vertex = vertices_1[_i];
472
+ if (convertToRightHandedSystem && !(vertexAttributeKind === VertexBuffer.ColorKind) && !(vertex instanceof Vector2)) {
473
+ if (vertex instanceof Vector3) {
474
+ if (vertexAttributeKind === VertexBuffer.NormalKind) {
475
+ _GLTFUtilities._GetRightHandedNormalVector3FromRef(vertex);
476
+ }
477
+ else if (vertexAttributeKind === VertexBuffer.PositionKind) {
478
+ _GLTFUtilities._GetRightHandedPositionVector3FromRef(vertex);
479
+ }
480
+ else {
481
+ Tools.Error("Unsupported vertex attribute kind!");
482
+ }
483
+ }
484
+ else {
485
+ _GLTFUtilities._GetRightHandedVector4FromRef(vertex);
486
+ }
487
+ }
488
+ if (vertexAttributeKind === VertexBuffer.NormalKind) {
489
+ vertex.normalize();
490
+ }
491
+ else if (vertexAttributeKind === VertexBuffer.TangentKind && vertex instanceof Vector4) {
492
+ _GLTFUtilities._NormalizeTangentFromRef(vertex);
493
+ }
494
+ for (var _a = 0, _b = vertex.asArray(); _a < _b.length; _a++) {
495
+ var component = _b[_a];
496
+ binaryWriter.setFloat32(component, byteOffset);
497
+ byteOffset += 4;
498
+ }
499
+ }
500
+ };
501
+ /**
502
+ * Writes mesh attribute data to a data buffer
503
+ * Returns the bytelength of the data
504
+ * @param vertexBufferKind Indicates what kind of vertex data is being passed in
505
+ * @param attributeComponentKind
506
+ * @param meshAttributeArray Array containing the attribute data
507
+ * @param stride Specifies the space between data
508
+ * @param binaryWriter The buffer to write the binary data to
509
+ * @param convertToRightHandedSystem Converts the values to right-handed
510
+ * @param babylonTransformNode
511
+ */
512
+ _Exporter.prototype._writeAttributeData = function (vertexBufferKind, attributeComponentKind, meshAttributeArray, stride, binaryWriter, convertToRightHandedSystem, babylonTransformNode) {
513
+ var vertexAttributes = [];
514
+ var index;
515
+ switch (vertexBufferKind) {
516
+ case VertexBuffer.PositionKind: {
517
+ for (var k = 0, length_2 = meshAttributeArray.length / stride; k < length_2; ++k) {
518
+ index = k * stride;
519
+ var vertexData = Vector3.FromArray(meshAttributeArray, index);
520
+ if (convertToRightHandedSystem) {
521
+ _GLTFUtilities._GetRightHandedPositionVector3FromRef(vertexData);
522
+ }
523
+ vertexAttributes.push(vertexData.asArray());
524
+ }
525
+ break;
526
+ }
527
+ case VertexBuffer.NormalKind: {
528
+ for (var k = 0, length_3 = meshAttributeArray.length / stride; k < length_3; ++k) {
529
+ index = k * stride;
530
+ var vertexData = Vector3.FromArray(meshAttributeArray, index);
531
+ if (convertToRightHandedSystem) {
532
+ _GLTFUtilities._GetRightHandedNormalVector3FromRef(vertexData);
533
+ }
534
+ vertexData.normalize();
535
+ vertexAttributes.push(vertexData.asArray());
536
+ }
537
+ break;
538
+ }
539
+ case VertexBuffer.TangentKind: {
540
+ for (var k = 0, length_4 = meshAttributeArray.length / stride; k < length_4; ++k) {
541
+ index = k * stride;
542
+ var vertexData = Vector4.FromArray(meshAttributeArray, index);
543
+ if (convertToRightHandedSystem) {
544
+ _GLTFUtilities._GetRightHandedVector4FromRef(vertexData);
545
+ }
546
+ _GLTFUtilities._NormalizeTangentFromRef(vertexData);
547
+ vertexAttributes.push(vertexData.asArray());
548
+ }
549
+ break;
550
+ }
551
+ case VertexBuffer.ColorKind: {
552
+ var meshMaterial = babylonTransformNode.material;
553
+ var convertToLinear = meshMaterial ? meshMaterial.getClassName() === "StandardMaterial" : true;
554
+ var vertexData = stride === 3 ? new Color3() : new Color4();
555
+ for (var k = 0, length_5 = meshAttributeArray.length / stride; k < length_5; ++k) {
556
+ index = k * stride;
557
+ if (stride === 3) {
558
+ Color3.FromArrayToRef(meshAttributeArray, index, vertexData);
559
+ if (convertToLinear) {
560
+ vertexData.toLinearSpaceToRef(vertexData);
561
+ }
562
+ }
563
+ else {
564
+ Color4.FromArrayToRef(meshAttributeArray, index, vertexData);
565
+ if (convertToLinear) {
566
+ vertexData.toLinearSpaceToRef(vertexData);
567
+ }
568
+ }
569
+ vertexAttributes.push(vertexData.asArray());
570
+ }
571
+ break;
572
+ }
573
+ case VertexBuffer.UVKind:
574
+ case VertexBuffer.UV2Kind: {
575
+ for (var k = 0, length_6 = meshAttributeArray.length / stride; k < length_6; ++k) {
576
+ index = k * stride;
577
+ vertexAttributes.push(convertToRightHandedSystem ? [meshAttributeArray[index], meshAttributeArray[index + 1]] : [meshAttributeArray[index], meshAttributeArray[index + 1]]);
578
+ }
579
+ break;
580
+ }
581
+ case VertexBuffer.MatricesIndicesKind:
582
+ case VertexBuffer.MatricesIndicesExtraKind: {
583
+ for (var k = 0, length_7 = meshAttributeArray.length / stride; k < length_7; ++k) {
584
+ index = k * stride;
585
+ var vertexData = Vector4.FromArray(meshAttributeArray, index);
586
+ vertexAttributes.push(vertexData.asArray());
587
+ }
588
+ break;
589
+ }
590
+ case VertexBuffer.MatricesWeightsKind:
591
+ case VertexBuffer.MatricesWeightsExtraKind: {
592
+ for (var k = 0, length_8 = meshAttributeArray.length / stride; k < length_8; ++k) {
593
+ index = k * stride;
594
+ var vertexData = Vector4.FromArray(meshAttributeArray, index);
595
+ vertexAttributes.push(vertexData.asArray());
596
+ }
597
+ break;
598
+ }
599
+ default: {
600
+ Tools.Warn("Unsupported Vertex Buffer Type: " + vertexBufferKind);
601
+ vertexAttributes = [];
602
+ }
603
+ }
604
+ var writeBinaryFunc;
605
+ switch (attributeComponentKind) {
606
+ case 5121 /* UNSIGNED_BYTE */: {
607
+ writeBinaryFunc = binaryWriter.setUInt8.bind(binaryWriter);
608
+ break;
609
+ }
610
+ case 5123 /* UNSIGNED_SHORT */: {
611
+ writeBinaryFunc = binaryWriter.setUInt16.bind(binaryWriter);
612
+ break;
613
+ }
614
+ case 5125 /* UNSIGNED_INT */: {
615
+ writeBinaryFunc = binaryWriter.setUInt32.bind(binaryWriter);
616
+ break;
617
+ }
618
+ case 5126 /* FLOAT */: {
619
+ writeBinaryFunc = binaryWriter.setFloat32.bind(binaryWriter);
620
+ break;
621
+ }
622
+ default: {
623
+ Tools.Warn("Unsupported Attribute Component kind: " + attributeComponentKind);
624
+ return;
625
+ }
626
+ }
627
+ for (var _i = 0, vertexAttributes_1 = vertexAttributes; _i < vertexAttributes_1.length; _i++) {
628
+ var vertexAttribute = vertexAttributes_1[_i];
629
+ for (var _a = 0, vertexAttribute_1 = vertexAttribute; _a < vertexAttribute_1.length; _a++) {
630
+ var component = vertexAttribute_1[_a];
631
+ writeBinaryFunc(component);
632
+ }
633
+ }
634
+ };
635
+ /**
636
+ * Writes mesh attribute data to a data buffer
637
+ * Returns the bytelength of the data
638
+ * @param vertexBufferKind Indicates what kind of vertex data is being passed in
639
+ * @param attributeComponentKind
640
+ * @param meshPrimitive
641
+ * @param morphTarget
642
+ * @param meshAttributeArray Array containing the attribute data
643
+ * @param morphTargetAttributeArray
644
+ * @param stride Specifies the space between data
645
+ * @param binaryWriter The buffer to write the binary data to
646
+ * @param convertToRightHandedSystem Converts the values to right-handed
647
+ * @param minMax
648
+ */
649
+ _Exporter.prototype.writeMorphTargetAttributeData = function (vertexBufferKind, attributeComponentKind, meshPrimitive, morphTarget, meshAttributeArray, morphTargetAttributeArray, stride, binaryWriter, convertToRightHandedSystem, minMax) {
650
+ var vertexAttributes = [];
651
+ var index;
652
+ var difference = new Vector3();
653
+ var difference4 = new Vector4(0, 0, 0, 0);
654
+ switch (vertexBufferKind) {
655
+ case VertexBuffer.PositionKind: {
656
+ for (var k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
657
+ index = meshPrimitive.indexStart + k * stride;
658
+ var vertexData = Vector3.FromArray(meshAttributeArray, index);
659
+ var morphData = Vector3.FromArray(morphTargetAttributeArray, index);
660
+ difference = morphData.subtractToRef(vertexData, difference);
661
+ if (convertToRightHandedSystem) {
662
+ _GLTFUtilities._GetRightHandedPositionVector3FromRef(difference);
663
+ }
664
+ if (minMax) {
665
+ minMax.min.copyFromFloats(Math.min(difference.x, minMax.min.x), Math.min(difference.y, minMax.min.y), Math.min(difference.z, minMax.min.z));
666
+ minMax.max.copyFromFloats(Math.max(difference.x, minMax.max.x), Math.max(difference.y, minMax.max.y), Math.max(difference.z, minMax.max.z));
667
+ }
668
+ vertexAttributes.push(difference.asArray());
669
+ }
670
+ break;
671
+ }
672
+ case VertexBuffer.NormalKind: {
673
+ for (var k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
674
+ index = meshPrimitive.indexStart + k * stride;
675
+ var vertexData = Vector3.FromArray(meshAttributeArray, index);
676
+ vertexData.normalize();
677
+ var morphData = Vector3.FromArray(morphTargetAttributeArray, index);
678
+ morphData.normalize();
679
+ difference = morphData.subtractToRef(vertexData, difference);
680
+ if (convertToRightHandedSystem) {
681
+ _GLTFUtilities._GetRightHandedNormalVector3FromRef(difference);
682
+ }
683
+ vertexAttributes.push(difference.asArray());
684
+ }
685
+ break;
686
+ }
687
+ case VertexBuffer.TangentKind: {
688
+ for (var k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
689
+ index = meshPrimitive.indexStart + k * (stride + 1);
690
+ var vertexData = Vector4.FromArray(meshAttributeArray, index);
691
+ _GLTFUtilities._NormalizeTangentFromRef(vertexData);
692
+ var morphData = Vector4.FromArray(morphTargetAttributeArray, index);
693
+ _GLTFUtilities._NormalizeTangentFromRef(morphData);
694
+ difference4 = morphData.subtractToRef(vertexData, difference4);
695
+ if (convertToRightHandedSystem) {
696
+ _GLTFUtilities._GetRightHandedVector4FromRef(difference4);
697
+ }
698
+ vertexAttributes.push([difference4.x, difference4.y, difference4.z]);
699
+ }
700
+ break;
701
+ }
702
+ default: {
703
+ Tools.Warn("Unsupported Vertex Buffer Type: " + vertexBufferKind);
704
+ vertexAttributes = [];
705
+ }
706
+ }
707
+ var writeBinaryFunc;
708
+ switch (attributeComponentKind) {
709
+ case 5121 /* UNSIGNED_BYTE */: {
710
+ writeBinaryFunc = binaryWriter.setUInt8.bind(binaryWriter);
711
+ break;
712
+ }
713
+ case 5123 /* UNSIGNED_SHORT */: {
714
+ writeBinaryFunc = binaryWriter.setUInt16.bind(binaryWriter);
715
+ break;
716
+ }
717
+ case 5125 /* UNSIGNED_INT */: {
718
+ writeBinaryFunc = binaryWriter.setUInt32.bind(binaryWriter);
719
+ break;
720
+ }
721
+ case 5126 /* FLOAT */: {
722
+ writeBinaryFunc = binaryWriter.setFloat32.bind(binaryWriter);
723
+ break;
724
+ }
725
+ default: {
726
+ Tools.Warn("Unsupported Attribute Component kind: " + attributeComponentKind);
727
+ return;
728
+ }
729
+ }
730
+ for (var _i = 0, vertexAttributes_2 = vertexAttributes; _i < vertexAttributes_2.length; _i++) {
731
+ var vertexAttribute = vertexAttributes_2[_i];
732
+ for (var _a = 0, vertexAttribute_2 = vertexAttribute; _a < vertexAttribute_2.length; _a++) {
733
+ var component = vertexAttribute_2[_a];
734
+ writeBinaryFunc(component);
735
+ }
736
+ }
737
+ };
738
+ /**
739
+ * Generates glTF json data
740
+ * @param shouldUseGlb Indicates whether the json should be written for a glb file
741
+ * @param glTFPrefix Text to use when prefixing a glTF file
742
+ * @param prettyPrint Indicates whether the json file should be pretty printed (true) or not (false)
743
+ * @returns json data as string
744
+ */
745
+ _Exporter.prototype._generateJSON = function (shouldUseGlb, glTFPrefix, prettyPrint) {
746
+ var _this = this;
747
+ var buffer = { byteLength: this._totalByteLength };
748
+ var imageName;
749
+ var imageData;
750
+ var bufferView;
751
+ var byteOffset = this._totalByteLength;
752
+ if (buffer.byteLength) {
753
+ this._glTF.buffers = [buffer];
754
+ }
755
+ if (this._nodes && this._nodes.length) {
756
+ this._glTF.nodes = this._nodes;
757
+ }
758
+ if (this._meshes && this._meshes.length) {
759
+ this._glTF.meshes = this._meshes;
760
+ }
761
+ if (this._scenes && this._scenes.length) {
762
+ this._glTF.scenes = this._scenes;
763
+ this._glTF.scene = 0;
764
+ }
765
+ if (this._cameras && this._cameras.length) {
766
+ this._glTF.cameras = this._cameras;
767
+ }
768
+ if (this._bufferViews && this._bufferViews.length) {
769
+ this._glTF.bufferViews = this._bufferViews;
770
+ }
771
+ if (this._accessors && this._accessors.length) {
772
+ this._glTF.accessors = this._accessors;
773
+ }
774
+ if (this._animations && this._animations.length) {
775
+ this._glTF.animations = this._animations;
776
+ }
777
+ if (this._materials && this._materials.length) {
778
+ this._glTF.materials = this._materials;
779
+ }
780
+ if (this._textures && this._textures.length) {
781
+ this._glTF.textures = this._textures;
782
+ }
783
+ if (this._samplers && this._samplers.length) {
784
+ this._glTF.samplers = this._samplers;
785
+ }
786
+ if (this._skins && this._skins.length) {
787
+ this._glTF.skins = this._skins;
788
+ }
789
+ if (this._images && this._images.length) {
790
+ if (!shouldUseGlb) {
791
+ this._glTF.images = this._images;
792
+ }
793
+ else {
794
+ this._glTF.images = [];
795
+ this._images.forEach(function (image) {
796
+ if (image.uri) {
797
+ imageData = _this._imageData[image.uri];
798
+ _this._orderedImageData.push(imageData);
799
+ imageName = image.uri.split(".")[0] + " image";
800
+ bufferView = _GLTFUtilities._CreateBufferView(0, byteOffset, imageData.data.length, undefined, imageName);
801
+ byteOffset += imageData.data.buffer.byteLength;
802
+ _this._bufferViews.push(bufferView);
803
+ image.bufferView = _this._bufferViews.length - 1;
804
+ image.name = imageName;
805
+ image.mimeType = imageData.mimeType;
806
+ image.uri = undefined;
807
+ if (!_this._glTF.images) {
808
+ _this._glTF.images = [];
809
+ }
810
+ _this._glTF.images.push(image);
811
+ }
812
+ });
813
+ // Replace uri with bufferview and mime type for glb
814
+ buffer.byteLength = byteOffset;
815
+ }
816
+ }
817
+ if (!shouldUseGlb) {
818
+ buffer.uri = glTFPrefix + ".bin";
819
+ }
820
+ var jsonText = prettyPrint ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF);
821
+ return jsonText;
822
+ };
823
+ /**
824
+ * Generates data for .gltf and .bin files based on the glTF prefix string
825
+ * @param glTFPrefix Text to use when prefixing a glTF file
826
+ * @param dispose Dispose the exporter
827
+ * @returns GLTFData with glTF file data
828
+ */
829
+ _Exporter.prototype._generateGLTFAsync = function (glTFPrefix, dispose) {
830
+ var _this = this;
831
+ if (dispose === void 0) { dispose = true; }
832
+ return this._generateBinaryAsync().then(function (binaryBuffer) {
833
+ _this._extensionsOnExporting();
834
+ var jsonText = _this._generateJSON(false, glTFPrefix, true);
835
+ var bin = new Blob([binaryBuffer], { type: "application/octet-stream" });
836
+ var glTFFileName = glTFPrefix + ".gltf";
837
+ var glTFBinFile = glTFPrefix + ".bin";
838
+ var container = new GLTFData();
839
+ container.glTFFiles[glTFFileName] = jsonText;
840
+ container.glTFFiles[glTFBinFile] = bin;
841
+ if (_this._imageData) {
842
+ for (var image in _this._imageData) {
843
+ container.glTFFiles[image] = new Blob([_this._imageData[image].data], { type: _this._imageData[image].mimeType });
844
+ }
845
+ }
846
+ if (dispose) {
847
+ _this.dispose();
848
+ }
849
+ return container;
850
+ });
851
+ };
852
+ /**
853
+ * Creates a binary buffer for glTF
854
+ * @returns array buffer for binary data
855
+ */
856
+ _Exporter.prototype._generateBinaryAsync = function () {
857
+ var _this = this;
858
+ var binaryWriter = new _BinaryWriter(4);
859
+ return this._createSceneAsync(this._babylonScene, binaryWriter).then(function () {
860
+ if (_this._localEngine) {
861
+ _this._localEngine.dispose();
862
+ }
863
+ return binaryWriter.getArrayBuffer();
864
+ });
865
+ };
866
+ /**
867
+ * Pads the number to a multiple of 4
868
+ * @param num number to pad
869
+ * @returns padded number
870
+ */
871
+ _Exporter.prototype._getPadding = function (num) {
872
+ var remainder = num % 4;
873
+ var padding = remainder === 0 ? remainder : 4 - remainder;
874
+ return padding;
875
+ };
876
+ /**
877
+ * @param glTFPrefix
878
+ * @param dispose
879
+ * @hidden
880
+ */
881
+ _Exporter.prototype._generateGLBAsync = function (glTFPrefix, dispose) {
882
+ var _this = this;
883
+ if (dispose === void 0) { dispose = true; }
884
+ return this._generateBinaryAsync().then(function (binaryBuffer) {
885
+ _this._extensionsOnExporting();
886
+ var jsonText = _this._generateJSON(true);
887
+ var glbFileName = glTFPrefix + ".glb";
888
+ var headerLength = 12;
889
+ var chunkLengthPrefix = 8;
890
+ var jsonLength = jsonText.length;
891
+ var encodedJsonText;
892
+ var imageByteLength = 0;
893
+ // make use of TextEncoder when available
894
+ if (typeof TextEncoder !== "undefined") {
895
+ var encoder = new TextEncoder();
896
+ encodedJsonText = encoder.encode(jsonText);
897
+ jsonLength = encodedJsonText.length;
898
+ }
899
+ for (var i = 0; i < _this._orderedImageData.length; ++i) {
900
+ imageByteLength += _this._orderedImageData[i].data.byteLength;
901
+ }
902
+ var jsonPadding = _this._getPadding(jsonLength);
903
+ var binPadding = _this._getPadding(binaryBuffer.byteLength);
904
+ var imagePadding = _this._getPadding(imageByteLength);
905
+ var byteLength = headerLength + 2 * chunkLengthPrefix + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength + imagePadding;
906
+ //header
907
+ var headerBuffer = new ArrayBuffer(headerLength);
908
+ var headerBufferView = new DataView(headerBuffer);
909
+ headerBufferView.setUint32(0, 0x46546c67, true); //glTF
910
+ headerBufferView.setUint32(4, 2, true); // version
911
+ headerBufferView.setUint32(8, byteLength, true); // total bytes in file
912
+ //json chunk
913
+ var jsonChunkBuffer = new ArrayBuffer(chunkLengthPrefix + jsonLength + jsonPadding);
914
+ var jsonChunkBufferView = new DataView(jsonChunkBuffer);
915
+ jsonChunkBufferView.setUint32(0, jsonLength + jsonPadding, true);
916
+ jsonChunkBufferView.setUint32(4, 0x4e4f534a, true);
917
+ //json chunk bytes
918
+ var jsonData = new Uint8Array(jsonChunkBuffer, chunkLengthPrefix);
919
+ // if TextEncoder was available, we can simply copy the encoded array
920
+ if (encodedJsonText) {
921
+ jsonData.set(encodedJsonText);
922
+ }
923
+ else {
924
+ var blankCharCode = "_".charCodeAt(0);
925
+ for (var i = 0; i < jsonLength; ++i) {
926
+ var charCode = jsonText.charCodeAt(i);
927
+ // if the character doesn't fit into a single UTF-16 code unit, just put a blank character
928
+ if (charCode != jsonText.codePointAt(i)) {
929
+ jsonData[i] = blankCharCode;
930
+ }
931
+ else {
932
+ jsonData[i] = charCode;
933
+ }
934
+ }
935
+ }
936
+ //json padding
937
+ var jsonPaddingView = new Uint8Array(jsonChunkBuffer, chunkLengthPrefix + jsonLength);
938
+ for (var i = 0; i < jsonPadding; ++i) {
939
+ jsonPaddingView[i] = 0x20;
940
+ }
941
+ //binary chunk
942
+ var binaryChunkBuffer = new ArrayBuffer(chunkLengthPrefix);
943
+ var binaryChunkBufferView = new DataView(binaryChunkBuffer);
944
+ binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + imageByteLength + imagePadding, true);
945
+ binaryChunkBufferView.setUint32(4, 0x004e4942, true);
946
+ // binary padding
947
+ var binPaddingBuffer = new ArrayBuffer(binPadding);
948
+ var binPaddingView = new Uint8Array(binPaddingBuffer);
949
+ for (var i = 0; i < binPadding; ++i) {
950
+ binPaddingView[i] = 0;
951
+ }
952
+ var imagePaddingBuffer = new ArrayBuffer(imagePadding);
953
+ var imagePaddingView = new Uint8Array(imagePaddingBuffer);
954
+ for (var i = 0; i < imagePadding; ++i) {
955
+ imagePaddingView[i] = 0;
956
+ }
957
+ var glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer];
958
+ // binary data
959
+ for (var i = 0; i < _this._orderedImageData.length; ++i) {
960
+ glbData.push(_this._orderedImageData[i].data.buffer);
961
+ }
962
+ glbData.push(binPaddingBuffer);
963
+ glbData.push(imagePaddingBuffer);
964
+ var glbFile = new Blob(glbData, { type: "application/octet-stream" });
965
+ var container = new GLTFData();
966
+ container.glTFFiles[glbFileName] = glbFile;
967
+ if (_this._localEngine != null) {
968
+ _this._localEngine.dispose();
969
+ }
970
+ if (dispose) {
971
+ _this.dispose();
972
+ }
973
+ return container;
974
+ });
975
+ };
976
+ /**
977
+ * Sets the TRS for each node
978
+ * @param node glTF Node for storing the transformation data
979
+ * @param babylonTransformNode Babylon mesh used as the source for the transformation data
980
+ * @param convertToRightHandedSystem Converts the values to right-handed
981
+ */
982
+ _Exporter.prototype._setNodeTransformation = function (node, babylonTransformNode, convertToRightHandedSystem) {
983
+ if (!babylonTransformNode.getPivotPoint().equalsToFloats(0, 0, 0)) {
984
+ Tools.Warn("Pivot points are not supported in the glTF serializer");
985
+ }
986
+ if (!babylonTransformNode.position.equalsToFloats(0, 0, 0)) {
987
+ node.translation = convertToRightHandedSystem
988
+ ? _GLTFUtilities._GetRightHandedPositionVector3(babylonTransformNode.position).asArray()
989
+ : babylonTransformNode.position.asArray();
990
+ }
991
+ if (!babylonTransformNode.scaling.equalsToFloats(1, 1, 1)) {
992
+ node.scale = babylonTransformNode.scaling.asArray();
993
+ }
994
+ var rotationQuaternion = Quaternion.RotationYawPitchRoll(babylonTransformNode.rotation.y, babylonTransformNode.rotation.x, babylonTransformNode.rotation.z);
995
+ if (babylonTransformNode.rotationQuaternion) {
996
+ rotationQuaternion.multiplyInPlace(babylonTransformNode.rotationQuaternion);
997
+ }
998
+ if (!Quaternion.IsIdentity(rotationQuaternion)) {
999
+ if (convertToRightHandedSystem) {
1000
+ _GLTFUtilities._GetRightHandedQuaternionFromRef(rotationQuaternion);
1001
+ }
1002
+ node.rotation = rotationQuaternion.normalize().asArray();
1003
+ }
1004
+ };
1005
+ _Exporter.prototype._setCameraTransformation = function (node, babylonCamera, convertToRightHandedSystem) {
1006
+ if (!babylonCamera.position.equalsToFloats(0, 0, 0)) {
1007
+ node.translation = convertToRightHandedSystem ? _GLTFUtilities._GetRightHandedPositionVector3(babylonCamera.position).asArray() : babylonCamera.position.asArray();
1008
+ }
1009
+ var rotationQuaternion = babylonCamera.absoluteRotation;
1010
+ if (!Quaternion.IsIdentity(rotationQuaternion)) {
1011
+ if (convertToRightHandedSystem) {
1012
+ _GLTFUtilities._GetRightHandedQuaternionFromRef(rotationQuaternion);
1013
+ }
1014
+ node.rotation = rotationQuaternion.normalize().asArray();
1015
+ }
1016
+ };
1017
+ _Exporter.prototype._getVertexBufferFromMesh = function (attributeKind, bufferMesh) {
1018
+ if (bufferMesh.isVerticesDataPresent(attributeKind)) {
1019
+ var vertexBuffer = bufferMesh.getVertexBuffer(attributeKind);
1020
+ if (vertexBuffer) {
1021
+ return vertexBuffer;
1022
+ }
1023
+ }
1024
+ return null;
1025
+ };
1026
+ /**
1027
+ * Creates a bufferview based on the vertices type for the Babylon mesh
1028
+ * @param kind Indicates the type of vertices data
1029
+ * @param attributeComponentKind Indicates the numerical type used to store the data
1030
+ * @param babylonTransformNode The Babylon mesh to get the vertices data from
1031
+ * @param binaryWriter The buffer to write the bufferview data to
1032
+ * @param byteStride
1033
+ * @param convertToRightHandedSystem Converts the values to right-handed
1034
+ */
1035
+ _Exporter.prototype._createBufferViewKind = function (kind, attributeComponentKind, babylonTransformNode, binaryWriter, byteStride, convertToRightHandedSystem) {
1036
+ var bufferMesh = babylonTransformNode instanceof Mesh
1037
+ ? babylonTransformNode
1038
+ : babylonTransformNode instanceof InstancedMesh
1039
+ ? babylonTransformNode.sourceMesh
1040
+ : null;
1041
+ if (bufferMesh) {
1042
+ var vertexBuffer = bufferMesh.getVertexBuffer(kind);
1043
+ var vertexData = bufferMesh.getVerticesData(kind);
1044
+ if (vertexBuffer && vertexData) {
1045
+ var typeByteLength = VertexBuffer.GetTypeByteLength(attributeComponentKind);
1046
+ var byteLength = vertexData.length * typeByteLength;
1047
+ var bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, kind + " - " + bufferMesh.name);
1048
+ this._bufferViews.push(bufferView);
1049
+ this._writeAttributeData(kind, attributeComponentKind, vertexData, byteStride / typeByteLength, binaryWriter, convertToRightHandedSystem, babylonTransformNode);
1050
+ }
1051
+ }
1052
+ };
1053
+ /**
1054
+ * Creates a bufferview based on the vertices type for the Babylon mesh
1055
+ * @param babylonSubMesh The Babylon submesh that the morph target is applied to
1056
+ * @param meshPrimitive
1057
+ * @param babylonMorphTarget the morph target to be exported
1058
+ * @param binaryWriter The buffer to write the bufferview data to
1059
+ * @param convertToRightHandedSystem Converts the values to right-handed
1060
+ */
1061
+ _Exporter.prototype._setMorphTargetAttributes = function (babylonSubMesh, meshPrimitive, babylonMorphTarget, binaryWriter, convertToRightHandedSystem) {
1062
+ if (babylonMorphTarget) {
1063
+ if (!meshPrimitive.targets) {
1064
+ meshPrimitive.targets = [];
1065
+ }
1066
+ var target = {};
1067
+ if (babylonMorphTarget.hasNormals) {
1068
+ var vertexNormals = babylonSubMesh.getMesh().getVerticesData(VertexBuffer.NormalKind);
1069
+ var morphNormals = babylonMorphTarget.getNormals();
1070
+ var count = babylonSubMesh.verticesCount;
1071
+ var byteStride = 12; // 3 x 4 byte floats
1072
+ var byteLength = count * byteStride;
1073
+ var bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_NORMAL");
1074
+ this._bufferViews.push(bufferView);
1075
+ var bufferViewIndex = this._bufferViews.length - 1;
1076
+ var accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "NORMAL", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
1077
+ this._accessors.push(accessor);
1078
+ target.NORMAL = this._accessors.length - 1;
1079
+ this.writeMorphTargetAttributeData(VertexBuffer.NormalKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexNormals, morphNormals, byteStride / 4, binaryWriter, convertToRightHandedSystem);
1080
+ }
1081
+ if (babylonMorphTarget.hasPositions) {
1082
+ var vertexPositions = babylonSubMesh.getMesh().getVerticesData(VertexBuffer.PositionKind);
1083
+ var morphPositions = babylonMorphTarget.getPositions();
1084
+ var count = babylonSubMesh.verticesCount;
1085
+ var byteStride = 12; // 3 x 4 byte floats
1086
+ var byteLength = count * byteStride;
1087
+ var bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_POSITION");
1088
+ this._bufferViews.push(bufferView);
1089
+ var bufferViewIndex = this._bufferViews.length - 1;
1090
+ var minMax = { min: new Vector3(Infinity, Infinity, Infinity), max: new Vector3(-Infinity, -Infinity, -Infinity) };
1091
+ var accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "POSITION", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
1092
+ this._accessors.push(accessor);
1093
+ target.POSITION = this._accessors.length - 1;
1094
+ this.writeMorphTargetAttributeData(VertexBuffer.PositionKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexPositions, morphPositions, byteStride / 4, binaryWriter, convertToRightHandedSystem, minMax);
1095
+ accessor.min = minMax.min.asArray();
1096
+ accessor.max = minMax.max.asArray();
1097
+ }
1098
+ if (babylonMorphTarget.hasTangents) {
1099
+ var vertexTangents = babylonSubMesh.getMesh().getVerticesData(VertexBuffer.TangentKind);
1100
+ var morphTangents = babylonMorphTarget.getTangents();
1101
+ var count = babylonSubMesh.verticesCount;
1102
+ var byteStride = 12; // 3 x 4 byte floats
1103
+ var byteLength = count * byteStride;
1104
+ var bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_NORMAL");
1105
+ this._bufferViews.push(bufferView);
1106
+ var bufferViewIndex = this._bufferViews.length - 1;
1107
+ var accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "TANGENT", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
1108
+ this._accessors.push(accessor);
1109
+ target.TANGENT = this._accessors.length - 1;
1110
+ this.writeMorphTargetAttributeData(VertexBuffer.TangentKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexTangents, morphTangents, byteStride / 4, binaryWriter, convertToRightHandedSystem);
1111
+ }
1112
+ meshPrimitive.targets.push(target);
1113
+ }
1114
+ };
1115
+ /**
1116
+ * The primitive mode of the Babylon mesh
1117
+ * @param babylonMesh The BabylonJS mesh
1118
+ */
1119
+ _Exporter.prototype._getMeshPrimitiveMode = function (babylonMesh) {
1120
+ if (babylonMesh instanceof LinesMesh) {
1121
+ return Material.LineListDrawMode;
1122
+ }
1123
+ return babylonMesh.material ? babylonMesh.material.fillMode : Material.TriangleFillMode;
1124
+ };
1125
+ /**
1126
+ * Sets the primitive mode of the glTF mesh primitive
1127
+ * @param meshPrimitive glTF mesh primitive
1128
+ * @param primitiveMode The primitive mode
1129
+ */
1130
+ _Exporter.prototype._setPrimitiveMode = function (meshPrimitive, primitiveMode) {
1131
+ switch (primitiveMode) {
1132
+ case Material.TriangleFillMode: {
1133
+ // glTF defaults to using Triangle Mode
1134
+ break;
1135
+ }
1136
+ case Material.TriangleStripDrawMode: {
1137
+ meshPrimitive.mode = 5 /* TRIANGLE_STRIP */;
1138
+ break;
1139
+ }
1140
+ case Material.TriangleFanDrawMode: {
1141
+ meshPrimitive.mode = 6 /* TRIANGLE_FAN */;
1142
+ break;
1143
+ }
1144
+ case Material.PointListDrawMode: {
1145
+ meshPrimitive.mode = 0 /* POINTS */;
1146
+ break;
1147
+ }
1148
+ case Material.PointFillMode: {
1149
+ meshPrimitive.mode = 0 /* POINTS */;
1150
+ break;
1151
+ }
1152
+ case Material.LineLoopDrawMode: {
1153
+ meshPrimitive.mode = 2 /* LINE_LOOP */;
1154
+ break;
1155
+ }
1156
+ case Material.LineListDrawMode: {
1157
+ meshPrimitive.mode = 1 /* LINES */;
1158
+ break;
1159
+ }
1160
+ case Material.LineStripDrawMode: {
1161
+ meshPrimitive.mode = 3 /* LINE_STRIP */;
1162
+ break;
1163
+ }
1164
+ }
1165
+ };
1166
+ /**
1167
+ * Sets the vertex attribute accessor based of the glTF mesh primitive
1168
+ * @param meshPrimitive glTF mesh primitive
1169
+ * @param attributeKind vertex attribute
1170
+ * @returns boolean specifying if uv coordinates are present
1171
+ */
1172
+ _Exporter.prototype._setAttributeKind = function (meshPrimitive, attributeKind) {
1173
+ switch (attributeKind) {
1174
+ case VertexBuffer.PositionKind: {
1175
+ meshPrimitive.attributes.POSITION = this._accessors.length - 1;
1176
+ break;
1177
+ }
1178
+ case VertexBuffer.NormalKind: {
1179
+ meshPrimitive.attributes.NORMAL = this._accessors.length - 1;
1180
+ break;
1181
+ }
1182
+ case VertexBuffer.ColorKind: {
1183
+ meshPrimitive.attributes.COLOR_0 = this._accessors.length - 1;
1184
+ break;
1185
+ }
1186
+ case VertexBuffer.TangentKind: {
1187
+ meshPrimitive.attributes.TANGENT = this._accessors.length - 1;
1188
+ break;
1189
+ }
1190
+ case VertexBuffer.UVKind: {
1191
+ meshPrimitive.attributes.TEXCOORD_0 = this._accessors.length - 1;
1192
+ break;
1193
+ }
1194
+ case VertexBuffer.UV2Kind: {
1195
+ meshPrimitive.attributes.TEXCOORD_1 = this._accessors.length - 1;
1196
+ break;
1197
+ }
1198
+ case VertexBuffer.MatricesIndicesKind: {
1199
+ meshPrimitive.attributes.JOINTS_0 = this._accessors.length - 1;
1200
+ break;
1201
+ }
1202
+ case VertexBuffer.MatricesIndicesExtraKind: {
1203
+ meshPrimitive.attributes.JOINTS_1 = this._accessors.length - 1;
1204
+ break;
1205
+ }
1206
+ case VertexBuffer.MatricesWeightsKind: {
1207
+ meshPrimitive.attributes.WEIGHTS_0 = this._accessors.length - 1;
1208
+ break;
1209
+ }
1210
+ case VertexBuffer.MatricesWeightsExtraKind: {
1211
+ meshPrimitive.attributes.WEIGHTS_1 = this._accessors.length - 1;
1212
+ break;
1213
+ }
1214
+ default: {
1215
+ Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
1216
+ }
1217
+ }
1218
+ };
1219
+ /**
1220
+ * Sets data for the primitive attributes of each submesh
1221
+ * @param mesh glTF Mesh object to store the primitive attribute information
1222
+ * @param babylonTransformNode Babylon mesh to get the primitive attribute data from
1223
+ * @param binaryWriter Buffer to write the attribute data to
1224
+ * @param convertToRightHandedSystem Converts the values to right-handed
1225
+ */
1226
+ _Exporter.prototype._setPrimitiveAttributesAsync = function (mesh, babylonTransformNode, binaryWriter, convertToRightHandedSystem) {
1227
+ var _a;
1228
+ var promises = [];
1229
+ var bufferMesh = null;
1230
+ var bufferView;
1231
+ var minMax;
1232
+ if (babylonTransformNode instanceof Mesh) {
1233
+ bufferMesh = babylonTransformNode;
1234
+ }
1235
+ else if (babylonTransformNode instanceof InstancedMesh) {
1236
+ bufferMesh = babylonTransformNode.sourceMesh;
1237
+ }
1238
+ var attributeData = [
1239
+ { kind: VertexBuffer.PositionKind, accessorType: "VEC3" /* VEC3 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 12 },
1240
+ { kind: VertexBuffer.NormalKind, accessorType: "VEC3" /* VEC3 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 12 },
1241
+ { kind: VertexBuffer.ColorKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 16 },
1242
+ { kind: VertexBuffer.TangentKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 16 },
1243
+ { kind: VertexBuffer.UVKind, accessorType: "VEC2" /* VEC2 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 8 },
1244
+ { kind: VertexBuffer.UV2Kind, accessorType: "VEC2" /* VEC2 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 8 },
1245
+ { kind: VertexBuffer.MatricesIndicesKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5123 /* UNSIGNED_SHORT */, byteStride: 8 },
1246
+ { kind: VertexBuffer.MatricesIndicesExtraKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5123 /* UNSIGNED_SHORT */, byteStride: 8 },
1247
+ { kind: VertexBuffer.MatricesWeightsKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 16 },
1248
+ { kind: VertexBuffer.MatricesWeightsExtraKind, accessorType: "VEC4" /* VEC4 */, accessorComponentType: 5126 /* FLOAT */, byteStride: 16 },
1249
+ ];
1250
+ if (bufferMesh) {
1251
+ var indexBufferViewIndex = null;
1252
+ var primitiveMode = this._getMeshPrimitiveMode(bufferMesh);
1253
+ var vertexAttributeBufferViews = {};
1254
+ var morphTargetManager = bufferMesh.morphTargetManager;
1255
+ // For each BabylonMesh, create bufferviews for each 'kind'
1256
+ for (var _i = 0, attributeData_1 = attributeData; _i < attributeData_1.length; _i++) {
1257
+ var attribute = attributeData_1[_i];
1258
+ var attributeKind = attribute.kind;
1259
+ var attributeComponentKind = attribute.accessorComponentType;
1260
+ if (bufferMesh.isVerticesDataPresent(attributeKind)) {
1261
+ var vertexBuffer = this._getVertexBufferFromMesh(attributeKind, bufferMesh);
1262
+ attribute.byteStride = vertexBuffer
1263
+ ? vertexBuffer.getSize() * VertexBuffer.GetTypeByteLength(attribute.accessorComponentType)
1264
+ : VertexBuffer.DeduceStride(attributeKind) * 4;
1265
+ if (attribute.byteStride === 12) {
1266
+ attribute.accessorType = "VEC3" /* VEC3 */;
1267
+ }
1268
+ this._createBufferViewKind(attributeKind, attributeComponentKind, babylonTransformNode, binaryWriter, attribute.byteStride, convertToRightHandedSystem);
1269
+ attribute.bufferViewIndex = this._bufferViews.length - 1;
1270
+ vertexAttributeBufferViews[attributeKind] = attribute.bufferViewIndex;
1271
+ }
1272
+ }
1273
+ if (bufferMesh.getTotalIndices()) {
1274
+ var indices = bufferMesh.getIndices();
1275
+ if (indices) {
1276
+ var byteLength = indices.length * 4;
1277
+ bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, undefined, "Indices - " + bufferMesh.name);
1278
+ this._bufferViews.push(bufferView);
1279
+ indexBufferViewIndex = this._bufferViews.length - 1;
1280
+ for (var k = 0, length_9 = indices.length; k < length_9; ++k) {
1281
+ binaryWriter.setUInt32(indices[k]);
1282
+ }
1283
+ }
1284
+ }
1285
+ if (bufferMesh.subMeshes) {
1286
+ // go through all mesh primitives (submeshes)
1287
+ for (var _b = 0, _c = bufferMesh.subMeshes; _b < _c.length; _b++) {
1288
+ var submesh = _c[_b];
1289
+ var babylonMaterial = submesh.getMaterial() || bufferMesh.getScene().defaultMaterial;
1290
+ var materialIndex = null;
1291
+ if (babylonMaterial) {
1292
+ if (bufferMesh instanceof LinesMesh) {
1293
+ // get the color from the lines mesh and set it in the material
1294
+ var material = {
1295
+ name: bufferMesh.name + " material",
1296
+ };
1297
+ if (!bufferMesh.color.equals(Color3.White()) || bufferMesh.alpha < 1) {
1298
+ material.pbrMetallicRoughness = {
1299
+ baseColorFactor: bufferMesh.color.asArray().concat([bufferMesh.alpha]),
1300
+ };
1301
+ }
1302
+ this._materials.push(material);
1303
+ materialIndex = this._materials.length - 1;
1304
+ }
1305
+ else if (babylonMaterial instanceof MultiMaterial) {
1306
+ var subMaterial = babylonMaterial.subMaterials[submesh.materialIndex];
1307
+ if (subMaterial) {
1308
+ babylonMaterial = subMaterial;
1309
+ materialIndex = this._materialMap[babylonMaterial.uniqueId];
1310
+ }
1311
+ }
1312
+ else {
1313
+ materialIndex = this._materialMap[babylonMaterial.uniqueId];
1314
+ }
1315
+ }
1316
+ var glTFMaterial = materialIndex != null ? this._materials[materialIndex] : null;
1317
+ var meshPrimitive = { attributes: {} };
1318
+ this._setPrimitiveMode(meshPrimitive, primitiveMode);
1319
+ for (var _d = 0, attributeData_2 = attributeData; _d < attributeData_2.length; _d++) {
1320
+ var attribute = attributeData_2[_d];
1321
+ var attributeKind = attribute.kind;
1322
+ if ((attributeKind === VertexBuffer.UVKind || attributeKind === VertexBuffer.UV2Kind) && !this._options.exportUnusedUVs) {
1323
+ if (!glTFMaterial || !this._glTFMaterialExporter._hasTexturesPresent(glTFMaterial)) {
1324
+ continue;
1325
+ }
1326
+ }
1327
+ var vertexData = bufferMesh.getVerticesData(attributeKind);
1328
+ if (vertexData) {
1329
+ var vertexBuffer = this._getVertexBufferFromMesh(attributeKind, bufferMesh);
1330
+ if (vertexBuffer) {
1331
+ var stride = vertexBuffer.getSize();
1332
+ var bufferViewIndex = attribute.bufferViewIndex;
1333
+ if (bufferViewIndex != undefined) {
1334
+ // check to see if bufferviewindex has a numeric value assigned.
1335
+ minMax = { min: null, max: null };
1336
+ if (attributeKind == VertexBuffer.PositionKind) {
1337
+ minMax = _GLTFUtilities._CalculateMinMaxPositions(vertexData, 0, vertexData.length / stride, convertToRightHandedSystem);
1338
+ }
1339
+ var accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, attributeKind + " - " + babylonTransformNode.name, attribute.accessorType, attribute.accessorComponentType, vertexData.length / stride, 0, minMax.min, minMax.max);
1340
+ this._accessors.push(accessor);
1341
+ this._setAttributeKind(meshPrimitive, attributeKind);
1342
+ }
1343
+ }
1344
+ }
1345
+ }
1346
+ if (indexBufferViewIndex) {
1347
+ // Create accessor
1348
+ var accessor = _GLTFUtilities._CreateAccessor(indexBufferViewIndex, "indices - " + babylonTransformNode.name, "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4, null, null);
1349
+ this._accessors.push(accessor);
1350
+ meshPrimitive.indices = this._accessors.length - 1;
1351
+ }
1352
+ if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
1353
+ var sideOrientation = bufferMesh.overrideMaterialSideOrientation !== null ? bufferMesh.overrideMaterialSideOrientation : babylonMaterial.sideOrientation;
1354
+ if ((sideOrientation == Material.ClockWiseSideOrientation && this._babylonScene.useRightHandedSystem) ||
1355
+ (sideOrientation == Material.ClockWiseSideOrientation &&
1356
+ convertToRightHandedSystem &&
1357
+ bufferMesh.overrideMaterialSideOrientation !== ((_a = bufferMesh.material) === null || _a === void 0 ? void 0 : _a.sideOrientation))) {
1358
+ var byteOffset = indexBufferViewIndex != null ? this._bufferViews[indexBufferViewIndex].byteOffset : null;
1359
+ if (byteOffset == null) {
1360
+ byteOffset = 0;
1361
+ }
1362
+ var babylonIndices = null;
1363
+ if (indexBufferViewIndex != null) {
1364
+ babylonIndices = bufferMesh.getIndices();
1365
+ }
1366
+ if (babylonIndices) {
1367
+ this._reorderIndicesBasedOnPrimitiveMode(submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter);
1368
+ }
1369
+ else {
1370
+ for (var _e = 0, attributeData_3 = attributeData; _e < attributeData_3.length; _e++) {
1371
+ var attribute = attributeData_3[_e];
1372
+ var vertexData = bufferMesh.getVerticesData(attribute.kind);
1373
+ if (vertexData) {
1374
+ var byteOffset_1 = this._bufferViews[vertexAttributeBufferViews[attribute.kind]].byteOffset;
1375
+ if (!byteOffset_1) {
1376
+ byteOffset_1 = 0;
1377
+ }
1378
+ this._reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData, byteOffset_1, binaryWriter, convertToRightHandedSystem);
1379
+ }
1380
+ }
1381
+ }
1382
+ }
1383
+ meshPrimitive.material = materialIndex;
1384
+ }
1385
+ if (morphTargetManager) {
1386
+ var target = void 0;
1387
+ for (var i = 0; i < morphTargetManager.numTargets; ++i) {
1388
+ target = morphTargetManager.getTarget(i);
1389
+ this._setMorphTargetAttributes(submesh, meshPrimitive, target, binaryWriter, convertToRightHandedSystem);
1390
+ }
1391
+ }
1392
+ mesh.primitives.push(meshPrimitive);
1393
+ this._extensionsPostExportMeshPrimitiveAsync("postExport", meshPrimitive, submesh, binaryWriter);
1394
+ promises.push();
1395
+ }
1396
+ }
1397
+ }
1398
+ return Promise.all(promises).then(function () {
1399
+ /* do nothing */
1400
+ });
1401
+ };
1402
+ /**
1403
+ * Check if the node is used to convert its descendants from a right handed coordinate system to the Babylon scene's coordinate system.
1404
+ * @param node The node to check
1405
+ * @returns True if the node is used to convert its descendants from right-handed to left-handed. False otherwise
1406
+ */
1407
+ _Exporter.prototype._isBabylonCoordinateSystemConvertingNode = function (node) {
1408
+ if (node instanceof TransformNode) {
1409
+ if (node.name !== "__root__") {
1410
+ return false;
1411
+ }
1412
+ // Transform
1413
+ var matrix = node.getWorldMatrix();
1414
+ if (matrix.determinant() === 1) {
1415
+ return false;
1416
+ }
1417
+ // Geometry
1418
+ if ((node instanceof Mesh && node.geometry !== null) || (node instanceof InstancedMesh && node.sourceMesh.geometry !== null)) {
1419
+ return false;
1420
+ }
1421
+ if (this._includeCoordinateSystemConversionNodes) {
1422
+ return false;
1423
+ }
1424
+ return true;
1425
+ }
1426
+ return false;
1427
+ };
1428
+ /**
1429
+ * Creates a glTF scene based on the array of meshes
1430
+ * Returns the the total byte offset
1431
+ * @param babylonScene Babylon scene to get the mesh data from
1432
+ * @param binaryWriter Buffer to write binary data to
1433
+ */
1434
+ _Exporter.prototype._createSceneAsync = function (babylonScene, binaryWriter) {
1435
+ var _this = this;
1436
+ var scene = { nodes: [] };
1437
+ var glTFNodeIndex;
1438
+ var glTFNode;
1439
+ var directDescendents;
1440
+ var nodes = __spreadArray(__spreadArray(__spreadArray(__spreadArray([], babylonScene.transformNodes, true), babylonScene.meshes, true), babylonScene.lights, true), babylonScene.cameras, true);
1441
+ var rootNodesToLeftHanded = [];
1442
+ this._convertToRightHandedSystem = !babylonScene.useRightHandedSystem;
1443
+ this._convertToRightHandedSystemMap = {};
1444
+ // Set default values for all nodes
1445
+ babylonScene.rootNodes.forEach(function (rootNode) {
1446
+ _this._convertToRightHandedSystemMap[rootNode.uniqueId] = _this._convertToRightHandedSystem;
1447
+ rootNode.getDescendants(false).forEach(function (descendant) {
1448
+ _this._convertToRightHandedSystemMap[descendant.uniqueId] = _this._convertToRightHandedSystem;
1449
+ });
1450
+ });
1451
+ // Check if root nodes converting to left-handed are present
1452
+ babylonScene.rootNodes.forEach(function (rootNode) {
1453
+ if (_this._isBabylonCoordinateSystemConvertingNode(rootNode)) {
1454
+ rootNodesToLeftHanded.push(rootNode);
1455
+ // Exclude the node from list of nodes to export
1456
+ var indexRootNode = nodes.indexOf(rootNode);
1457
+ if (indexRootNode !== -1) {
1458
+ // should always be true
1459
+ nodes.splice(indexRootNode, 1);
1460
+ }
1461
+ // Cancel conversion to right handed system
1462
+ rootNode.getDescendants(false).forEach(function (descendant) {
1463
+ _this._convertToRightHandedSystemMap[descendant.uniqueId] = false;
1464
+ });
1465
+ }
1466
+ });
1467
+ // Export babylon cameras to glTFCamera
1468
+ var cameraMap = new Map();
1469
+ babylonScene.cameras.forEach(function (camera) {
1470
+ if (!_this._options.shouldExportNode || _this._options.shouldExportNode(camera)) {
1471
+ var glTFCamera = {
1472
+ type: camera.mode === Camera.PERSPECTIVE_CAMERA ? "perspective" /* PERSPECTIVE */ : "orthographic" /* ORTHOGRAPHIC */,
1473
+ };
1474
+ if (camera.name) {
1475
+ glTFCamera.name = camera.name;
1476
+ }
1477
+ if (glTFCamera.type === "perspective" /* PERSPECTIVE */) {
1478
+ glTFCamera.perspective = {
1479
+ aspectRatio: camera.getEngine().getAspectRatio(camera),
1480
+ yfov: camera.fovMode === Camera.FOVMODE_VERTICAL_FIXED ? camera.fov : camera.fov * camera.getEngine().getAspectRatio(camera),
1481
+ znear: camera.minZ,
1482
+ zfar: camera.maxZ,
1483
+ };
1484
+ }
1485
+ else if (glTFCamera.type === "orthographic" /* ORTHOGRAPHIC */) {
1486
+ var halfWidth = camera.orthoLeft && camera.orthoRight ? 0.5 * (camera.orthoRight - camera.orthoLeft) : camera.getEngine().getRenderWidth() * 0.5;
1487
+ var halfHeight = camera.orthoBottom && camera.orthoTop ? 0.5 * (camera.orthoTop - camera.orthoBottom) : camera.getEngine().getRenderHeight() * 0.5;
1488
+ glTFCamera.orthographic = {
1489
+ xmag: halfWidth,
1490
+ ymag: halfHeight,
1491
+ znear: camera.minZ,
1492
+ zfar: camera.maxZ,
1493
+ };
1494
+ }
1495
+ cameraMap.set(camera, _this._cameras.length);
1496
+ _this._cameras.push(glTFCamera);
1497
+ }
1498
+ });
1499
+ var _a = this._getExportNodes(nodes), exportNodes = _a[0], exportMaterials = _a[1];
1500
+ return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(exportMaterials, "image/png" /* PNG */, true).then(function () {
1501
+ return _this._createNodeMapAndAnimationsAsync(babylonScene, exportNodes, binaryWriter).then(function (nodeMap) {
1502
+ return _this._createSkinsAsync(babylonScene, nodeMap, binaryWriter).then(function (skinMap) {
1503
+ _this._nodeMap = nodeMap;
1504
+ _this._totalByteLength = binaryWriter.getByteOffset();
1505
+ if (_this._totalByteLength == undefined) {
1506
+ throw new Error("undefined byte length!");
1507
+ }
1508
+ // Build Hierarchy with the node map.
1509
+ for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
1510
+ var babylonNode = nodes_1[_i];
1511
+ glTFNodeIndex = _this._nodeMap[babylonNode.uniqueId];
1512
+ if (glTFNodeIndex !== undefined) {
1513
+ glTFNode = _this._nodes[glTFNodeIndex];
1514
+ if (babylonNode.metadata) {
1515
+ if (_this._options.metadataSelector) {
1516
+ glTFNode.extras = _this._options.metadataSelector(babylonNode.metadata);
1517
+ }
1518
+ else if (babylonNode.metadata.gltf) {
1519
+ glTFNode.extras = babylonNode.metadata.gltf.extras;
1520
+ }
1521
+ }
1522
+ if (babylonNode instanceof Camera) {
1523
+ glTFNode.camera = cameraMap.get(babylonNode);
1524
+ }
1525
+ if (!babylonNode.parent || rootNodesToLeftHanded.indexOf(babylonNode.parent) !== -1) {
1526
+ if (_this._options.shouldExportNode && !_this._options.shouldExportNode(babylonNode)) {
1527
+ Tools.Log("Omitting " + babylonNode.name + " from scene.");
1528
+ }
1529
+ else {
1530
+ var convertToRightHandedSystem = _this._convertToRightHandedSystemMap[babylonNode.uniqueId];
1531
+ if (convertToRightHandedSystem) {
1532
+ if (glTFNode.translation) {
1533
+ glTFNode.translation[2] *= -1;
1534
+ glTFNode.translation[0] *= -1;
1535
+ }
1536
+ glTFNode.rotation = glTFNode.rotation
1537
+ ? Quaternion.FromArray([0, 1, 0, 0]).multiply(Quaternion.FromArray(glTFNode.rotation)).asArray()
1538
+ : Quaternion.FromArray([0, 1, 0, 0]).asArray();
1539
+ }
1540
+ scene.nodes.push(glTFNodeIndex);
1541
+ }
1542
+ }
1543
+ if (babylonNode instanceof Mesh) {
1544
+ var babylonMesh = babylonNode;
1545
+ if (babylonMesh.skeleton) {
1546
+ glTFNode.skin = skinMap[babylonMesh.skeleton.uniqueId];
1547
+ }
1548
+ }
1549
+ directDescendents = babylonNode.getDescendants(true);
1550
+ if (!glTFNode.children && directDescendents && directDescendents.length) {
1551
+ var children = [];
1552
+ for (var _a = 0, directDescendents_1 = directDescendents; _a < directDescendents_1.length; _a++) {
1553
+ var descendent = directDescendents_1[_a];
1554
+ if (_this._nodeMap[descendent.uniqueId] != null) {
1555
+ children.push(_this._nodeMap[descendent.uniqueId]);
1556
+ }
1557
+ }
1558
+ if (children.length) {
1559
+ glTFNode.children = children;
1560
+ }
1561
+ }
1562
+ }
1563
+ }
1564
+ if (scene.nodes.length) {
1565
+ _this._scenes.push(scene);
1566
+ }
1567
+ });
1568
+ });
1569
+ });
1570
+ };
1571
+ /**
1572
+ * Getting the nodes and materials that would be exported.
1573
+ * @param nodes Babylon transform nodes
1574
+ * @returns Array of nodes which would be exported.
1575
+ * @returns Set of materials which would be exported.
1576
+ */
1577
+ _Exporter.prototype._getExportNodes = function (nodes) {
1578
+ var exportNodes = [];
1579
+ var exportMaterials = new Set();
1580
+ for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
1581
+ var babylonNode = nodes_2[_i];
1582
+ if (!this._options.shouldExportNode || this._options.shouldExportNode(babylonNode)) {
1583
+ exportNodes.push(babylonNode);
1584
+ if (babylonNode instanceof AbstractMesh) {
1585
+ var material = babylonNode.material || babylonNode.getScene().defaultMaterial;
1586
+ if (material instanceof MultiMaterial) {
1587
+ for (var _a = 0, _b = material.subMaterials; _a < _b.length; _a++) {
1588
+ var subMaterial = _b[_a];
1589
+ if (subMaterial) {
1590
+ exportMaterials.add(subMaterial);
1591
+ }
1592
+ }
1593
+ }
1594
+ else {
1595
+ exportMaterials.add(material);
1596
+ }
1597
+ }
1598
+ }
1599
+ else {
1600
+ "Excluding node ".concat(babylonNode.name);
1601
+ }
1602
+ }
1603
+ return [exportNodes, exportMaterials];
1604
+ };
1605
+ /**
1606
+ * Creates a mapping of Node unique id to node index and handles animations
1607
+ * @param babylonScene Babylon Scene
1608
+ * @param nodes Babylon transform nodes
1609
+ * @param binaryWriter Buffer to write binary data to
1610
+ * @returns Node mapping of unique id to index
1611
+ */
1612
+ _Exporter.prototype._createNodeMapAndAnimationsAsync = function (babylonScene, nodes, binaryWriter) {
1613
+ var _this = this;
1614
+ var promiseChain = Promise.resolve();
1615
+ var nodeMap = {};
1616
+ var nodeIndex;
1617
+ var runtimeGLTFAnimation = {
1618
+ name: "runtime animations",
1619
+ channels: [],
1620
+ samplers: [],
1621
+ };
1622
+ var idleGLTFAnimations = [];
1623
+ var _loop_1 = function (babylonNode) {
1624
+ promiseChain = promiseChain.then(function () {
1625
+ var convertToRightHandedSystem = _this._convertToRightHandedSystemMap[babylonNode.uniqueId];
1626
+ return _this._createNodeAsync(babylonNode, binaryWriter, convertToRightHandedSystem).then(function (node) {
1627
+ var promise = _this._extensionsPostExportNodeAsync("createNodeAsync", node, babylonNode, nodeMap);
1628
+ if (promise == null) {
1629
+ Tools.Warn("Not exporting node ".concat(babylonNode.name));
1630
+ return Promise.resolve();
1631
+ }
1632
+ else {
1633
+ return promise.then(function (node) {
1634
+ if (!node) {
1635
+ return;
1636
+ }
1637
+ _this._nodes.push(node);
1638
+ nodeIndex = _this._nodes.length - 1;
1639
+ nodeMap[babylonNode.uniqueId] = nodeIndex;
1640
+ if (!babylonScene.animationGroups.length) {
1641
+ _GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, convertToRightHandedSystem, _this._animationSampleRate);
1642
+ if (babylonNode.animations.length) {
1643
+ _GLTFAnimation._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, convertToRightHandedSystem, _this._animationSampleRate);
1644
+ }
1645
+ }
1646
+ });
1647
+ }
1648
+ });
1649
+ });
1650
+ };
1651
+ for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) {
1652
+ var babylonNode = nodes_3[_i];
1653
+ _loop_1(babylonNode);
1654
+ }
1655
+ return promiseChain.then(function () {
1656
+ if (runtimeGLTFAnimation.channels.length && runtimeGLTFAnimation.samplers.length) {
1657
+ _this._animations.push(runtimeGLTFAnimation);
1658
+ }
1659
+ idleGLTFAnimations.forEach(function (idleGLTFAnimation) {
1660
+ if (idleGLTFAnimation.channels.length && idleGLTFAnimation.samplers.length) {
1661
+ _this._animations.push(idleGLTFAnimation);
1662
+ }
1663
+ });
1664
+ if (babylonScene.animationGroups.length) {
1665
+ _GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(babylonScene, _this._animations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._convertToRightHandedSystemMap, _this._animationSampleRate);
1666
+ }
1667
+ return nodeMap;
1668
+ });
1669
+ };
1670
+ /**
1671
+ * Creates a glTF node from a Babylon mesh
1672
+ * @param babylonNode Source Babylon mesh
1673
+ * @param binaryWriter Buffer for storing geometry data
1674
+ * @param convertToRightHandedSystem Converts the values to right-handed
1675
+ * @returns glTF node
1676
+ */
1677
+ _Exporter.prototype._createNodeAsync = function (babylonNode, binaryWriter, convertToRightHandedSystem) {
1678
+ var _this = this;
1679
+ return Promise.resolve().then(function () {
1680
+ // create node to hold translation/rotation/scale and the mesh
1681
+ var node = {};
1682
+ // create mesh
1683
+ var mesh = { primitives: [] };
1684
+ if (babylonNode.name) {
1685
+ node.name = babylonNode.name;
1686
+ }
1687
+ if (babylonNode instanceof TransformNode) {
1688
+ // Set transformation
1689
+ _this._setNodeTransformation(node, babylonNode, convertToRightHandedSystem);
1690
+ if (babylonNode instanceof Mesh) {
1691
+ var morphTargetManager = babylonNode.morphTargetManager;
1692
+ if (morphTargetManager && morphTargetManager.numTargets > 0) {
1693
+ mesh.weights = [];
1694
+ for (var i = 0; i < morphTargetManager.numTargets; ++i) {
1695
+ mesh.weights.push(morphTargetManager.getTarget(i).influence);
1696
+ }
1697
+ }
1698
+ }
1699
+ return _this._setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter, convertToRightHandedSystem).then(function () {
1700
+ if (mesh.primitives.length) {
1701
+ _this._meshes.push(mesh);
1702
+ node.mesh = _this._meshes.length - 1;
1703
+ }
1704
+ return node;
1705
+ });
1706
+ }
1707
+ else if (babylonNode instanceof Camera) {
1708
+ _this._setCameraTransformation(node, babylonNode, convertToRightHandedSystem);
1709
+ return node;
1710
+ }
1711
+ else {
1712
+ return node;
1713
+ }
1714
+ });
1715
+ };
1716
+ /**
1717
+ * Creates a glTF skin from a Babylon skeleton
1718
+ * @param babylonScene Babylon Scene
1719
+ * @param nodeMap Babylon transform nodes
1720
+ * @param binaryWriter Buffer to write binary data to
1721
+ * @returns Node mapping of unique id to index
1722
+ */
1723
+ _Exporter.prototype._createSkinsAsync = function (babylonScene, nodeMap, binaryWriter) {
1724
+ var _a;
1725
+ var promiseChain = Promise.resolve();
1726
+ var skinMap = {};
1727
+ for (var _i = 0, _b = babylonScene.skeletons; _i < _b.length; _i++) {
1728
+ var skeleton = _b[_i];
1729
+ // create skin
1730
+ var skin = { joints: [] };
1731
+ var inverseBindMatrices = [];
1732
+ var boneIndexMap = {};
1733
+ var maxBoneIndex = -1;
1734
+ for (var i = 0; i < skeleton.bones.length; ++i) {
1735
+ var bone = skeleton.bones[i];
1736
+ var boneIndex = (_a = bone.getIndex()) !== null && _a !== void 0 ? _a : i;
1737
+ if (boneIndex !== -1) {
1738
+ boneIndexMap[boneIndex] = bone;
1739
+ if (boneIndex > maxBoneIndex) {
1740
+ maxBoneIndex = boneIndex;
1741
+ }
1742
+ }
1743
+ }
1744
+ for (var boneIndex = 0; boneIndex <= maxBoneIndex; ++boneIndex) {
1745
+ var bone = boneIndexMap[boneIndex];
1746
+ inverseBindMatrices.push(bone.getInvertedAbsoluteTransform());
1747
+ var transformNode = bone.getTransformNode();
1748
+ if (transformNode) {
1749
+ skin.joints.push(nodeMap[transformNode.uniqueId]);
1750
+ }
1751
+ else {
1752
+ Tools.Warn("Exporting a bone without a linked transform node is currently unsupported");
1753
+ }
1754
+ }
1755
+ // create buffer view for inverse bind matrices
1756
+ var byteStride = 64; // 4 x 4 matrix of 32 bit float
1757
+ var byteLength = inverseBindMatrices.length * byteStride;
1758
+ var bufferViewOffset = binaryWriter.getByteOffset();
1759
+ var bufferView = _GLTFUtilities._CreateBufferView(0, bufferViewOffset, byteLength, undefined, "InverseBindMatrices" + " - " + skeleton.name);
1760
+ this._bufferViews.push(bufferView);
1761
+ var bufferViewIndex = this._bufferViews.length - 1;
1762
+ var bindMatrixAccessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, "InverseBindMatrices" + " - " + skeleton.name, "MAT4" /* MAT4 */, 5126 /* FLOAT */, inverseBindMatrices.length, null, null, null);
1763
+ var inverseBindAccessorIndex = this._accessors.push(bindMatrixAccessor) - 1;
1764
+ skin.inverseBindMatrices = inverseBindAccessorIndex;
1765
+ this._skins.push(skin);
1766
+ skinMap[skeleton.uniqueId] = this._skins.length - 1;
1767
+ inverseBindMatrices.forEach(function (mat) {
1768
+ mat.m.forEach(function (cell) {
1769
+ binaryWriter.setFloat32(cell);
1770
+ });
1771
+ });
1772
+ }
1773
+ return promiseChain.then(function () {
1774
+ return skinMap;
1775
+ });
1776
+ };
1777
+ _Exporter._ExtensionNames = new Array();
1778
+ _Exporter._ExtensionFactories = {};
1779
+ return _Exporter;
1780
+ }());
1781
+ export { _Exporter };
1782
+ /**
1783
+ * @hidden
1784
+ *
1785
+ * Stores glTF binary data. If the array buffer byte length is exceeded, it doubles in size dynamically
1786
+ */
1787
+ var _BinaryWriter = /** @class */ (function () {
1788
+ /**
1789
+ * Initialize binary writer with an initial byte length
1790
+ * @param byteLength Initial byte length of the array buffer
1791
+ */
1792
+ function _BinaryWriter(byteLength) {
1793
+ this._arrayBuffer = new ArrayBuffer(byteLength);
1794
+ this._dataView = new DataView(this._arrayBuffer);
1795
+ this._byteOffset = 0;
1796
+ }
1797
+ /**
1798
+ * Resize the array buffer to the specified byte length
1799
+ * @param byteLength
1800
+ */
1801
+ _BinaryWriter.prototype._resizeBuffer = function (byteLength) {
1802
+ var newBuffer = new ArrayBuffer(byteLength);
1803
+ var oldUint8Array = new Uint8Array(this._arrayBuffer);
1804
+ var newUint8Array = new Uint8Array(newBuffer);
1805
+ for (var i = 0, length_10 = newUint8Array.byteLength; i < length_10; ++i) {
1806
+ newUint8Array[i] = oldUint8Array[i];
1807
+ }
1808
+ this._arrayBuffer = newBuffer;
1809
+ this._dataView = new DataView(this._arrayBuffer);
1810
+ return newBuffer;
1811
+ };
1812
+ /**
1813
+ * Get an array buffer with the length of the byte offset
1814
+ * @returns ArrayBuffer resized to the byte offset
1815
+ */
1816
+ _BinaryWriter.prototype.getArrayBuffer = function () {
1817
+ return this._resizeBuffer(this.getByteOffset());
1818
+ };
1819
+ /**
1820
+ * Get the byte offset of the array buffer
1821
+ * @returns byte offset
1822
+ */
1823
+ _BinaryWriter.prototype.getByteOffset = function () {
1824
+ if (this._byteOffset == undefined) {
1825
+ throw new Error("Byte offset is undefined!");
1826
+ }
1827
+ return this._byteOffset;
1828
+ };
1829
+ /**
1830
+ * Stores an UInt8 in the array buffer
1831
+ * @param entry
1832
+ * @param byteOffset If defined, specifies where to set the value as an offset.
1833
+ */
1834
+ _BinaryWriter.prototype.setUInt8 = function (entry, byteOffset) {
1835
+ if (byteOffset != null) {
1836
+ if (byteOffset < this._byteOffset) {
1837
+ this._dataView.setUint8(byteOffset, entry);
1838
+ }
1839
+ else {
1840
+ Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1841
+ }
1842
+ }
1843
+ else {
1844
+ if (this._byteOffset + 1 > this._arrayBuffer.byteLength) {
1845
+ this._resizeBuffer(this._arrayBuffer.byteLength * 2);
1846
+ }
1847
+ this._dataView.setUint8(this._byteOffset, entry);
1848
+ this._byteOffset += 1;
1849
+ }
1850
+ };
1851
+ /**
1852
+ * Stores an UInt16 in the array buffer
1853
+ * @param entry
1854
+ * @param byteOffset If defined, specifies where to set the value as an offset.
1855
+ */
1856
+ _BinaryWriter.prototype.setUInt16 = function (entry, byteOffset) {
1857
+ if (byteOffset != null) {
1858
+ if (byteOffset < this._byteOffset) {
1859
+ this._dataView.setUint16(byteOffset, entry, true);
1860
+ }
1861
+ else {
1862
+ Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1863
+ }
1864
+ }
1865
+ else {
1866
+ if (this._byteOffset + 2 > this._arrayBuffer.byteLength) {
1867
+ this._resizeBuffer(this._arrayBuffer.byteLength * 2);
1868
+ }
1869
+ this._dataView.setUint16(this._byteOffset, entry, true);
1870
+ this._byteOffset += 2;
1871
+ }
1872
+ };
1873
+ /**
1874
+ * Gets an UInt32 in the array buffer
1875
+ * @param byteOffset If defined, specifies where to set the value as an offset.
1876
+ */
1877
+ _BinaryWriter.prototype.getUInt32 = function (byteOffset) {
1878
+ if (byteOffset < this._byteOffset) {
1879
+ return this._dataView.getUint32(byteOffset, true);
1880
+ }
1881
+ else {
1882
+ Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1883
+ throw new Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1884
+ }
1885
+ };
1886
+ _BinaryWriter.prototype.getVector3Float32FromRef = function (vector3, byteOffset) {
1887
+ if (byteOffset + 8 > this._byteOffset) {
1888
+ Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1889
+ }
1890
+ else {
1891
+ vector3.x = this._dataView.getFloat32(byteOffset, true);
1892
+ vector3.y = this._dataView.getFloat32(byteOffset + 4, true);
1893
+ vector3.z = this._dataView.getFloat32(byteOffset + 8, true);
1894
+ }
1895
+ };
1896
+ _BinaryWriter.prototype.setVector3Float32FromRef = function (vector3, byteOffset) {
1897
+ if (byteOffset + 8 > this._byteOffset) {
1898
+ Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1899
+ }
1900
+ else {
1901
+ this._dataView.setFloat32(byteOffset, vector3.x, true);
1902
+ this._dataView.setFloat32(byteOffset + 4, vector3.y, true);
1903
+ this._dataView.setFloat32(byteOffset + 8, vector3.z, true);
1904
+ }
1905
+ };
1906
+ _BinaryWriter.prototype.getVector4Float32FromRef = function (vector4, byteOffset) {
1907
+ if (byteOffset + 12 > this._byteOffset) {
1908
+ Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1909
+ }
1910
+ else {
1911
+ vector4.x = this._dataView.getFloat32(byteOffset, true);
1912
+ vector4.y = this._dataView.getFloat32(byteOffset + 4, true);
1913
+ vector4.z = this._dataView.getFloat32(byteOffset + 8, true);
1914
+ vector4.w = this._dataView.getFloat32(byteOffset + 12, true);
1915
+ }
1916
+ };
1917
+ _BinaryWriter.prototype.setVector4Float32FromRef = function (vector4, byteOffset) {
1918
+ if (byteOffset + 12 > this._byteOffset) {
1919
+ Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1920
+ }
1921
+ else {
1922
+ this._dataView.setFloat32(byteOffset, vector4.x, true);
1923
+ this._dataView.setFloat32(byteOffset + 4, vector4.y, true);
1924
+ this._dataView.setFloat32(byteOffset + 8, vector4.z, true);
1925
+ this._dataView.setFloat32(byteOffset + 12, vector4.w, true);
1926
+ }
1927
+ };
1928
+ /**
1929
+ * Stores a Float32 in the array buffer
1930
+ * @param entry
1931
+ * @param byteOffset
1932
+ */
1933
+ _BinaryWriter.prototype.setFloat32 = function (entry, byteOffset) {
1934
+ if (isNaN(entry)) {
1935
+ Tools.Error("Invalid data being written!");
1936
+ }
1937
+ if (byteOffset != null) {
1938
+ if (byteOffset < this._byteOffset) {
1939
+ this._dataView.setFloat32(byteOffset, entry, true);
1940
+ }
1941
+ else {
1942
+ Tools.Error("BinaryWriter: byteoffset is greater than the current binary length!");
1943
+ }
1944
+ }
1945
+ if (this._byteOffset + 4 > this._arrayBuffer.byteLength) {
1946
+ this._resizeBuffer(this._arrayBuffer.byteLength * 2);
1947
+ }
1948
+ this._dataView.setFloat32(this._byteOffset, entry, true);
1949
+ this._byteOffset += 4;
1950
+ };
1951
+ /**
1952
+ * Stores an UInt32 in the array buffer
1953
+ * @param entry
1954
+ * @param byteOffset If defined, specifies where to set the value as an offset.
1955
+ */
1956
+ _BinaryWriter.prototype.setUInt32 = function (entry, byteOffset) {
1957
+ if (byteOffset != null) {
1958
+ if (byteOffset < this._byteOffset) {
1959
+ this._dataView.setUint32(byteOffset, entry, true);
1960
+ }
1961
+ else {
1962
+ Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!");
1963
+ }
1964
+ }
1965
+ else {
1966
+ if (this._byteOffset + 4 > this._arrayBuffer.byteLength) {
1967
+ this._resizeBuffer(this._arrayBuffer.byteLength * 2);
1968
+ }
1969
+ this._dataView.setUint32(this._byteOffset, entry, true);
1970
+ this._byteOffset += 4;
1971
+ }
1972
+ };
1973
+ return _BinaryWriter;
1974
+ }());
1975
+ export { _BinaryWriter };
1973
1976
  //# sourceMappingURL=glTFExporter.js.map