@babylonjs/serializers 6.6.1 → 6.7.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.
@@ -18,6 +18,54 @@ import { EngineStore } from "@babylonjs/core/Engines/engineStore.js";
18
18
  import { MultiMaterial } from "@babylonjs/core/Materials/multiMaterial.js";
19
19
  // Matrix that converts handedness on the X-axis.
20
20
  const convertHandednessMatrix = Matrix.Compose(new Vector3(-1, 1, 1), Quaternion.Identity(), Vector3.Zero());
21
+ function isNoopNode(node, useRightHandedSystem) {
22
+ if (!(node instanceof TransformNode)) {
23
+ return false;
24
+ }
25
+ // Transform
26
+ if (useRightHandedSystem) {
27
+ const matrix = node.getWorldMatrix();
28
+ if (!matrix.isIdentity()) {
29
+ return false;
30
+ }
31
+ }
32
+ else {
33
+ const matrix = node.getWorldMatrix().multiplyToRef(convertHandednessMatrix, TmpVectors.Matrix[0]);
34
+ if (!matrix.isIdentity()) {
35
+ return false;
36
+ }
37
+ }
38
+ // Geometry
39
+ if ((node instanceof Mesh && node.geometry) || (node instanceof InstancedMesh && node.sourceMesh.geometry)) {
40
+ return false;
41
+ }
42
+ return true;
43
+ }
44
+ function convertNodeHandedness(node) {
45
+ const translation = Vector3.FromArrayToRef(node.translation || [0, 0, 0], 0, TmpVectors.Vector3[0]);
46
+ const rotation = Quaternion.FromArrayToRef(node.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[0]);
47
+ const scale = Vector3.FromArrayToRef(node.scale || [1, 1, 1], 0, TmpVectors.Vector3[1]);
48
+ const matrix = Matrix.ComposeToRef(scale, rotation, translation, TmpVectors.Matrix[0]).multiplyToRef(convertHandednessMatrix, TmpVectors.Matrix[0]);
49
+ matrix.decompose(scale, rotation, translation);
50
+ if (translation.equalsToFloats(0, 0, 0)) {
51
+ delete node.translation;
52
+ }
53
+ else {
54
+ node.translation = translation.asArray();
55
+ }
56
+ if (Quaternion.IsIdentity(rotation)) {
57
+ delete node.rotation;
58
+ }
59
+ else {
60
+ node.rotation = rotation.asArray();
61
+ }
62
+ if (scale.equalsToFloats(1, 1, 1)) {
63
+ delete node.scale;
64
+ }
65
+ else {
66
+ node.scale = scale.asArray();
67
+ }
68
+ }
21
69
  /**
22
70
  * Converts Babylon Scene into glTF 2.0.
23
71
  * @internal
@@ -119,10 +167,6 @@ export class _Exporter {
119
167
  * @param options Options to modify the behavior of the exporter
120
168
  */
121
169
  constructor(babylonScene, options) {
122
- /*
123
- * Specifies if root Babylon empty nodes that act as a coordinate space transform should be included in export
124
- */
125
- this._includeCoordinateSystemConversionNodes = false;
126
170
  this._extensions = {};
127
171
  this._glTF = {
128
172
  asset: { generator: `Babylon.js v${Engine.Version}`, version: "2.0" },
@@ -148,8 +192,7 @@ export class _Exporter {
148
192
  this._imageData = {};
149
193
  this._orderedImageData = [];
150
194
  this._options = options || {};
151
- this._animationSampleRate = options && options.animationSampleRate ? options.animationSampleRate : 1 / 60;
152
- this._includeCoordinateSystemConversionNodes = options && options.includeCoordinateSystemConversionNodes ? true : false;
195
+ this._animationSampleRate = this._options.animationSampleRate || 1 / 60;
153
196
  this._glTFMaterialExporter = new _GLTFMaterialExporter(this);
154
197
  this._loadExtensions();
155
198
  }
@@ -227,28 +270,24 @@ export class _Exporter {
227
270
  * clock-wise during export to glTF
228
271
  * @param submesh BabylonJS submesh
229
272
  * @param primitiveMode Primitive mode of the mesh
230
- * @param sideOrientation the winding order of the submesh
231
273
  * @param vertexBufferKind The type of vertex attribute
232
274
  * @param meshAttributeArray The vertex attribute data
233
275
  * @param byteOffset The offset to the binary data
234
276
  * @param binaryWriter The binary data for the glTF file
235
- * @param convertToRightHandedSystem Converts the values to right-handed
236
277
  */
237
- _reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
238
- if (convertToRightHandedSystem && sideOrientation === Material.ClockWiseSideOrientation) {
239
- switch (primitiveMode) {
240
- case Material.TriangleFillMode: {
241
- this._reorderTriangleFillMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
242
- break;
243
- }
244
- case Material.TriangleStripDrawMode: {
245
- this._reorderTriangleStripDrawMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
246
- break;
247
- }
248
- case Material.TriangleFanDrawMode: {
249
- this._reorderTriangleFanMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
250
- break;
251
- }
278
+ _reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) {
279
+ switch (primitiveMode) {
280
+ case Material.TriangleFillMode: {
281
+ this._reorderTriangleFillMode(submesh, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter);
282
+ break;
283
+ }
284
+ case Material.TriangleStripDrawMode: {
285
+ this._reorderTriangleStripDrawMode(submesh, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter);
286
+ break;
287
+ }
288
+ case Material.TriangleFanDrawMode: {
289
+ this._reorderTriangleFanMode(submesh, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter);
290
+ break;
252
291
  }
253
292
  }
254
293
  }
@@ -256,15 +295,12 @@ export class _Exporter {
256
295
  * Reorders the vertex attributes in the correct triangle mode order . This is necessary when indices are not available and the winding order is
257
296
  * clock-wise during export to glTF
258
297
  * @param submesh BabylonJS submesh
259
- * @param primitiveMode Primitive mode of the mesh
260
- * @param sideOrientation the winding order of the submesh
261
298
  * @param vertexBufferKind The type of vertex attribute
262
299
  * @param meshAttributeArray The vertex attribute data
263
300
  * @param byteOffset The offset to the binary data
264
301
  * @param binaryWriter The binary data for the glTF file
265
- * @param convertToRightHandedSystem Converts the values to right-handed
266
302
  */
267
- _reorderTriangleFillMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
303
+ _reorderTriangleFillMode(submesh, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) {
268
304
  const vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
269
305
  if (vertexBuffer) {
270
306
  const stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);
@@ -325,7 +361,7 @@ export class _Exporter {
325
361
  Tools.Error(`Unsupported Vertex Buffer type: ${vertexBufferKind}`);
326
362
  }
327
363
  }
328
- this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
364
+ this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, binaryWriter);
329
365
  }
330
366
  }
331
367
  else {
@@ -336,15 +372,12 @@ export class _Exporter {
336
372
  * Reorders the vertex attributes in the correct triangle strip order. This is necessary when indices are not available and the winding order is
337
373
  * clock-wise during export to glTF
338
374
  * @param submesh BabylonJS submesh
339
- * @param primitiveMode Primitive mode of the mesh
340
- * @param sideOrientation the winding order of the submesh
341
375
  * @param vertexBufferKind The type of vertex attribute
342
376
  * @param meshAttributeArray The vertex attribute data
343
377
  * @param byteOffset The offset to the binary data
344
378
  * @param binaryWriter The binary data for the glTF file
345
- * @param convertToRightHandedSystem Converts the values to right-handed
346
379
  */
347
- _reorderTriangleStripDrawMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
380
+ _reorderTriangleStripDrawMode(submesh, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) {
348
381
  const vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
349
382
  if (vertexBuffer) {
350
383
  const stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);
@@ -386,7 +419,7 @@ export class _Exporter {
386
419
  Tools.Error(`Unsupported Vertex Buffer type: ${vertexBufferKind}`);
387
420
  }
388
421
  }
389
- this._writeVertexAttributeData(vertexData, byteOffset + 12, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
422
+ this._writeVertexAttributeData(vertexData, byteOffset + 12, vertexBufferKind, binaryWriter);
390
423
  }
391
424
  else {
392
425
  Tools.Warn(`reorderTriangleStripDrawMode: Vertex buffer kind ${vertexBufferKind} not present!`);
@@ -396,15 +429,12 @@ export class _Exporter {
396
429
  * Reorders the vertex attributes in the correct triangle fan order. This is necessary when indices are not available and the winding order is
397
430
  * clock-wise during export to glTF
398
431
  * @param submesh BabylonJS submesh
399
- * @param primitiveMode Primitive mode of the mesh
400
- * @param sideOrientation the winding order of the submesh
401
432
  * @param vertexBufferKind The type of vertex attribute
402
433
  * @param meshAttributeArray The vertex attribute data
403
434
  * @param byteOffset The offset to the binary data
404
435
  * @param binaryWriter The binary data for the glTF file
405
- * @param convertToRightHandedSystem Converts the values to right-handed
406
436
  */
407
- _reorderTriangleFanMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
437
+ _reorderTriangleFanMode(submesh, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) {
408
438
  const vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
409
439
  if (vertexBuffer) {
410
440
  const stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);
@@ -448,7 +478,7 @@ export class _Exporter {
448
478
  Tools.Error(`Unsupported Vertex Buffer type: ${vertexBufferKind}`);
449
479
  }
450
480
  }
451
- this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
481
+ this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, binaryWriter);
452
482
  }
453
483
  else {
454
484
  Tools.Warn(`reorderTriangleFanMode: Vertex buffer kind ${vertexBufferKind} not present!`);
@@ -459,28 +489,10 @@ export class _Exporter {
459
489
  * @param vertices The vertices to write to the binary writer
460
490
  * @param byteOffset The offset into the binary writer to overwrite binary data
461
491
  * @param vertexAttributeKind The vertex attribute type
462
- * @param meshAttributeArray The vertex attribute data
463
492
  * @param binaryWriter The writer containing the binary data
464
- * @param convertToRightHandedSystem Converts the values to right-handed
465
493
  */
466
- _writeVertexAttributeData(vertices, byteOffset, vertexAttributeKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem) {
494
+ _writeVertexAttributeData(vertices, byteOffset, vertexAttributeKind, binaryWriter) {
467
495
  for (const vertex of vertices) {
468
- if (convertToRightHandedSystem && !(vertexAttributeKind === VertexBuffer.ColorKind) && !(vertex instanceof Vector2)) {
469
- if (vertex instanceof Vector3) {
470
- if (vertexAttributeKind === VertexBuffer.NormalKind) {
471
- _GLTFUtilities._GetRightHandedNormalVector3FromRef(vertex);
472
- }
473
- else if (vertexAttributeKind === VertexBuffer.PositionKind) {
474
- _GLTFUtilities._GetRightHandedPositionVector3FromRef(vertex);
475
- }
476
- else {
477
- Tools.Error("Unsupported vertex attribute kind!");
478
- }
479
- }
480
- else {
481
- _GLTFUtilities._GetRightHandedVector4FromRef(vertex);
482
- }
483
- }
484
496
  if (vertexAttributeKind === VertexBuffer.NormalKind) {
485
497
  vertex.normalize();
486
498
  }
@@ -501,10 +513,9 @@ export class _Exporter {
501
513
  * @param meshAttributeArray Array containing the attribute data
502
514
  * @param stride Specifies the space between data
503
515
  * @param binaryWriter The buffer to write the binary data to
504
- * @param convertToRightHandedSystem Converts the values to right-handed
505
516
  * @param babylonTransformNode
506
517
  */
507
- _writeAttributeData(vertexBufferKind, attributeComponentKind, meshAttributeArray, stride, binaryWriter, convertToRightHandedSystem, babylonTransformNode) {
518
+ _writeAttributeData(vertexBufferKind, attributeComponentKind, meshAttributeArray, stride, binaryWriter, babylonTransformNode) {
508
519
  let vertexAttributes = [];
509
520
  let index;
510
521
  switch (vertexBufferKind) {
@@ -512,9 +523,6 @@ export class _Exporter {
512
523
  for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {
513
524
  index = k * stride;
514
525
  const vertexData = Vector3.FromArray(meshAttributeArray, index);
515
- if (convertToRightHandedSystem) {
516
- _GLTFUtilities._GetRightHandedPositionVector3FromRef(vertexData);
517
- }
518
526
  vertexAttributes.push(vertexData.asArray());
519
527
  }
520
528
  break;
@@ -523,11 +531,7 @@ export class _Exporter {
523
531
  for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {
524
532
  index = k * stride;
525
533
  const vertexData = Vector3.FromArray(meshAttributeArray, index);
526
- if (convertToRightHandedSystem) {
527
- _GLTFUtilities._GetRightHandedNormalVector3FromRef(vertexData);
528
- }
529
- vertexData.normalize();
530
- vertexAttributes.push(vertexData.asArray());
534
+ vertexAttributes.push(vertexData.normalize().asArray());
531
535
  }
532
536
  break;
533
537
  }
@@ -535,9 +539,6 @@ export class _Exporter {
535
539
  for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {
536
540
  index = k * stride;
537
541
  const vertexData = Vector4.FromArray(meshAttributeArray, index);
538
- if (convertToRightHandedSystem) {
539
- _GLTFUtilities._GetRightHandedVector4FromRef(vertexData);
540
- }
541
542
  _GLTFUtilities._NormalizeTangentFromRef(vertexData);
542
543
  vertexAttributes.push(vertexData.asArray());
543
544
  }
@@ -570,7 +571,8 @@ export class _Exporter {
570
571
  case VertexBuffer.UV2Kind: {
571
572
  for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {
572
573
  index = k * stride;
573
- vertexAttributes.push(convertToRightHandedSystem ? [meshAttributeArray[index], meshAttributeArray[index + 1]] : [meshAttributeArray[index], meshAttributeArray[index + 1]]);
574
+ const vertexData = Vector2.FromArray(meshAttributeArray, index);
575
+ vertexAttributes.push(vertexData.asArray());
574
576
  }
575
577
  break;
576
578
  }
@@ -637,10 +639,9 @@ export class _Exporter {
637
639
  * @param morphTargetAttributeArray
638
640
  * @param stride Specifies the space between data
639
641
  * @param binaryWriter The buffer to write the binary data to
640
- * @param convertToRightHandedSystem Converts the values to right-handed
641
642
  * @param minMax
642
643
  */
643
- writeMorphTargetAttributeData(vertexBufferKind, attributeComponentKind, meshPrimitive, morphTarget, meshAttributeArray, morphTargetAttributeArray, stride, binaryWriter, convertToRightHandedSystem, minMax) {
644
+ writeMorphTargetAttributeData(vertexBufferKind, attributeComponentKind, meshPrimitive, meshAttributeArray, morphTargetAttributeArray, stride, binaryWriter, minMax) {
644
645
  let vertexAttributes = [];
645
646
  let index;
646
647
  let difference = new Vector3();
@@ -652,9 +653,6 @@ export class _Exporter {
652
653
  const vertexData = Vector3.FromArray(meshAttributeArray, index);
653
654
  const morphData = Vector3.FromArray(morphTargetAttributeArray, index);
654
655
  difference = morphData.subtractToRef(vertexData, difference);
655
- if (convertToRightHandedSystem) {
656
- _GLTFUtilities._GetRightHandedPositionVector3FromRef(difference);
657
- }
658
656
  if (minMax) {
659
657
  minMax.min.copyFromFloats(Math.min(difference.x, minMax.min.x), Math.min(difference.y, minMax.min.y), Math.min(difference.z, minMax.min.z));
660
658
  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,14 +664,9 @@ export class _Exporter {
666
664
  case VertexBuffer.NormalKind: {
667
665
  for (let k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
668
666
  index = meshPrimitive.indexStart + k * stride;
669
- const vertexData = Vector3.FromArray(meshAttributeArray, index);
670
- vertexData.normalize();
671
- const morphData = Vector3.FromArray(morphTargetAttributeArray, index);
672
- morphData.normalize();
667
+ const vertexData = Vector3.FromArray(meshAttributeArray, index).normalize();
668
+ const morphData = Vector3.FromArray(morphTargetAttributeArray, index).normalize();
673
669
  difference = morphData.subtractToRef(vertexData, difference);
674
- if (convertToRightHandedSystem) {
675
- _GLTFUtilities._GetRightHandedNormalVector3FromRef(difference);
676
- }
677
670
  vertexAttributes.push(difference.asArray());
678
671
  }
679
672
  break;
@@ -686,9 +679,6 @@ export class _Exporter {
686
679
  const morphData = Vector4.FromArray(morphTargetAttributeArray, index);
687
680
  _GLTFUtilities._NormalizeTangentFromRef(morphData);
688
681
  difference4 = morphData.subtractToRef(vertexData, difference4);
689
- if (convertToRightHandedSystem) {
690
- _GLTFUtilities._GetRightHandedVector4FromRef(difference4);
691
- }
692
682
  vertexAttributes.push([difference4.x, difference4.y, difference4.z]);
693
683
  }
694
684
  break;
@@ -844,7 +834,7 @@ export class _Exporter {
844
834
  */
845
835
  _generateBinaryAsync() {
846
836
  const binaryWriter = new _BinaryWriter(4);
847
- return this._createSceneAsync(this._babylonScene, binaryWriter).then(() => {
837
+ return this._createSceneAsync(binaryWriter).then(() => {
848
838
  if (this._localEngine) {
849
839
  this._localEngine.dispose();
850
840
  }
@@ -961,16 +951,13 @@ export class _Exporter {
961
951
  * Sets the TRS for each node
962
952
  * @param node glTF Node for storing the transformation data
963
953
  * @param babylonTransformNode Babylon mesh used as the source for the transformation data
964
- * @param convertToRightHandedSystem Converts the values to right-handed
965
954
  */
966
- _setNodeTransformation(node, babylonTransformNode, convertToRightHandedSystem) {
955
+ _setNodeTransformation(node, babylonTransformNode) {
967
956
  if (!babylonTransformNode.getPivotPoint().equalsToFloats(0, 0, 0)) {
968
957
  Tools.Warn("Pivot points are not supported in the glTF serializer");
969
958
  }
970
959
  if (!babylonTransformNode.position.equalsToFloats(0, 0, 0)) {
971
- node.translation = convertToRightHandedSystem
972
- ? _GLTFUtilities._GetRightHandedPositionVector3(babylonTransformNode.position).asArray()
973
- : babylonTransformNode.position.asArray();
960
+ node.translation = babylonTransformNode.position.asArray();
974
961
  }
975
962
  if (!babylonTransformNode.scaling.equalsToFloats(1, 1, 1)) {
976
963
  node.scale = babylonTransformNode.scaling.asArray();
@@ -980,21 +967,15 @@ export class _Exporter {
980
967
  rotationQuaternion.multiplyInPlace(babylonTransformNode.rotationQuaternion);
981
968
  }
982
969
  if (!Quaternion.IsIdentity(rotationQuaternion)) {
983
- if (convertToRightHandedSystem) {
984
- _GLTFUtilities._GetRightHandedQuaternionFromRef(rotationQuaternion);
985
- }
986
970
  node.rotation = rotationQuaternion.normalize().asArray();
987
971
  }
988
972
  }
989
- _setCameraTransformation(node, babylonCamera, convertToRightHandedSystem) {
973
+ _setCameraTransformation(node, babylonCamera) {
990
974
  if (!babylonCamera.position.equalsToFloats(0, 0, 0)) {
991
- node.translation = convertToRightHandedSystem ? _GLTFUtilities._GetRightHandedPositionVector3(babylonCamera.position).asArray() : babylonCamera.position.asArray();
975
+ node.translation = babylonCamera.position.asArray();
992
976
  }
993
977
  const rotationQuaternion = babylonCamera.rotationQuaternion; // we target the local transformation if one.
994
978
  if (rotationQuaternion && !Quaternion.IsIdentity(rotationQuaternion)) {
995
- if (convertToRightHandedSystem) {
996
- _GLTFUtilities._GetRightHandedQuaternionFromRef(rotationQuaternion);
997
- }
998
979
  node.rotation = rotationQuaternion.normalize().asArray();
999
980
  }
1000
981
  }
@@ -1014,9 +995,8 @@ export class _Exporter {
1014
995
  * @param babylonTransformNode The Babylon mesh to get the vertices data from
1015
996
  * @param binaryWriter The buffer to write the bufferview data to
1016
997
  * @param byteStride
1017
- * @param convertToRightHandedSystem Converts the values to right-handed
1018
998
  */
1019
- _createBufferViewKind(kind, attributeComponentKind, babylonTransformNode, binaryWriter, byteStride, convertToRightHandedSystem) {
999
+ _createBufferViewKind(kind, attributeComponentKind, babylonTransformNode, binaryWriter, byteStride) {
1020
1000
  const bufferMesh = babylonTransformNode instanceof Mesh
1021
1001
  ? babylonTransformNode
1022
1002
  : babylonTransformNode instanceof InstancedMesh
@@ -1030,7 +1010,7 @@ export class _Exporter {
1030
1010
  const byteLength = vertexData.length * typeByteLength;
1031
1011
  const bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, kind + " - " + bufferMesh.name);
1032
1012
  this._bufferViews.push(bufferView);
1033
- this._writeAttributeData(kind, attributeComponentKind, vertexData, byteStride / typeByteLength, binaryWriter, convertToRightHandedSystem, babylonTransformNode);
1013
+ this._writeAttributeData(kind, attributeComponentKind, vertexData, byteStride / typeByteLength, binaryWriter, babylonTransformNode);
1034
1014
  }
1035
1015
  }
1036
1016
  }
@@ -1040,9 +1020,8 @@ export class _Exporter {
1040
1020
  * @param meshPrimitive
1041
1021
  * @param babylonMorphTarget the morph target to be exported
1042
1022
  * @param binaryWriter The buffer to write the bufferview data to
1043
- * @param convertToRightHandedSystem Converts the values to right-handed
1044
1023
  */
1045
- _setMorphTargetAttributes(babylonSubMesh, meshPrimitive, babylonMorphTarget, binaryWriter, convertToRightHandedSystem) {
1024
+ _setMorphTargetAttributes(babylonSubMesh, meshPrimitive, babylonMorphTarget, binaryWriter) {
1046
1025
  if (babylonMorphTarget) {
1047
1026
  if (!meshPrimitive.targets) {
1048
1027
  meshPrimitive.targets = [];
@@ -1061,7 +1040,7 @@ export class _Exporter {
1061
1040
  const accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "NORMAL", "VEC3" /* AccessorType.VEC3 */, 5126 /* AccessorComponentType.FLOAT */, count, 0, null, null);
1062
1041
  this._accessors.push(accessor);
1063
1042
  target.NORMAL = this._accessors.length - 1;
1064
- this.writeMorphTargetAttributeData(VertexBuffer.NormalKind, 5126 /* AccessorComponentType.FLOAT */, babylonSubMesh, babylonMorphTarget, vertexNormals, morphNormals, byteStride / 4, binaryWriter, convertToRightHandedSystem);
1043
+ this.writeMorphTargetAttributeData(VertexBuffer.NormalKind, 5126 /* AccessorComponentType.FLOAT */, babylonSubMesh, vertexNormals, morphNormals, byteStride / 4, binaryWriter);
1065
1044
  }
1066
1045
  if (babylonMorphTarget.hasPositions) {
1067
1046
  const vertexPositions = mesh.getVerticesData(VertexBuffer.PositionKind, undefined, undefined, true);
@@ -1076,7 +1055,7 @@ export class _Exporter {
1076
1055
  const accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "POSITION", "VEC3" /* AccessorType.VEC3 */, 5126 /* AccessorComponentType.FLOAT */, count, 0, null, null);
1077
1056
  this._accessors.push(accessor);
1078
1057
  target.POSITION = this._accessors.length - 1;
1079
- this.writeMorphTargetAttributeData(VertexBuffer.PositionKind, 5126 /* AccessorComponentType.FLOAT */, babylonSubMesh, babylonMorphTarget, vertexPositions, morphPositions, byteStride / 4, binaryWriter, convertToRightHandedSystem, minMax);
1058
+ this.writeMorphTargetAttributeData(VertexBuffer.PositionKind, 5126 /* AccessorComponentType.FLOAT */, babylonSubMesh, vertexPositions, morphPositions, byteStride / 4, binaryWriter, minMax);
1080
1059
  accessor.min = minMax.min.asArray();
1081
1060
  accessor.max = minMax.max.asArray();
1082
1061
  }
@@ -1092,7 +1071,7 @@ export class _Exporter {
1092
1071
  const accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "TANGENT", "VEC3" /* AccessorType.VEC3 */, 5126 /* AccessorComponentType.FLOAT */, count, 0, null, null);
1093
1072
  this._accessors.push(accessor);
1094
1073
  target.TANGENT = this._accessors.length - 1;
1095
- this.writeMorphTargetAttributeData(VertexBuffer.TangentKind, 5126 /* AccessorComponentType.FLOAT */, babylonSubMesh, babylonMorphTarget, vertexTangents, morphTangents, byteStride / 4, binaryWriter, convertToRightHandedSystem);
1074
+ this.writeMorphTargetAttributeData(VertexBuffer.TangentKind, 5126 /* AccessorComponentType.FLOAT */, babylonSubMesh, vertexTangents, morphTangents, byteStride / 4, binaryWriter);
1096
1075
  }
1097
1076
  meshPrimitive.targets.push(target);
1098
1077
  }
@@ -1212,10 +1191,8 @@ export class _Exporter {
1212
1191
  * @param mesh glTF Mesh object to store the primitive attribute information
1213
1192
  * @param babylonTransformNode Babylon mesh to get the primitive attribute data from
1214
1193
  * @param binaryWriter Buffer to write the attribute data to
1215
- * @param convertToRightHandedSystem Converts the values to right-handed
1216
1194
  */
1217
- _setPrimitiveAttributesAsync(mesh, babylonTransformNode, binaryWriter, convertToRightHandedSystem) {
1218
- var _a;
1195
+ _setPrimitiveAttributesAsync(mesh, babylonTransformNode, binaryWriter) {
1219
1196
  const promises = [];
1220
1197
  let bufferMesh = null;
1221
1198
  let bufferView;
@@ -1255,7 +1232,7 @@ export class _Exporter {
1255
1232
  if (attribute.byteStride === 12) {
1256
1233
  attribute.accessorType = "VEC3" /* AccessorType.VEC3 */;
1257
1234
  }
1258
- this._createBufferViewKind(attributeKind, attributeComponentKind, babylonTransformNode, binaryWriter, attribute.byteStride, convertToRightHandedSystem);
1235
+ this._createBufferViewKind(attributeKind, attributeComponentKind, babylonTransformNode, binaryWriter, attribute.byteStride);
1259
1236
  attribute.bufferViewIndex = this._bufferViews.length - 1;
1260
1237
  vertexAttributeBufferViews[attributeKind] = attribute.bufferViewIndex;
1261
1238
  }
@@ -1322,7 +1299,7 @@ export class _Exporter {
1322
1299
  // check to see if bufferviewindex has a numeric value assigned.
1323
1300
  minMax = { min: null, max: null };
1324
1301
  if (attributeKind == VertexBuffer.PositionKind) {
1325
- minMax = _GLTFUtilities._CalculateMinMaxPositions(vertexData, 0, vertexData.length / stride, convertToRightHandedSystem);
1302
+ minMax = _GLTFUtilities._CalculateMinMaxPositions(vertexData, 0, vertexData.length / stride);
1326
1303
  }
1327
1304
  const accessor = _GLTFUtilities._CreateAccessor(bufferViewIndex, attributeKind + " - " + babylonTransformNode.name, attribute.accessorType, attribute.accessorComponentType, vertexData.length / stride, 0, minMax.min, minMax.max);
1328
1305
  this._accessors.push(accessor);
@@ -1339,10 +1316,7 @@ export class _Exporter {
1339
1316
  }
1340
1317
  if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
1341
1318
  const sideOrientation = bufferMesh.overrideMaterialSideOrientation !== null ? bufferMesh.overrideMaterialSideOrientation : babylonMaterial.sideOrientation;
1342
- if ((sideOrientation == Material.ClockWiseSideOrientation && this._babylonScene.useRightHandedSystem) ||
1343
- (sideOrientation == Material.ClockWiseSideOrientation &&
1344
- convertToRightHandedSystem &&
1345
- bufferMesh.overrideMaterialSideOrientation !== ((_a = bufferMesh.material) === null || _a === void 0 ? void 0 : _a.sideOrientation))) {
1319
+ if (sideOrientation === (this._babylonScene.useRightHandedSystem ? Material.ClockWiseSideOrientation : Material.CounterClockWiseSideOrientation)) {
1346
1320
  let byteOffset = indexBufferViewIndex != null ? this._bufferViews[indexBufferViewIndex].byteOffset : null;
1347
1321
  if (byteOffset == null) {
1348
1322
  byteOffset = 0;
@@ -1358,11 +1332,8 @@ export class _Exporter {
1358
1332
  for (const attribute of attributeData) {
1359
1333
  const vertexData = bufferMesh.getVerticesData(attribute.kind, undefined, undefined, true);
1360
1334
  if (vertexData) {
1361
- let byteOffset = this._bufferViews[vertexAttributeBufferViews[attribute.kind]].byteOffset;
1362
- if (!byteOffset) {
1363
- byteOffset = 0;
1364
- }
1365
- this._reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData, byteOffset, binaryWriter, convertToRightHandedSystem);
1335
+ const byteOffset = this._bufferViews[vertexAttributeBufferViews[attribute.kind]].byteOffset || 0;
1336
+ this._reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, attribute.kind, vertexData, byteOffset, binaryWriter);
1366
1337
  }
1367
1338
  }
1368
1339
  }
@@ -1373,7 +1344,7 @@ export class _Exporter {
1373
1344
  let target;
1374
1345
  for (let i = 0; i < morphTargetManager.numTargets; ++i) {
1375
1346
  target = morphTargetManager.getTarget(i);
1376
- this._setMorphTargetAttributes(submesh, meshPrimitive, target, binaryWriter, convertToRightHandedSystem);
1347
+ this._setMorphTargetAttributes(submesh, meshPrimitive, target, binaryWriter);
1377
1348
  }
1378
1349
  }
1379
1350
  mesh.primitives.push(meshPrimitive);
@@ -1386,79 +1357,42 @@ export class _Exporter {
1386
1357
  /* do nothing */
1387
1358
  });
1388
1359
  }
1389
- /**
1390
- * Check if the node is used to convert its descendants from a right handed coordinate system to the Babylon scene's coordinate system.
1391
- * @param node The node to check
1392
- * @returns True if the node is used to convert its descendants from right-handed to left-handed. False otherwise
1393
- */
1394
- _isBabylonCoordinateSystemConvertingNode(node) {
1395
- if (node instanceof TransformNode) {
1396
- // Transform
1397
- const matrix = node.getWorldMatrix().multiplyToRef(convertHandednessMatrix, TmpVectors.Matrix[0]);
1398
- if (!matrix.isIdentity()) {
1399
- return false;
1400
- }
1401
- // Geometry
1402
- if ((node instanceof Mesh && node.geometry !== null) || (node instanceof InstancedMesh && node.sourceMesh.geometry !== null)) {
1403
- return false;
1404
- }
1405
- return true;
1406
- }
1407
- return false;
1408
- }
1409
1360
  /**
1410
1361
  * Creates a glTF scene based on the array of meshes
1411
1362
  * Returns the the total byte offset
1412
1363
  * @param babylonScene Babylon scene to get the mesh data from
1413
1364
  * @param binaryWriter Buffer to write binary data to
1414
1365
  */
1415
- _createSceneAsync(babylonScene, binaryWriter) {
1366
+ _createSceneAsync(binaryWriter) {
1367
+ var _a;
1416
1368
  const scene = { nodes: [] };
1417
1369
  let glTFNodeIndex;
1418
1370
  let glTFNode;
1419
1371
  let directDescendents;
1420
- const nodes = [...babylonScene.transformNodes, ...babylonScene.meshes, ...babylonScene.lights, ...babylonScene.cameras];
1421
- const rootNodesToLeftHanded = [];
1422
- this._convertToRightHandedSystem = !babylonScene.useRightHandedSystem;
1423
- this._convertToRightHandedSystemMap = {};
1372
+ const nodes = [...this._babylonScene.transformNodes, ...this._babylonScene.meshes, ...this._babylonScene.lights, ...this._babylonScene.cameras];
1373
+ const removedRootNodes = new Set();
1424
1374
  // Scene metadata
1425
- if (babylonScene.metadata) {
1375
+ if (this._babylonScene.metadata) {
1426
1376
  if (this._options.metadataSelector) {
1427
- scene.extras = this._options.metadataSelector(babylonScene.metadata);
1377
+ scene.extras = this._options.metadataSelector(this._babylonScene.metadata);
1428
1378
  }
1429
- else if (babylonScene.metadata.gltf) {
1430
- scene.extras = babylonScene.metadata.gltf.extras;
1379
+ else if (this._babylonScene.metadata.gltf) {
1380
+ scene.extras = this._babylonScene.metadata.gltf.extras;
1431
1381
  }
1432
1382
  }
1433
- // Set default values for all nodes
1434
- babylonScene.rootNodes.forEach((rootNode) => {
1435
- this._convertToRightHandedSystemMap[rootNode.uniqueId] = this._convertToRightHandedSystem;
1436
- rootNode.getDescendants(false).forEach((descendant) => {
1437
- this._convertToRightHandedSystemMap[descendant.uniqueId] = this._convertToRightHandedSystem;
1438
- });
1439
- });
1440
- // Check if root nodes converting to left-handed are present
1441
- babylonScene.rootNodes.forEach((rootNode) => {
1442
- if (this._includeCoordinateSystemConversionNodes) {
1443
- return;
1444
- }
1445
- if (this._isBabylonCoordinateSystemConvertingNode(rootNode)) {
1446
- rootNodesToLeftHanded.push(rootNode);
1447
- // Exclude the node from list of nodes to export
1448
- const indexRootNode = nodes.indexOf(rootNode);
1449
- if (indexRootNode !== -1) {
1450
- // should always be true
1451
- nodes.splice(indexRootNode, 1);
1383
+ // Remove no-op root nodes
1384
+ if (((_a = this._options.removeNoopRootNodes) !== null && _a !== void 0 ? _a : true) && !this._options.includeCoordinateSystemConversionNodes) {
1385
+ for (const rootNode of this._babylonScene.rootNodes) {
1386
+ if (isNoopNode(rootNode, this._babylonScene.useRightHandedSystem)) {
1387
+ removedRootNodes.add(rootNode);
1388
+ // Exclude the node from list of nodes to export
1389
+ nodes.splice(nodes.indexOf(rootNode), 1);
1452
1390
  }
1453
- // Cancel conversion to right handed system
1454
- rootNode.getDescendants(false).forEach((descendant) => {
1455
- this._convertToRightHandedSystemMap[descendant.uniqueId] = false;
1456
- });
1457
1391
  }
1458
- });
1392
+ }
1459
1393
  // Export babylon cameras to glTFCamera
1460
1394
  const cameraMap = new Map();
1461
- babylonScene.cameras.forEach((camera) => {
1395
+ this._babylonScene.cameras.forEach((camera) => {
1462
1396
  if (!this._options.shouldExportNode || this._options.shouldExportNode(camera)) {
1463
1397
  const glTFCamera = {
1464
1398
  type: camera.mode === Camera.PERSPECTIVE_CAMERA ? "perspective" /* CameraType.PERSPECTIVE */ : "orthographic" /* CameraType.ORTHOGRAPHIC */,
@@ -1490,8 +1424,8 @@ export class _Exporter {
1490
1424
  });
1491
1425
  const [exportNodes, exportMaterials] = this._getExportNodes(nodes);
1492
1426
  return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(exportMaterials, "image/png" /* ImageMimeType.PNG */, true).then(() => {
1493
- return this._createNodeMapAndAnimationsAsync(babylonScene, exportNodes, binaryWriter).then((nodeMap) => {
1494
- return this._createSkinsAsync(babylonScene, nodeMap, binaryWriter).then((skinMap) => {
1427
+ return this._createNodeMapAndAnimationsAsync(exportNodes, binaryWriter).then((nodeMap) => {
1428
+ return this._createSkinsAsync(nodeMap, binaryWriter).then((skinMap) => {
1495
1429
  this._nodeMap = nodeMap;
1496
1430
  this._totalByteLength = binaryWriter.getByteOffset();
1497
1431
  if (this._totalByteLength == undefined) {
@@ -1513,28 +1447,20 @@ export class _Exporter {
1513
1447
  if (babylonNode instanceof Camera) {
1514
1448
  glTFNode.camera = cameraMap.get(babylonNode);
1515
1449
  }
1516
- if (!babylonNode.parent || rootNodesToLeftHanded.indexOf(babylonNode.parent) !== -1) {
1517
- if (this._options.shouldExportNode && !this._options.shouldExportNode(babylonNode)) {
1518
- Tools.Log("Omitting " + babylonNode.name + " from scene.");
1450
+ if (this._options.shouldExportNode && !this._options.shouldExportNode(babylonNode)) {
1451
+ Tools.Log("Omitting " + babylonNode.name + " from scene.");
1452
+ }
1453
+ else {
1454
+ if (!babylonNode.parent && !this._babylonScene.useRightHandedSystem) {
1455
+ convertNodeHandedness(glTFNode);
1519
1456
  }
1520
- else {
1521
- const convertToRightHandedSystem = this._convertToRightHandedSystemMap[babylonNode.uniqueId];
1522
- if (convertToRightHandedSystem) {
1523
- if (glTFNode.translation) {
1524
- glTFNode.translation[2] *= -1;
1525
- glTFNode.translation[0] *= -1;
1526
- }
1527
- glTFNode.rotation = glTFNode.rotation
1528
- ? Quaternion.FromArray([0, 1, 0, 0]).multiply(Quaternion.FromArray(glTFNode.rotation)).asArray()
1529
- : Quaternion.FromArray([0, 1, 0, 0]).asArray();
1530
- }
1457
+ if (!babylonNode.parent || removedRootNodes.has(babylonNode.parent)) {
1531
1458
  scene.nodes.push(glTFNodeIndex);
1532
1459
  }
1533
1460
  }
1534
1461
  if (babylonNode instanceof Mesh) {
1535
- const babylonMesh = babylonNode;
1536
- if (babylonMesh.skeleton) {
1537
- glTFNode.skin = skinMap[babylonMesh.skeleton.uniqueId];
1462
+ if (babylonNode.skeleton) {
1463
+ glTFNode.skin = skinMap[babylonNode.skeleton.uniqueId];
1538
1464
  }
1539
1465
  }
1540
1466
  directDescendents = babylonNode.getDescendants(true);
@@ -1593,12 +1519,11 @@ export class _Exporter {
1593
1519
  }
1594
1520
  /**
1595
1521
  * Creates a mapping of Node unique id to node index and handles animations
1596
- * @param babylonScene Babylon Scene
1597
1522
  * @param nodes Babylon transform nodes
1598
1523
  * @param binaryWriter Buffer to write binary data to
1599
1524
  * @returns Node mapping of unique id to index
1600
1525
  */
1601
- _createNodeMapAndAnimationsAsync(babylonScene, nodes, binaryWriter) {
1526
+ _createNodeMapAndAnimationsAsync(nodes, binaryWriter) {
1602
1527
  let promiseChain = Promise.resolve();
1603
1528
  const nodeMap = {};
1604
1529
  let nodeIndex;
@@ -1610,8 +1535,7 @@ export class _Exporter {
1610
1535
  const idleGLTFAnimations = [];
1611
1536
  for (const babylonNode of nodes) {
1612
1537
  promiseChain = promiseChain.then(() => {
1613
- const convertToRightHandedSystem = this._convertToRightHandedSystemMap[babylonNode.uniqueId];
1614
- return this._createNodeAsync(babylonNode, binaryWriter, convertToRightHandedSystem).then((node) => {
1538
+ return this._createNodeAsync(babylonNode, binaryWriter).then((node) => {
1615
1539
  const promise = this._extensionsPostExportNodeAsync("createNodeAsync", node, babylonNode, nodeMap, binaryWriter);
1616
1540
  if (promise == null) {
1617
1541
  Tools.Warn(`Not exporting node ${babylonNode.name}`);
@@ -1625,10 +1549,10 @@ export class _Exporter {
1625
1549
  this._nodes.push(node);
1626
1550
  nodeIndex = this._nodes.length - 1;
1627
1551
  nodeMap[babylonNode.uniqueId] = nodeIndex;
1628
- if (!babylonScene.animationGroups.length) {
1629
- _GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, this._nodes, binaryWriter, this._bufferViews, this._accessors, convertToRightHandedSystem, this._animationSampleRate, this._options.shouldExportAnimation);
1552
+ if (!this._babylonScene.animationGroups.length) {
1553
+ _GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, this._nodes, binaryWriter, this._bufferViews, this._accessors, this._animationSampleRate, this._options.shouldExportAnimation);
1630
1554
  if (babylonNode.animations.length) {
1631
- _GLTFAnimation._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, this._nodes, binaryWriter, this._bufferViews, this._accessors, convertToRightHandedSystem, this._animationSampleRate, this._options.shouldExportAnimation);
1555
+ _GLTFAnimation._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, this._nodes, binaryWriter, this._bufferViews, this._accessors, this._animationSampleRate, this._options.shouldExportAnimation);
1632
1556
  }
1633
1557
  }
1634
1558
  });
@@ -1645,8 +1569,8 @@ export class _Exporter {
1645
1569
  this._animations.push(idleGLTFAnimation);
1646
1570
  }
1647
1571
  });
1648
- if (babylonScene.animationGroups.length) {
1649
- _GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(babylonScene, this._animations, nodeMap, this._nodes, binaryWriter, this._bufferViews, this._accessors, this._convertToRightHandedSystemMap, this._animationSampleRate, this._options.shouldExportAnimation);
1572
+ if (this._babylonScene.animationGroups.length) {
1573
+ _GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(this._babylonScene, this._animations, nodeMap, binaryWriter, this._bufferViews, this._accessors, this._animationSampleRate, this._options.shouldExportAnimation);
1650
1574
  }
1651
1575
  return nodeMap;
1652
1576
  });
@@ -1655,10 +1579,9 @@ export class _Exporter {
1655
1579
  * Creates a glTF node from a Babylon mesh
1656
1580
  * @param babylonNode Source Babylon mesh
1657
1581
  * @param binaryWriter Buffer for storing geometry data
1658
- * @param convertToRightHandedSystem Converts the values to right-handed
1659
1582
  * @returns glTF node
1660
1583
  */
1661
- _createNodeAsync(babylonNode, binaryWriter, convertToRightHandedSystem) {
1584
+ _createNodeAsync(babylonNode, binaryWriter) {
1662
1585
  return Promise.resolve().then(() => {
1663
1586
  // create node to hold translation/rotation/scale and the mesh
1664
1587
  const node = {};
@@ -1669,7 +1592,7 @@ export class _Exporter {
1669
1592
  }
1670
1593
  if (babylonNode instanceof TransformNode) {
1671
1594
  // Set transformation
1672
- this._setNodeTransformation(node, babylonNode, convertToRightHandedSystem);
1595
+ this._setNodeTransformation(node, babylonNode);
1673
1596
  if (babylonNode instanceof Mesh) {
1674
1597
  const morphTargetManager = babylonNode.morphTargetManager;
1675
1598
  if (morphTargetManager && morphTargetManager.numTargets > 0) {
@@ -1679,7 +1602,7 @@ export class _Exporter {
1679
1602
  }
1680
1603
  }
1681
1604
  }
1682
- return this._setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter, convertToRightHandedSystem).then(() => {
1605
+ return this._setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter).then(() => {
1683
1606
  if (mesh.primitives.length) {
1684
1607
  this._meshes.push(mesh);
1685
1608
  node.mesh = this._meshes.length - 1;
@@ -1688,7 +1611,7 @@ export class _Exporter {
1688
1611
  });
1689
1612
  }
1690
1613
  else if (babylonNode instanceof Camera) {
1691
- this._setCameraTransformation(node, babylonNode, convertToRightHandedSystem);
1614
+ this._setCameraTransformation(node, babylonNode);
1692
1615
  return node;
1693
1616
  }
1694
1617
  else {
@@ -1703,11 +1626,11 @@ export class _Exporter {
1703
1626
  * @param binaryWriter Buffer to write binary data to
1704
1627
  * @returns Node mapping of unique id to index
1705
1628
  */
1706
- _createSkinsAsync(babylonScene, nodeMap, binaryWriter) {
1629
+ _createSkinsAsync(nodeMap, binaryWriter) {
1707
1630
  var _a;
1708
1631
  const promiseChain = Promise.resolve();
1709
1632
  const skinMap = {};
1710
- for (const skeleton of babylonScene.skeletons) {
1633
+ for (const skeleton of this._babylonScene.skeletons) {
1711
1634
  if (skeleton.bones.length <= 0) {
1712
1635
  continue;
1713
1636
  }