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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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);