|
@@ -2890,11 +2890,12 @@ var BABYLON;
|
|
|
var verticesCounts = [];
|
|
|
var indexStarts = [];
|
|
|
var indexCounts = [];
|
|
|
+ var morphTargetManager = new BABYLON.MorphTargetManager();
|
|
|
// Positions, normals and UVs
|
|
|
- for (var index = 0; index < mesh.primitives.length; index++) {
|
|
|
+ for (var primitiveIndex = 0; primitiveIndex < mesh.primitives.length; primitiveIndex++) {
|
|
|
// Temporary vertex data
|
|
|
var tempVertexData = new BABYLON.VertexData();
|
|
|
- var primitive = mesh.primitives[index];
|
|
|
+ var primitive = mesh.primitives[primitiveIndex];
|
|
|
if (primitive.mode !== GLTF2.EMeshPrimitiveMode.TRIANGLES) {
|
|
|
// continue;
|
|
|
}
|
|
@@ -2954,8 +2955,8 @@ var BABYLON;
|
|
|
else {
|
|
|
// Set indices on the fly
|
|
|
var indices = [];
|
|
|
- for (var j = 0; j < tempVertexData.positions.length / 3; j++) {
|
|
|
- indices.push(j);
|
|
|
+ for (var index = 0; index < tempVertexData.positions.length / 3; index++) {
|
|
|
+ indices.push(index);
|
|
|
}
|
|
|
tempVertexData.indices = new Int32Array(indices);
|
|
|
indexCounts.push(tempVertexData.indices.length);
|
|
@@ -2965,6 +2966,65 @@ var BABYLON;
|
|
|
// Sub material
|
|
|
var material = getMaterial(runtime, primitive.material);
|
|
|
multiMat.subMaterials.push(material);
|
|
|
+ // Morph Targets
|
|
|
+ if (primitive.targets !== undefined) {
|
|
|
+ for (var targetsIndex = 0; targetsIndex < primitive.targets.length; targetsIndex++) {
|
|
|
+ var target = primitive.targets[targetsIndex];
|
|
|
+ var weight = 0.0;
|
|
|
+ if (node.weights !== undefined) {
|
|
|
+ weight = node.weights[targetsIndex];
|
|
|
+ }
|
|
|
+ else if (mesh.weights !== undefined) {
|
|
|
+ weight = mesh.weights[targetsIndex];
|
|
|
+ }
|
|
|
+ var morph = new BABYLON.MorphTarget("morph" + targetsIndex, weight);
|
|
|
+ for (var semantic in target) {
|
|
|
+ // Link accessor and buffer view
|
|
|
+ accessor = runtime.gltf.accessors[target[semantic]];
|
|
|
+ buffer = GLTF2.GLTFUtils.GetBufferFromAccessor(runtime, accessor);
|
|
|
+ if (accessor.name !== undefined) {
|
|
|
+ morph.name = accessor.name;
|
|
|
+ }
|
|
|
+ // glTF stores morph target information as deltas
|
|
|
+ // while babylon.js expects the final data.
|
|
|
+ // As a result we have to add the original data to the delta to calculate
|
|
|
+ // the final data.
|
|
|
+ if (semantic === "NORMAL") {
|
|
|
+ for (var bufferIndex = 0; bufferIndex < buffer.length; bufferIndex++) {
|
|
|
+ buffer[bufferIndex] += vertexData.normals[bufferIndex];
|
|
|
+ }
|
|
|
+ morph.setNormals(buffer);
|
|
|
+ }
|
|
|
+ else if (semantic === "POSITION") {
|
|
|
+ for (var bufferIndex = 0; bufferIndex < buffer.length; bufferIndex++) {
|
|
|
+ buffer[bufferIndex] += vertexData.positions[bufferIndex];
|
|
|
+ }
|
|
|
+ morph.setPositions(buffer);
|
|
|
+ }
|
|
|
+ else if (semantic === "TANGENT") {
|
|
|
+ // Tangent data for morph targets is stored as xyz delta.
|
|
|
+ // The vertexData.tangent is stored as xyzw.
|
|
|
+ // So we need to skip every fourth vertexData.tangent.
|
|
|
+ for (var bufferIndex = 0, tangentsIndex = 0; bufferIndex < buffer.length; bufferIndex++, tangentsIndex++) {
|
|
|
+ buffer[bufferIndex] += vertexData.tangents[tangentsIndex];
|
|
|
+ if ((bufferIndex + 1) % 3 == 0) {
|
|
|
+ tangentsIndex++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ morph.setTangents(buffer);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ BABYLON.Tools.Warn("Ignoring unrecognized semantic '" + semantic + "'");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (morph.getPositions() !== undefined) {
|
|
|
+ morphTargetManager.addTarget(morph);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ BABYLON.Tools.Warn("Not adding morph target '" + morph.name + "' because it has no position data");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
// Update vertices start and index start
|
|
|
verticesStarts.push(verticesStarts.length === 0 ? 0 : verticesStarts[verticesStarts.length - 1] + verticesCounts[verticesCounts.length - 2]);
|
|
|
indexStarts.push(indexStarts.length === 0 ? 0 : indexStarts[indexStarts.length - 1] + indexCounts[indexCounts.length - 2]);
|
|
@@ -2972,13 +3032,17 @@ var BABYLON;
|
|
|
// Apply geometry
|
|
|
geometry.setAllVerticesData(vertexData, false);
|
|
|
babylonMesh.computeWorldMatrix(true);
|
|
|
+ // Set morph target manager after all vertices data has been processed
|
|
|
+ if (morphTargetManager !== undefined && morphTargetManager.numInfluencers > 0) {
|
|
|
+ babylonMesh.morphTargetManager = morphTargetManager;
|
|
|
+ }
|
|
|
// Apply submeshes
|
|
|
babylonMesh.subMeshes = [];
|
|
|
- for (var index = 0; index < mesh.primitives.length; index++) {
|
|
|
- if (mesh.primitives[index].mode !== GLTF2.EMeshPrimitiveMode.TRIANGLES) {
|
|
|
+ for (var primitiveIndex = 0; primitiveIndex < mesh.primitives.length; primitiveIndex++) {
|
|
|
+ if (mesh.primitives[primitiveIndex].mode !== GLTF2.EMeshPrimitiveMode.TRIANGLES) {
|
|
|
//continue;
|
|
|
}
|
|
|
- var subMesh = new BABYLON.SubMesh(index, verticesStarts[index], verticesCounts[index], indexStarts[index], indexCounts[index], babylonMesh, babylonMesh, true);
|
|
|
+ var subMesh = new BABYLON.SubMesh(primitiveIndex, verticesStarts[primitiveIndex], verticesCounts[primitiveIndex], indexStarts[primitiveIndex], indexCounts[primitiveIndex], babylonMesh, babylonMesh, true);
|
|
|
}
|
|
|
// Finish
|
|
|
return babylonMesh;
|