@babylonjs/loaders 5.0.0-beta.5 → 5.0.0-beta.9

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.
@@ -46,9 +46,9 @@ export declare class GLTFLoader implements IGLTFLoader {
46
46
  _babylonLights: Light[];
47
47
  /** @hidden */
48
48
  _disableInstancedMesh: number;
49
+ private readonly _parent;
50
+ private readonly _extensions;
49
51
  private _disposed;
50
- private _parent;
51
- private _extensions;
52
52
  private _rootUrl;
53
53
  private _fileName;
54
54
  private _uniqueRootUrl;
@@ -57,6 +57,7 @@ export declare class GLTFLoader implements IGLTFLoader {
57
57
  private _babylonScene;
58
58
  private _rootBabylonMesh;
59
59
  private _defaultBabylonMaterialData;
60
+ private _postSceneLoadActions;
60
61
  private static _RegisteredExtensions;
61
62
  /**
62
63
  * The default glTF sampler.
@@ -149,6 +150,7 @@ export declare class GLTFLoader implements IGLTFLoader {
149
150
  private static _LoadTransform;
150
151
  private _loadSkinAsync;
151
152
  private _loadBones;
153
+ private _findSkeletonRootNode;
152
154
  private _loadBone;
153
155
  private _loadSkinInverseBindMatricesDataAsync;
154
156
  private _updateBoneMatrices;
@@ -71,10 +71,15 @@ var GLTFLoader = /** @class */ (function () {
71
71
  this._babylonLights = [];
72
72
  /** @hidden */
73
73
  this._disableInstancedMesh = 0;
74
- this._disposed = false;
75
74
  this._extensions = new Array();
75
+ this._disposed = false;
76
+ this._rootUrl = null;
77
+ this._fileName = null;
78
+ this._uniqueRootUrl = null;
79
+ this._bin = null;
76
80
  this._rootBabylonMesh = null;
77
81
  this._defaultBabylonMaterialData = {};
82
+ this._postSceneLoadActions = new Array();
78
83
  this._parent = parent;
79
84
  }
80
85
  /**
@@ -107,6 +112,9 @@ var GLTFLoader = /** @class */ (function () {
107
112
  * The object that represents the glTF JSON.
108
113
  */
109
114
  get: function () {
115
+ if (!this._gltf) {
116
+ throw new Error("glTF JSON is not available");
117
+ }
110
118
  return this._gltf;
111
119
  },
112
120
  enumerable: false,
@@ -137,6 +145,9 @@ var GLTFLoader = /** @class */ (function () {
137
145
  * The Babylon scene when loading the asset.
138
146
  */
139
147
  get: function () {
148
+ if (!this._babylonScene) {
149
+ throw new Error("Scene is not available");
150
+ }
140
151
  return this._babylonScene;
141
152
  },
142
153
  enumerable: false,
@@ -159,14 +170,14 @@ var GLTFLoader = /** @class */ (function () {
159
170
  }
160
171
  this._disposed = true;
161
172
  this._completePromises.length = 0;
162
- for (var name_1 in this._extensions) {
163
- var extension = this._extensions[name_1];
164
- extension.dispose && extension.dispose();
165
- delete this._extensions[name_1];
166
- }
167
- this._gltf = null;
168
- this._babylonScene = null;
173
+ this._extensions.forEach(function (extension) { return extension.dispose && extension.dispose(); });
174
+ this._extensions.length = 0;
175
+ this._gltf = null; // TODO
176
+ this._bin = null;
177
+ this._babylonScene = null; // TODO
169
178
  this._rootBabylonMesh = null;
179
+ this._defaultBabylonMaterialData = {};
180
+ this._postSceneLoadActions.length = 0;
170
181
  this._parent.dispose();
171
182
  };
172
183
  /** @hidden */
@@ -349,10 +360,10 @@ var GLTFLoader = /** @class */ (function () {
349
360
  }
350
361
  };
351
362
  GLTFLoader.prototype._loadExtensions = function () {
352
- for (var name_2 in GLTFLoader._RegisteredExtensions) {
353
- var extension = GLTFLoader._RegisteredExtensions[name_2].factory(this);
354
- if (extension.name !== name_2) {
355
- Logger.Warn("The name of the glTF loader extension instance does not match the registered name: ".concat(extension.name, " !== ").concat(name_2));
363
+ for (var name_1 in GLTFLoader._RegisteredExtensions) {
364
+ var extension = GLTFLoader._RegisteredExtensions[name_1].factory(this);
365
+ if (extension.name !== name_1) {
366
+ Logger.Warn("The name of the glTF loader extension instance does not match the registered name: ".concat(extension.name, " !== ").concat(name_1));
356
367
  }
357
368
  this._extensions.push(extension);
358
369
  this._parent.onExtensionLoadedObservable.notifyObservers(extension);
@@ -362,16 +373,16 @@ var GLTFLoader = /** @class */ (function () {
362
373
  };
363
374
  GLTFLoader.prototype._checkExtensions = function () {
364
375
  if (this._gltf.extensionsRequired) {
365
- var _loop_1 = function (name_3) {
366
- var available = this_1._extensions.some(function (extension) { return extension.name === name_3 && extension.enabled; });
376
+ var _loop_1 = function (name_2) {
377
+ var available = this_1._extensions.some(function (extension) { return extension.name === name_2 && extension.enabled; });
367
378
  if (!available) {
368
- throw new Error("Require extension ".concat(name_3, " is not available"));
379
+ throw new Error("Require extension ".concat(name_2, " is not available"));
369
380
  }
370
381
  };
371
382
  var this_1 = this;
372
383
  for (var _i = 0, _a = this._gltf.extensionsRequired; _i < _a.length; _i++) {
373
- var name_3 = _a[_i];
374
- _loop_1(name_3);
384
+ var name_2 = _a[_i];
385
+ _loop_1(name_2);
375
386
  }
376
387
  }
377
388
  };
@@ -428,18 +439,9 @@ var GLTFLoader = /** @class */ (function () {
428
439
  }));
429
440
  }
430
441
  }
431
- // Link all Babylon bones for each glTF node with the corresponding Babylon transform node.
432
- // A glTF joint is a pointer to a glTF node in the glTF node hierarchy similar to Unity3D.
433
- if (this._gltf.nodes) {
434
- for (var _b = 0, _c = this._gltf.nodes; _b < _c.length; _b++) {
435
- var node = _c[_b];
436
- if (node._babylonTransformNode && node._babylonBones) {
437
- for (var _d = 0, _e = node._babylonBones; _d < _e.length; _d++) {
438
- var babylonBone = _e[_d];
439
- babylonBone.linkTransformNode(node._babylonTransformNode);
440
- }
441
- }
442
- }
442
+ for (var _b = 0, _c = this._postSceneLoadActions; _b < _c.length; _b++) {
443
+ var action = _c[_b];
444
+ action();
443
445
  }
444
446
  promises.push(this._loadAnimationsAsync());
445
447
  this.logClose();
@@ -591,7 +593,7 @@ var GLTFLoader = /** @class */ (function () {
591
593
  }
592
594
  assign(babylonTransformNode);
593
595
  };
594
- if (node.mesh == undefined) {
596
+ if (node.mesh == undefined || node.skin != undefined) {
595
597
  var nodeName = node.name || "node".concat(node.index);
596
598
  this._babylonScene._blockEntityCollection = !!this._assetContainer;
597
599
  node._babylonTransformNode = new TransformNode(nodeName, this._babylonScene);
@@ -599,9 +601,37 @@ var GLTFLoader = /** @class */ (function () {
599
601
  this._babylonScene._blockEntityCollection = false;
600
602
  loadNode(node._babylonTransformNode);
601
603
  }
602
- else {
603
- var mesh = ArrayItem.Get("".concat(context, "/mesh"), this._gltf.meshes, node.mesh);
604
- promises.push(this._loadMeshAsync("/meshes/".concat(mesh.index), node, mesh, loadNode));
604
+ if (node.mesh != undefined) {
605
+ if (node.skin == undefined) {
606
+ var mesh = ArrayItem.Get("".concat(context, "/mesh"), this._gltf.meshes, node.mesh);
607
+ promises.push(this._loadMeshAsync("/meshes/".concat(mesh.index), node, mesh, loadNode));
608
+ }
609
+ else {
610
+ // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note)
611
+ // This code path will place the skinned mesh as a sibling of the skeleton root node without loading the
612
+ // transform, which effectively ignores the transform of the skinned mesh, as per spec.
613
+ var mesh = ArrayItem.Get("".concat(context, "/mesh"), this._gltf.meshes, node.mesh);
614
+ promises.push(this._loadMeshAsync("/meshes/".concat(mesh.index), node, mesh, function (babylonTransformNode) {
615
+ GLTFLoader.AddPointerMetadata(babylonTransformNode, context);
616
+ var skin = ArrayItem.Get("".concat(context, "/skin"), _this._gltf.skins, node.skin);
617
+ promises.push(_this._loadSkinAsync("/skins/".concat(skin.index), node, skin, function (babylonSkeleton) {
618
+ _this._forEachPrimitive(node, function (babylonMesh) {
619
+ babylonMesh.skeleton = babylonSkeleton;
620
+ });
621
+ // Wait until the scene is loaded to ensure the skeleton root node has been loaded.
622
+ _this._postSceneLoadActions.push(function () {
623
+ if (skin.skeleton != undefined) {
624
+ // Place the skinned mesh node as a sibling of the skeleton root node.
625
+ var skeletonRootNode = ArrayItem.Get("/skins/".concat(skin.index, "/skeleton"), _this._gltf.nodes, skin.skeleton);
626
+ babylonTransformNode.parent = skeletonRootNode.parent._babylonTransformNode;
627
+ }
628
+ else {
629
+ babylonTransformNode.parent = _this._rootBabylonMesh;
630
+ }
631
+ });
632
+ }));
633
+ }));
634
+ }
605
635
  }
606
636
  this.logClose();
607
637
  return Promise.all(promises).then(function () {
@@ -649,10 +679,6 @@ var GLTFLoader = /** @class */ (function () {
649
679
  }));
650
680
  }
651
681
  }
652
- if (node.skin != undefined) {
653
- var skin = ArrayItem.Get("".concat(context, "/skin"), this._gltf.skins, node.skin);
654
- promises.push(this._loadSkinAsync("/skins/".concat(skin.index), node, skin));
655
- }
656
682
  assign(node._babylonTransformNode);
657
683
  this.logClose();
658
684
  return Promise.all(promises).then(function () {
@@ -843,8 +869,8 @@ var GLTFLoader = /** @class */ (function () {
843
869
  babylonMesh.morphTargetManager.areUpdatesFrozen = true;
844
870
  for (var index = 0; index < primitive.targets.length; index++) {
845
871
  var weight = node.weights ? node.weights[index] : mesh.weights ? mesh.weights[index] : 0;
846
- var name_4 = targetNames ? targetNames[index] : "morphTarget".concat(index);
847
- babylonMesh.morphTargetManager.addTarget(new MorphTarget(name_4, weight, babylonMesh.getScene()));
872
+ var name_3 = targetNames ? targetNames[index] : "morphTarget".concat(index);
873
+ babylonMesh.morphTargetManager.addTarget(new MorphTarget(name_3, weight, babylonMesh.getScene()));
848
874
  // TODO: tell the target whether it has positions, normals, tangents
849
875
  }
850
876
  };
@@ -936,19 +962,14 @@ var GLTFLoader = /** @class */ (function () {
936
962
  babylonNode.rotationQuaternion = rotation;
937
963
  babylonNode.scaling = scaling;
938
964
  };
939
- GLTFLoader.prototype._loadSkinAsync = function (context, node, skin) {
965
+ GLTFLoader.prototype._loadSkinAsync = function (context, node, skin, assign) {
940
966
  var _this = this;
941
967
  var extensionPromise = this._extensionsLoadSkinAsync(context, node, skin);
942
968
  if (extensionPromise) {
943
969
  return extensionPromise;
944
970
  }
945
- var assignSkeleton = function (skeleton) {
946
- _this._forEachPrimitive(node, function (babylonMesh) {
947
- babylonMesh.skeleton = skeleton;
948
- });
949
- };
950
971
  if (skin._data) {
951
- assignSkeleton(skin._data.babylonSkeleton);
972
+ assign(skin._data.babylonSkeleton);
952
973
  return skin._data.promise;
953
974
  }
954
975
  var skeletonId = "skeleton".concat(skin.index);
@@ -956,10 +977,7 @@ var GLTFLoader = /** @class */ (function () {
956
977
  var babylonSkeleton = new Skeleton(skin.name || skeletonId, skeletonId, this._babylonScene);
957
978
  babylonSkeleton._parentContainer = this._assetContainer;
958
979
  this._babylonScene._blockEntityCollection = false;
959
- // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note)
960
- babylonSkeleton.overrideMesh = this._rootBabylonMesh;
961
980
  this._loadBones(context, skin, babylonSkeleton);
962
- assignSkeleton(babylonSkeleton);
963
981
  var promise = this._loadSkinInverseBindMatricesDataAsync(context, skin).then(function (inverseBindMatricesData) {
964
982
  _this._updateBoneMatrices(babylonSkeleton, inverseBindMatricesData);
965
983
  });
@@ -967,9 +985,19 @@ var GLTFLoader = /** @class */ (function () {
967
985
  babylonSkeleton: babylonSkeleton,
968
986
  promise: promise
969
987
  };
988
+ assign(babylonSkeleton);
970
989
  return promise;
971
990
  };
972
991
  GLTFLoader.prototype._loadBones = function (context, skin, babylonSkeleton) {
992
+ if (skin.skeleton == undefined) {
993
+ var rootNode = this._findSkeletonRootNode("".concat(context, "/joints"), skin.joints);
994
+ if (rootNode) {
995
+ skin.skeleton = rootNode.index;
996
+ }
997
+ else {
998
+ Logger.Warn("".concat(context, ": Failed to find common root"));
999
+ }
1000
+ }
973
1001
  var babylonBones = {};
974
1002
  for (var _i = 0, _a = skin.joints; _i < _a.length; _i++) {
975
1003
  var index = _a[_i];
@@ -977,20 +1005,57 @@ var GLTFLoader = /** @class */ (function () {
977
1005
  this._loadBone(node, skin, babylonSkeleton, babylonBones);
978
1006
  }
979
1007
  };
1008
+ GLTFLoader.prototype._findSkeletonRootNode = function (context, joints) {
1009
+ var paths = {};
1010
+ for (var _i = 0, joints_1 = joints; _i < joints_1.length; _i++) {
1011
+ var index = joints_1[_i];
1012
+ var path = new Array();
1013
+ var node = ArrayItem.Get("".concat(context, "/").concat(index), this._gltf.nodes, index);
1014
+ while (node.index !== -1) {
1015
+ path.unshift(node);
1016
+ node = node.parent;
1017
+ }
1018
+ paths[index] = path;
1019
+ }
1020
+ var rootNode = null;
1021
+ for (var i = 0;; ++i) {
1022
+ var path = paths[joints[0]];
1023
+ if (i >= path.length) {
1024
+ return rootNode;
1025
+ }
1026
+ var node = path[i];
1027
+ for (var j = 1; j < joints.length; ++j) {
1028
+ path = paths[joints[j]];
1029
+ if (i >= path.length || node !== path[i]) {
1030
+ return rootNode;
1031
+ }
1032
+ }
1033
+ rootNode = node;
1034
+ }
1035
+ };
980
1036
  GLTFLoader.prototype._loadBone = function (node, skin, babylonSkeleton, babylonBones) {
981
1037
  var babylonBone = babylonBones[node.index];
982
1038
  if (babylonBone) {
983
1039
  return babylonBone;
984
1040
  }
985
- var babylonParentBone = null;
986
- if (node.parent && node.parent._babylonTransformNode !== this._rootBabylonMesh) {
987
- babylonParentBone = this._loadBone(node.parent, skin, babylonSkeleton, babylonBones);
1041
+ var parentBabylonBone = null;
1042
+ if (node.index !== skin.skeleton) {
1043
+ if (node.parent && node.parent.index !== -1) {
1044
+ parentBabylonBone = this._loadBone(node.parent, skin, babylonSkeleton, babylonBones);
1045
+ }
1046
+ else if (skin.skeleton !== undefined) {
1047
+ Logger.Warn("/skins/".concat(skin.index, "/skeleton: Skeleton node is not a common root"));
1048
+ }
988
1049
  }
989
1050
  var boneIndex = skin.joints.indexOf(node.index);
990
- babylonBone = new Bone(node.name || "joint".concat(node.index), babylonSkeleton, babylonParentBone, this._getNodeMatrix(node), null, null, boneIndex);
1051
+ babylonBone = new Bone(node.name || "joint".concat(node.index), babylonSkeleton, parentBabylonBone, this._getNodeMatrix(node), null, null, boneIndex);
991
1052
  babylonBones[node.index] = babylonBone;
992
- node._babylonBones = node._babylonBones || [];
993
- node._babylonBones.push(babylonBone);
1053
+ // Wait until the scene is loaded to ensure the transform nodes are loaded.
1054
+ this._postSceneLoadActions.push(function () {
1055
+ // Link the Babylon bone with the corresponding Babylon transform node.
1056
+ // A glTF joint is a pointer to a glTF node in the glTF node hierarchy similar to Unity3D.
1057
+ babylonBone.linkTransformNode(node._babylonTransformNode);
1058
+ });
994
1059
  return babylonBone;
995
1060
  };
996
1061
  GLTFLoader.prototype._loadSkinInverseBindMatricesDataAsync = function (context, skin) {
@@ -1179,34 +1244,34 @@ var GLTFLoader = /** @class */ (function () {
1179
1244
  var getNextOutputValue;
1180
1245
  switch (targetPath) {
1181
1246
  case "position": {
1182
- getNextOutputValue = function () {
1183
- var value = Vector3.FromArray(data.output, outputBufferOffset);
1247
+ getNextOutputValue = function (scale) {
1248
+ var value = Vector3.FromArray(data.output, outputBufferOffset).scaleInPlace(scale);
1184
1249
  outputBufferOffset += 3;
1185
1250
  return value;
1186
1251
  };
1187
1252
  break;
1188
1253
  }
1189
1254
  case "rotationQuaternion": {
1190
- getNextOutputValue = function () {
1191
- var value = Quaternion.FromArray(data.output, outputBufferOffset);
1255
+ getNextOutputValue = function (scale) {
1256
+ var value = Quaternion.FromArray(data.output, outputBufferOffset).scaleInPlace(scale);
1192
1257
  outputBufferOffset += 4;
1193
1258
  return value;
1194
1259
  };
1195
1260
  break;
1196
1261
  }
1197
1262
  case "scaling": {
1198
- getNextOutputValue = function () {
1199
- var value = Vector3.FromArray(data.output, outputBufferOffset);
1263
+ getNextOutputValue = function (scale) {
1264
+ var value = Vector3.FromArray(data.output, outputBufferOffset).scaleInPlace(scale);
1200
1265
  outputBufferOffset += 3;
1201
1266
  return value;
1202
1267
  };
1203
1268
  break;
1204
1269
  }
1205
1270
  case "influence": {
1206
- getNextOutputValue = function () {
1271
+ getNextOutputValue = function (scale) {
1207
1272
  var value = new Array(targetNode._numMorphTargets);
1208
1273
  for (var i = 0; i < targetNode._numMorphTargets; i++) {
1209
- value[i] = data.output[outputBufferOffset++];
1274
+ value[i] = data.output[outputBufferOffset++] * scale;
1210
1275
  }
1211
1276
  return value;
1212
1277
  };
@@ -1217,25 +1282,26 @@ var GLTFLoader = /** @class */ (function () {
1217
1282
  switch (data.interpolation) {
1218
1283
  case "STEP" /* STEP */: {
1219
1284
  getNextKey = function (frameIndex) { return ({
1220
- frame: data.input[frameIndex],
1221
- value: getNextOutputValue(),
1285
+ frame: data.input[frameIndex] * _this.parent.targetFps,
1286
+ value: getNextOutputValue(1),
1222
1287
  interpolation: AnimationKeyInterpolation.STEP
1223
1288
  }); };
1224
1289
  break;
1225
1290
  }
1226
1291
  case "LINEAR" /* LINEAR */: {
1227
1292
  getNextKey = function (frameIndex) { return ({
1228
- frame: data.input[frameIndex],
1229
- value: getNextOutputValue()
1293
+ frame: data.input[frameIndex] * _this.parent.targetFps,
1294
+ value: getNextOutputValue(1)
1230
1295
  }); };
1231
1296
  break;
1232
1297
  }
1233
1298
  case "CUBICSPLINE" /* CUBICSPLINE */: {
1299
+ var invTargetFps_1 = 1 / _this.parent.targetFps;
1234
1300
  getNextKey = function (frameIndex) { return ({
1235
- frame: data.input[frameIndex],
1236
- inTangent: getNextOutputValue(),
1237
- value: getNextOutputValue(),
1238
- outTangent: getNextOutputValue()
1301
+ frame: data.input[frameIndex] * _this.parent.targetFps,
1302
+ inTangent: getNextOutputValue(invTargetFps_1),
1303
+ value: getNextOutputValue(1),
1304
+ outTangent: getNextOutputValue(invTargetFps_1)
1239
1305
  }); };
1240
1306
  break;
1241
1307
  }
@@ -1247,7 +1313,7 @@ var GLTFLoader = /** @class */ (function () {
1247
1313
  if (targetPath === "influence") {
1248
1314
  var _loop_2 = function (targetIndex) {
1249
1315
  var animationName = "".concat(babylonAnimationGroup.name, "_channel").concat(babylonAnimationGroup.targetedAnimations.length);
1250
- var babylonAnimation = new Animation(animationName, targetPath, 1, animationType);
1316
+ var babylonAnimation = new Animation(animationName, targetPath, _this.parent.targetFps, animationType);
1251
1317
  babylonAnimation.setKeys(keys.map(function (key) { return ({
1252
1318
  frame: key.frame,
1253
1319
  inTangent: key.inTangent ? key.inTangent[targetIndex] : undefined,
@@ -1268,7 +1334,7 @@ var GLTFLoader = /** @class */ (function () {
1268
1334
  }
1269
1335
  else {
1270
1336
  var animationName = "".concat(babylonAnimationGroup.name, "_channel").concat(babylonAnimationGroup.targetedAnimations.length);
1271
- var babylonAnimation = new Animation(animationName, targetPath, 1, animationType);
1337
+ var babylonAnimation = new Animation(animationName, targetPath, _this.parent.targetFps, animationType);
1272
1338
  babylonAnimation.setKeys(keys);
1273
1339
  if (animationTargetOverride != null && animationTargetOverride.animations != null) {
1274
1340
  animationTargetOverride.animations.push(babylonAnimation);