|
@@ -2472,8 +2472,8 @@ var BABYLON;
|
|
if (_this._gltf.nodes) {
|
|
if (_this._gltf.nodes) {
|
|
for (var i = 0; i < _this._gltf.nodes.length; i++) {
|
|
for (var i = 0; i < _this._gltf.nodes.length; i++) {
|
|
var node = _this._gltf.nodes[i];
|
|
var node = _this._gltf.nodes[i];
|
|
- if (node.babylonNode instanceof BABYLON.AbstractMesh) {
|
|
|
|
- meshes.push(node.babylonNode);
|
|
|
|
|
|
+ if (node.babylonMesh) {
|
|
|
|
+ meshes.push(node.babylonMesh);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -2539,8 +2539,8 @@ var BABYLON;
|
|
var nodes = this._gltf.nodes;
|
|
var nodes = this._gltf.nodes;
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
var node = nodes[i];
|
|
var node = nodes[i];
|
|
- if (node.babylonNode instanceof BABYLON.Mesh) {
|
|
|
|
- node.babylonNode.isVisible = true;
|
|
|
|
|
|
+ if (node.babylonMesh) {
|
|
|
|
+ node.babylonMesh.isVisible = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
@@ -2584,17 +2584,13 @@ var BABYLON;
|
|
};
|
|
};
|
|
GLTFLoader.prototype._loadSkin = function (node) {
|
|
GLTFLoader.prototype._loadSkin = function (node) {
|
|
var _this = this;
|
|
var _this = this;
|
|
- if (node.babylonNode) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
if (node.skin !== undefined) {
|
|
if (node.skin !== undefined) {
|
|
var skin = this._gltf.skins[node.skin];
|
|
var skin = this._gltf.skins[node.skin];
|
|
var skeletonId = "skeleton" + node.skin;
|
|
var skeletonId = "skeleton" + node.skin;
|
|
skin.babylonSkeleton = new BABYLON.Skeleton(skin.name || skeletonId, skeletonId, this._babylonScene);
|
|
skin.babylonSkeleton = new BABYLON.Skeleton(skin.name || skeletonId, skeletonId, this._babylonScene);
|
|
|
|
+ skin.index = node.skin;
|
|
for (var i = 0; i < skin.joints.length; i++) {
|
|
for (var i = 0; i < skin.joints.length; i++) {
|
|
- var jointIndex = skin.joints[i];
|
|
|
|
- var jointNode = this._gltf.nodes[jointIndex];
|
|
|
|
- jointNode.babylonNode = new BABYLON.Bone(jointNode.name || "bone" + jointIndex, skin.babylonSkeleton);
|
|
|
|
|
|
+ this._createBone(this._gltf.nodes[skin.joints[i]], skin);
|
|
}
|
|
}
|
|
if (skin.skeleton === undefined) {
|
|
if (skin.skeleton === undefined) {
|
|
// TODO: handle when skeleton is not defined
|
|
// TODO: handle when skeleton is not defined
|
|
@@ -2614,30 +2610,28 @@ var BABYLON;
|
|
GLTFLoader.prototype._updateBone = function (node, parentNode, skin, inverseBindMatrixData) {
|
|
GLTFLoader.prototype._updateBone = function (node, parentNode, skin, inverseBindMatrixData) {
|
|
var jointIndex = skin.joints.indexOf(node.index);
|
|
var jointIndex = skin.joints.indexOf(node.index);
|
|
if (jointIndex === -1) {
|
|
if (jointIndex === -1) {
|
|
- // TODO: handle non-joint in between two joints
|
|
|
|
- throw new Error("Not implemented");
|
|
|
|
|
|
+ this._createBone(node, skin);
|
|
}
|
|
}
|
|
- var babylonBone = node.babylonNode;
|
|
|
|
|
|
+ var babylonBone = node.babylonSkinToBones[skin.index];
|
|
// TODO: explain the math
|
|
// TODO: explain the math
|
|
- var matrix = BABYLON.Matrix.FromArray(inverseBindMatrixData, jointIndex * 16);
|
|
|
|
|
|
+ var matrix = jointIndex === -1 ? BABYLON.Matrix.Identity() : BABYLON.Matrix.FromArray(inverseBindMatrixData, jointIndex * 16);
|
|
matrix.invertToRef(matrix);
|
|
matrix.invertToRef(matrix);
|
|
if (parentNode) {
|
|
if (parentNode) {
|
|
- babylonBone.setParent(parentNode.babylonNode, false);
|
|
|
|
|
|
+ babylonBone.setParent(parentNode.babylonSkinToBones[skin.index], false);
|
|
matrix.multiplyToRef(babylonBone.getParent().getInvertedAbsoluteTransform(), matrix);
|
|
matrix.multiplyToRef(babylonBone.getParent().getInvertedAbsoluteTransform(), matrix);
|
|
}
|
|
}
|
|
babylonBone.updateMatrix(matrix);
|
|
babylonBone.updateMatrix(matrix);
|
|
return true;
|
|
return true;
|
|
};
|
|
};
|
|
|
|
+ GLTFLoader.prototype._createBone = function (node, skin) {
|
|
|
|
+ var babylonBone = new BABYLON.Bone(node.name || "bone" + node.index, skin.babylonSkeleton);
|
|
|
|
+ node.babylonSkinToBones = node.babylonSkinToBones || {};
|
|
|
|
+ node.babylonSkinToBones[skin.index] = babylonBone;
|
|
|
|
+ node.babylonAnimationTargets = node.babylonAnimationTargets || [];
|
|
|
|
+ node.babylonAnimationTargets.push(babylonBone);
|
|
|
|
+ return babylonBone;
|
|
|
|
+ };
|
|
GLTFLoader.prototype._loadMesh = function (node, parentNode) {
|
|
GLTFLoader.prototype._loadMesh = function (node, parentNode) {
|
|
- if (node.babylonNode) {
|
|
|
|
- if (node.babylonNode instanceof BABYLON.Bone) {
|
|
|
|
- if (node.mesh !== undefined) {
|
|
|
|
- // TODO: handle mesh attached to bone
|
|
|
|
- throw new Error("Not implemented");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
var babylonMesh = new BABYLON.Mesh(node.name || "mesh" + node.index, this._babylonScene);
|
|
var babylonMesh = new BABYLON.Mesh(node.name || "mesh" + node.index, this._babylonScene);
|
|
babylonMesh.isVisible = false;
|
|
babylonMesh.isVisible = false;
|
|
this._loadTransform(node, babylonMesh);
|
|
this._loadTransform(node, babylonMesh);
|
|
@@ -2645,8 +2639,10 @@ var BABYLON;
|
|
var mesh = this._gltf.meshes[node.mesh];
|
|
var mesh = this._gltf.meshes[node.mesh];
|
|
this._loadMeshData(node, mesh, babylonMesh);
|
|
this._loadMeshData(node, mesh, babylonMesh);
|
|
}
|
|
}
|
|
- babylonMesh.parent = parentNode ? parentNode.babylonNode : null;
|
|
|
|
- node.babylonNode = babylonMesh;
|
|
|
|
|
|
+ babylonMesh.parent = parentNode ? parentNode.babylonMesh : null;
|
|
|
|
+ node.babylonMesh = babylonMesh;
|
|
|
|
+ node.babylonAnimationTargets = node.babylonAnimationTargets || [];
|
|
|
|
+ node.babylonAnimationTargets.push(node.babylonMesh);
|
|
if (node.skin !== undefined) {
|
|
if (node.skin !== undefined) {
|
|
var skin = this._gltf.skins[node.skin];
|
|
var skin = this._gltf.skins[node.skin];
|
|
babylonMesh.skeleton = skin.babylonSkeleton;
|
|
babylonMesh.skeleton = skin.babylonSkeleton;
|
|
@@ -2666,25 +2662,41 @@ var BABYLON;
|
|
var vertexData = new BABYLON.VertexData();
|
|
var vertexData = new BABYLON.VertexData();
|
|
vertexData.positions = [];
|
|
vertexData.positions = [];
|
|
vertexData.indices = [];
|
|
vertexData.indices = [];
|
|
|
|
+ var subMeshInfos = [];
|
|
var primitivesLoaded = 0;
|
|
var primitivesLoaded = 0;
|
|
var numPrimitives = mesh.primitives.length;
|
|
var numPrimitives = mesh.primitives.length;
|
|
- for (var i = 0; i < numPrimitives; i++) {
|
|
|
|
|
|
+ var _loop_1 = function () {
|
|
var primitive = mesh.primitives[i];
|
|
var primitive = mesh.primitives[i];
|
|
if (primitive.mode && primitive.mode !== GLTF2.EMeshPrimitiveMode.TRIANGLES) {
|
|
if (primitive.mode && primitive.mode !== GLTF2.EMeshPrimitiveMode.TRIANGLES) {
|
|
// TODO: handle other primitive modes
|
|
// TODO: handle other primitive modes
|
|
throw new Error("Not implemented");
|
|
throw new Error("Not implemented");
|
|
}
|
|
}
|
|
- this._createMorphTargets(node, mesh, primitive, babylonMesh);
|
|
|
|
- this._loadVertexDataAsync(primitive, function (subVertexData) {
|
|
|
|
|
|
+ this_1._createMorphTargets(node, mesh, primitive, babylonMesh);
|
|
|
|
+ this_1._loadVertexDataAsync(primitive, function (subVertexData) {
|
|
_this._loadMorphTargetsData(mesh, primitive, subVertexData, babylonMesh);
|
|
_this._loadMorphTargetsData(mesh, primitive, subVertexData, babylonMesh);
|
|
- var subMesh = new BABYLON.SubMesh(multiMaterial.subMaterials.length, vertexData.positions.length, subVertexData.positions.length, vertexData.indices.length, subVertexData.indices.length, babylonMesh);
|
|
|
|
|
|
+ subMeshInfos.push({
|
|
|
|
+ materialIndex: multiMaterial.subMaterials.length,
|
|
|
|
+ verticesStart: vertexData.positions.length,
|
|
|
|
+ verticesCount: subVertexData.positions.length,
|
|
|
|
+ indicesStart: vertexData.indices.length,
|
|
|
|
+ indicesCount: subVertexData.indices.length
|
|
|
|
+ });
|
|
var subMaterial = primitive.material === undefined ? _this._getDefaultMaterial() : GLTF2.GLTFLoaderExtension.LoadMaterial(primitive.material);
|
|
var subMaterial = primitive.material === undefined ? _this._getDefaultMaterial() : GLTF2.GLTFLoaderExtension.LoadMaterial(primitive.material);
|
|
multiMaterial.subMaterials.push(subMaterial);
|
|
multiMaterial.subMaterials.push(subMaterial);
|
|
vertexData.merge(subVertexData);
|
|
vertexData.merge(subVertexData);
|
|
if (++primitivesLoaded === numPrimitives) {
|
|
if (++primitivesLoaded === numPrimitives) {
|
|
geometry.setAllVerticesData(vertexData, false);
|
|
geometry.setAllVerticesData(vertexData, false);
|
|
|
|
+ // Sub meshes must be created after setting vertex data because of mesh._createGlobalSubMesh.
|
|
|
|
+ for (var i = 0; i < subMeshInfos.length; i++) {
|
|
|
|
+ var info = subMeshInfos[i];
|
|
|
|
+ new BABYLON.SubMesh(info.materialIndex, info.verticesStart, info.verticesCount, info.indicesStart, info.indicesCount, babylonMesh);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
+ };
|
|
|
|
+ var this_1 = this;
|
|
|
|
+ for (var i = 0; i < numPrimitives; i++) {
|
|
|
|
+ _loop_1();
|
|
}
|
|
}
|
|
};
|
|
};
|
|
GLTFLoader.prototype._loadVertexDataAsync = function (primitive, onSuccess) {
|
|
GLTFLoader.prototype._loadVertexDataAsync = function (primitive, onSuccess) {
|
|
@@ -2697,9 +2709,9 @@ var BABYLON;
|
|
var vertexData = new BABYLON.VertexData();
|
|
var vertexData = new BABYLON.VertexData();
|
|
var loadedAttributes = 0;
|
|
var loadedAttributes = 0;
|
|
var numAttributes = Object.keys(attributes).length;
|
|
var numAttributes = Object.keys(attributes).length;
|
|
- var _loop_1 = function (semantic) {
|
|
|
|
- accessor = this_1._gltf.accessors[attributes[semantic]];
|
|
|
|
- this_1._loadAccessorAsync(accessor, function (data) {
|
|
|
|
|
|
+ var _loop_2 = function (semantic) {
|
|
|
|
+ accessor = this_2._gltf.accessors[attributes[semantic]];
|
|
|
|
+ this_2._loadAccessorAsync(accessor, function (data) {
|
|
switch (semantic) {
|
|
switch (semantic) {
|
|
case "NORMAL":
|
|
case "NORMAL":
|
|
vertexData.normals = data;
|
|
vertexData.normals = data;
|
|
@@ -2745,9 +2757,9 @@ var BABYLON;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
};
|
|
};
|
|
- var this_1 = this, accessor;
|
|
|
|
|
|
+ var this_2 = this, accessor;
|
|
for (var semantic in attributes) {
|
|
for (var semantic in attributes) {
|
|
- _loop_1(semantic);
|
|
|
|
|
|
+ _loop_2(semantic);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
GLTFLoader.prototype._createMorphTargets = function (node, mesh, primitive, babylonMesh) {
|
|
GLTFLoader.prototype._createMorphTargets = function (node, mesh, primitive, babylonMesh) {
|
|
@@ -2768,12 +2780,12 @@ var BABYLON;
|
|
if (!targets) {
|
|
if (!targets) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- var _loop_2 = function () {
|
|
|
|
|
|
+ var _loop_3 = function () {
|
|
var babylonMorphTarget = babylonMesh.morphTargetManager.getTarget(index);
|
|
var babylonMorphTarget = babylonMesh.morphTargetManager.getTarget(index);
|
|
attributes = targets[index];
|
|
attributes = targets[index];
|
|
- var _loop_3 = function (semantic) {
|
|
|
|
- accessor = this_2._gltf.accessors[attributes[semantic]];
|
|
|
|
- this_2._loadAccessorAsync(accessor, function (data) {
|
|
|
|
|
|
+ var _loop_4 = function (semantic) {
|
|
|
|
+ accessor = this_3._gltf.accessors[attributes[semantic]];
|
|
|
|
+ this_3._loadAccessorAsync(accessor, function (data) {
|
|
if (accessor.name) {
|
|
if (accessor.name) {
|
|
babylonMorphTarget.name = accessor.name;
|
|
babylonMorphTarget.name = accessor.name;
|
|
}
|
|
}
|
|
@@ -2808,12 +2820,12 @@ var BABYLON;
|
|
});
|
|
});
|
|
};
|
|
};
|
|
for (var semantic in attributes) {
|
|
for (var semantic in attributes) {
|
|
- _loop_3(semantic);
|
|
|
|
|
|
+ _loop_4(semantic);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
- var this_2 = this, attributes, accessor;
|
|
|
|
|
|
+ var this_3 = this, attributes, accessor;
|
|
for (var index = 0; index < targets.length; index++) {
|
|
for (var index = 0; index < targets.length; index++) {
|
|
- _loop_2();
|
|
|
|
|
|
+ _loop_3();
|
|
}
|
|
}
|
|
};
|
|
};
|
|
GLTFLoader.prototype._loadTransform = function (node, babylonMesh) {
|
|
GLTFLoader.prototype._loadTransform = function (node, babylonMesh) {
|
|
@@ -2883,7 +2895,7 @@ var BABYLON;
|
|
var channel = animation.channels[channelIndex];
|
|
var channel = animation.channels[channelIndex];
|
|
var samplerIndex = channel.sampler;
|
|
var samplerIndex = channel.sampler;
|
|
var sampler = animation.samplers[samplerIndex];
|
|
var sampler = animation.samplers[samplerIndex];
|
|
- var targetNode = this._gltf.nodes[channel.target.node].babylonNode;
|
|
|
|
|
|
+ var targetNode = this._gltf.nodes[channel.target.node];
|
|
if (!targetNode) {
|
|
if (!targetNode) {
|
|
BABYLON.Tools.Warn("Animation channel target node (" + channel.target.node + ") does not exist");
|
|
BABYLON.Tools.Warn("Animation channel target node (" + channel.target.node + ") does not exist");
|
|
return;
|
|
return;
|
|
@@ -2928,7 +2940,7 @@ var BABYLON;
|
|
return value;
|
|
return value;
|
|
},
|
|
},
|
|
"influence": function () {
|
|
"influence": function () {
|
|
- var numTargets = targetNode.morphTargetManager.numTargets;
|
|
|
|
|
|
+ var numTargets = targetNode.babylonMesh.morphTargetManager.numTargets;
|
|
var value = new Array(numTargets);
|
|
var value = new Array(numTargets);
|
|
for (var i = 0; i < numTargets; i++) {
|
|
for (var i = 0; i < numTargets; i++) {
|
|
value[i] = outputData[outputBufferOffset++];
|
|
value[i] = outputData[outputBufferOffset++];
|
|
@@ -2954,9 +2966,9 @@ var BABYLON;
|
|
}
|
|
}
|
|
animation.targets = animation.targets || [];
|
|
animation.targets = animation.targets || [];
|
|
if (targetPath === "influence") {
|
|
if (targetPath === "influence") {
|
|
- var targetMesh = targetNode;
|
|
|
|
- for (var targetIndex = 0; targetIndex < targetMesh.morphTargetManager.numTargets; targetIndex++) {
|
|
|
|
- var morphTarget = targetMesh.morphTargetManager.getTarget(targetIndex);
|
|
|
|
|
|
+ var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
|
|
|
|
+ for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
|
|
|
|
+ var morphTarget = morphTargetManager.getTarget(targetIndex);
|
|
var animationName = (animation.name || "anim" + animationIndex) + "_" + targetIndex;
|
|
var animationName = (animation.name || "anim" + animationIndex) + "_" + targetIndex;
|
|
var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
|
|
var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
|
|
babylonAnimation.setKeys(keys.map(function (key) { return ({
|
|
babylonAnimation.setKeys(keys.map(function (key) { return ({
|
|
@@ -2973,8 +2985,11 @@ var BABYLON;
|
|
var animationName = animation.name || "anim" + animationIndex;
|
|
var animationName = animation.name || "anim" + animationIndex;
|
|
var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
|
|
var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
|
|
babylonAnimation.setKeys(keys);
|
|
babylonAnimation.setKeys(keys);
|
|
- targetNode.animations.push(babylonAnimation);
|
|
|
|
- animation.targets.push(targetNode);
|
|
|
|
|
|
+ for (var i = 0; i < targetNode.babylonAnimationTargets.length; i++) {
|
|
|
|
+ var target = targetNode.babylonAnimationTargets[i];
|
|
|
|
+ target.animations.push(babylonAnimation.clone());
|
|
|
|
+ animation.targets.push(target);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
};
|
|
};
|
|
this._loadAccessorAsync(this._gltf.accessors[sampler.input], function (data) {
|
|
this._loadAccessorAsync(this._gltf.accessors[sampler.input], function (data) {
|
|
@@ -3113,21 +3128,20 @@ var BABYLON;
|
|
material.babylonMaterial.metallic = 1;
|
|
material.babylonMaterial.metallic = 1;
|
|
material.babylonMaterial.roughness = 1;
|
|
material.babylonMaterial.roughness = 1;
|
|
var properties = material.pbrMetallicRoughness;
|
|
var properties = material.pbrMetallicRoughness;
|
|
- if (!properties) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- material.babylonMaterial.albedoColor = properties.baseColorFactor ? BABYLON.Color3.FromArray(properties.baseColorFactor) : new BABYLON.Color3(1, 1, 1);
|
|
|
|
- material.babylonMaterial.metallic = properties.metallicFactor === undefined ? 1 : properties.metallicFactor;
|
|
|
|
- material.babylonMaterial.roughness = properties.roughnessFactor === undefined ? 1 : properties.roughnessFactor;
|
|
|
|
- if (properties.baseColorTexture) {
|
|
|
|
- material.babylonMaterial.albedoTexture = this._loadTexture(properties.baseColorTexture);
|
|
|
|
- this._loadAlphaProperties(material);
|
|
|
|
- }
|
|
|
|
- if (properties.metallicRoughnessTexture) {
|
|
|
|
- material.babylonMaterial.metallicTexture = this._loadTexture(properties.metallicRoughnessTexture);
|
|
|
|
- material.babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
|
|
|
|
- material.babylonMaterial.useRoughnessFromMetallicTextureGreen = true;
|
|
|
|
- material.babylonMaterial.useRoughnessFromMetallicTextureAlpha = false;
|
|
|
|
|
|
+ if (properties) {
|
|
|
|
+ material.babylonMaterial.albedoColor = properties.baseColorFactor ? BABYLON.Color3.FromArray(properties.baseColorFactor) : new BABYLON.Color3(1, 1, 1);
|
|
|
|
+ material.babylonMaterial.metallic = properties.metallicFactor === undefined ? 1 : properties.metallicFactor;
|
|
|
|
+ material.babylonMaterial.roughness = properties.roughnessFactor === undefined ? 1 : properties.roughnessFactor;
|
|
|
|
+ if (properties.baseColorTexture) {
|
|
|
|
+ material.babylonMaterial.albedoTexture = this._loadTexture(properties.baseColorTexture);
|
|
|
|
+ this._loadAlphaProperties(material);
|
|
|
|
+ }
|
|
|
|
+ if (properties.metallicRoughnessTexture) {
|
|
|
|
+ material.babylonMaterial.metallicTexture = this._loadTexture(properties.metallicRoughnessTexture);
|
|
|
|
+ material.babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
|
|
|
|
+ material.babylonMaterial.useRoughnessFromMetallicTextureGreen = true;
|
|
|
|
+ material.babylonMaterial.useRoughnessFromMetallicTextureAlpha = false;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return material.babylonMaterial;
|
|
return material.babylonMaterial;
|
|
};
|
|
};
|