David Catuhe 8 年之前
父節點
當前提交
a48497bff5

文件差異過大導致無法顯示
+ 950 - 937
dist/preview release/babylon.d.ts


文件差異過大導致無法顯示
+ 950 - 937
dist/preview release/babylon.module.d.ts


+ 262 - 262
dist/preview release/inspector/babylon.inspector.bundle.js

@@ -43,15 +43,15 @@ var INSPECTOR =
 /************************************************************************/
 /******/ ([
 /* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
 
 	__webpack_require__(1);
 	module.exports = __webpack_require__(5);
 
 
-/***/ },
+/***/ }),
 /* 1 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
 
 	// style-loader: Adds some css to the DOM by adding a <style> tag
 
@@ -65,8 +65,8 @@ var INSPECTOR =
 	if(false) {
 		// When the styles change, update the <style> tags
 		if(!content.locals) {
-			module.hot.accept("!!./../../../Tools/Gulp/node_modules/css-loader/index.js!./babylon.inspector.css", function() {
-				var newContent = require("!!./../../../Tools/Gulp/node_modules/css-loader/index.js!./babylon.inspector.css");
+			module.hot.accept("!!../../../Tools/Gulp/node_modules/css-loader/index.js!./babylon.inspector.css", function() {
+				var newContent = require("!!../../../Tools/Gulp/node_modules/css-loader/index.js!./babylon.inspector.css");
 				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
 				update(newContent);
 			});
@@ -75,9 +75,9 @@ var INSPECTOR =
 		module.hot.dispose(function() { update(); });
 	}
 
-/***/ },
+/***/ }),
 /* 2 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
 
 	exports = module.exports = __webpack_require__(3)();
 	// imports
@@ -90,9 +90,9 @@ var INSPECTOR =
 	// exports
 
 
-/***/ },
+/***/ }),
 /* 3 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
 
 	/*
 		MIT License http://www.opensource.org/licenses/mit-license.php
@@ -146,261 +146,261 @@ var INSPECTOR =
 	};
 
 
-/***/ },
+/***/ }),
 /* 4 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
+
+	/*
+		MIT License http://www.opensource.org/licenses/mit-license.php
+		Author Tobias Koppers @sokra
+	*/
+	var stylesInDom = {},
+		memoize = function(fn) {
+			var memo;
+			return function () {
+				if (typeof memo === "undefined") memo = fn.apply(this, arguments);
+				return memo;
+			};
+		},
+		isOldIE = memoize(function() {
+			return /msie [6-9]\b/.test(self.navigator.userAgent.toLowerCase());
+		}),
+		getHeadElement = memoize(function () {
+			return document.head || document.getElementsByTagName("head")[0];
+		}),
+		singletonElement = null,
+		singletonCounter = 0,
+		styleElementsInsertedAtTop = [];
+
+	module.exports = function(list, options) {
+		if(false) {
+			if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
+		}
 
-	/*
-		MIT License http://www.opensource.org/licenses/mit-license.php
-		Author Tobias Koppers @sokra
-	*/
-	var stylesInDom = {},
-		memoize = function(fn) {
-			var memo;
-			return function () {
-				if (typeof memo === "undefined") memo = fn.apply(this, arguments);
-				return memo;
-			};
-		},
-		isOldIE = memoize(function() {
-			return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
-		}),
-		getHeadElement = memoize(function () {
-			return document.head || document.getElementsByTagName("head")[0];
-		}),
-		singletonElement = null,
-		singletonCounter = 0,
-		styleElementsInsertedAtTop = [];
-
-	module.exports = function(list, options) {
-		if(false) {
-			if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
-		}
-
-		options = options || {};
-		// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
-		// tags it will allow on a page
-		if (typeof options.singleton === "undefined") options.singleton = isOldIE();
-
-		// By default, add <style> tags to the bottom of <head>.
-		if (typeof options.insertAt === "undefined") options.insertAt = "bottom";
-
-		var styles = listToStyles(list);
-		addStylesToDom(styles, options);
-
-		return function update(newList) {
-			var mayRemove = [];
-			for(var i = 0; i < styles.length; i++) {
-				var item = styles[i];
-				var domStyle = stylesInDom[item.id];
-				domStyle.refs--;
-				mayRemove.push(domStyle);
-			}
-			if(newList) {
-				var newStyles = listToStyles(newList);
-				addStylesToDom(newStyles, options);
-			}
-			for(var i = 0; i < mayRemove.length; i++) {
-				var domStyle = mayRemove[i];
-				if(domStyle.refs === 0) {
-					for(var j = 0; j < domStyle.parts.length; j++)
-						domStyle.parts[j]();
-					delete stylesInDom[domStyle.id];
-				}
-			}
-		};
-	}
-
-	function addStylesToDom(styles, options) {
-		for(var i = 0; i < styles.length; i++) {
-			var item = styles[i];
-			var domStyle = stylesInDom[item.id];
-			if(domStyle) {
-				domStyle.refs++;
-				for(var j = 0; j < domStyle.parts.length; j++) {
-					domStyle.parts[j](item.parts[j]);
-				}
-				for(; j < item.parts.length; j++) {
-					domStyle.parts.push(addStyle(item.parts[j], options));
-				}
-			} else {
-				var parts = [];
-				for(var j = 0; j < item.parts.length; j++) {
-					parts.push(addStyle(item.parts[j], options));
-				}
-				stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
-			}
-		}
-	}
-
-	function listToStyles(list) {
-		var styles = [];
-		var newStyles = {};
-		for(var i = 0; i < list.length; i++) {
-			var item = list[i];
-			var id = item[0];
-			var css = item[1];
-			var media = item[2];
-			var sourceMap = item[3];
-			var part = {css: css, media: media, sourceMap: sourceMap};
-			if(!newStyles[id])
-				styles.push(newStyles[id] = {id: id, parts: [part]});
-			else
-				newStyles[id].parts.push(part);
-		}
-		return styles;
-	}
-
-	function insertStyleElement(options, styleElement) {
-		var head = getHeadElement();
-		var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
-		if (options.insertAt === "top") {
-			if(!lastStyleElementInsertedAtTop) {
-				head.insertBefore(styleElement, head.firstChild);
-			} else if(lastStyleElementInsertedAtTop.nextSibling) {
-				head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
-			} else {
-				head.appendChild(styleElement);
-			}
-			styleElementsInsertedAtTop.push(styleElement);
-		} else if (options.insertAt === "bottom") {
-			head.appendChild(styleElement);
-		} else {
-			throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
-		}
-	}
-
-	function removeStyleElement(styleElement) {
-		styleElement.parentNode.removeChild(styleElement);
-		var idx = styleElementsInsertedAtTop.indexOf(styleElement);
-		if(idx >= 0) {
-			styleElementsInsertedAtTop.splice(idx, 1);
-		}
-	}
-
-	function createStyleElement(options) {
-		var styleElement = document.createElement("style");
-		styleElement.type = "text/css";
-		insertStyleElement(options, styleElement);
-		return styleElement;
-	}
-
-	function createLinkElement(options) {
-		var linkElement = document.createElement("link");
-		linkElement.rel = "stylesheet";
-		insertStyleElement(options, linkElement);
-		return linkElement;
-	}
-
-	function addStyle(obj, options) {
-		var styleElement, update, remove;
-
-		if (options.singleton) {
-			var styleIndex = singletonCounter++;
-			styleElement = singletonElement || (singletonElement = createStyleElement(options));
-			update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
-			remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
-		} else if(obj.sourceMap &&
-			typeof URL === "function" &&
-			typeof URL.createObjectURL === "function" &&
-			typeof URL.revokeObjectURL === "function" &&
-			typeof Blob === "function" &&
-			typeof btoa === "function") {
-			styleElement = createLinkElement(options);
-			update = updateLink.bind(null, styleElement);
-			remove = function() {
-				removeStyleElement(styleElement);
-				if(styleElement.href)
-					URL.revokeObjectURL(styleElement.href);
-			};
-		} else {
-			styleElement = createStyleElement(options);
-			update = applyToTag.bind(null, styleElement);
-			remove = function() {
-				removeStyleElement(styleElement);
-			};
-		}
-
-		update(obj);
-
-		return function updateStyle(newObj) {
-			if(newObj) {
-				if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
-					return;
-				update(obj = newObj);
-			} else {
-				remove();
-			}
-		};
-	}
-
-	var replaceText = (function () {
-		var textStore = [];
-
-		return function (index, replacement) {
-			textStore[index] = replacement;
-			return textStore.filter(Boolean).join('\n');
-		};
-	})();
-
-	function applyToSingletonTag(styleElement, index, remove, obj) {
-		var css = remove ? "" : obj.css;
-
-		if (styleElement.styleSheet) {
-			styleElement.styleSheet.cssText = replaceText(index, css);
-		} else {
-			var cssNode = document.createTextNode(css);
-			var childNodes = styleElement.childNodes;
-			if (childNodes[index]) styleElement.removeChild(childNodes[index]);
-			if (childNodes.length) {
-				styleElement.insertBefore(cssNode, childNodes[index]);
-			} else {
-				styleElement.appendChild(cssNode);
-			}
-		}
-	}
-
-	function applyToTag(styleElement, obj) {
-		var css = obj.css;
-		var media = obj.media;
-
-		if(media) {
-			styleElement.setAttribute("media", media)
-		}
-
-		if(styleElement.styleSheet) {
-			styleElement.styleSheet.cssText = css;
-		} else {
-			while(styleElement.firstChild) {
-				styleElement.removeChild(styleElement.firstChild);
-			}
-			styleElement.appendChild(document.createTextNode(css));
-		}
-	}
-
-	function updateLink(linkElement, obj) {
-		var css = obj.css;
-		var sourceMap = obj.sourceMap;
-
-		if(sourceMap) {
-			// http://stackoverflow.com/a/26603875
-			css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
-		}
-
-		var blob = new Blob([css], { type: "text/css" });
-
-		var oldSrc = linkElement.href;
-
-		linkElement.href = URL.createObjectURL(blob);
-
-		if(oldSrc)
-			URL.revokeObjectURL(oldSrc);
-	}
+		options = options || {};
+		// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
+		// tags it will allow on a page
+		if (typeof options.singleton === "undefined") options.singleton = isOldIE();
+
+		// By default, add <style> tags to the bottom of <head>.
+		if (typeof options.insertAt === "undefined") options.insertAt = "bottom";
+
+		var styles = listToStyles(list);
+		addStylesToDom(styles, options);
+
+		return function update(newList) {
+			var mayRemove = [];
+			for(var i = 0; i < styles.length; i++) {
+				var item = styles[i];
+				var domStyle = stylesInDom[item.id];
+				domStyle.refs--;
+				mayRemove.push(domStyle);
+			}
+			if(newList) {
+				var newStyles = listToStyles(newList);
+				addStylesToDom(newStyles, options);
+			}
+			for(var i = 0; i < mayRemove.length; i++) {
+				var domStyle = mayRemove[i];
+				if(domStyle.refs === 0) {
+					for(var j = 0; j < domStyle.parts.length; j++)
+						domStyle.parts[j]();
+					delete stylesInDom[domStyle.id];
+				}
+			}
+		};
+	}
+
+	function addStylesToDom(styles, options) {
+		for(var i = 0; i < styles.length; i++) {
+			var item = styles[i];
+			var domStyle = stylesInDom[item.id];
+			if(domStyle) {
+				domStyle.refs++;
+				for(var j = 0; j < domStyle.parts.length; j++) {
+					domStyle.parts[j](item.parts[j]);
+				}
+				for(; j < item.parts.length; j++) {
+					domStyle.parts.push(addStyle(item.parts[j], options));
+				}
+			} else {
+				var parts = [];
+				for(var j = 0; j < item.parts.length; j++) {
+					parts.push(addStyle(item.parts[j], options));
+				}
+				stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
+			}
+		}
+	}
+
+	function listToStyles(list) {
+		var styles = [];
+		var newStyles = {};
+		for(var i = 0; i < list.length; i++) {
+			var item = list[i];
+			var id = item[0];
+			var css = item[1];
+			var media = item[2];
+			var sourceMap = item[3];
+			var part = {css: css, media: media, sourceMap: sourceMap};
+			if(!newStyles[id])
+				styles.push(newStyles[id] = {id: id, parts: [part]});
+			else
+				newStyles[id].parts.push(part);
+		}
+		return styles;
+	}
+
+	function insertStyleElement(options, styleElement) {
+		var head = getHeadElement();
+		var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
+		if (options.insertAt === "top") {
+			if(!lastStyleElementInsertedAtTop) {
+				head.insertBefore(styleElement, head.firstChild);
+			} else if(lastStyleElementInsertedAtTop.nextSibling) {
+				head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
+			} else {
+				head.appendChild(styleElement);
+			}
+			styleElementsInsertedAtTop.push(styleElement);
+		} else if (options.insertAt === "bottom") {
+			head.appendChild(styleElement);
+		} else {
+			throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
+		}
+	}
+
+	function removeStyleElement(styleElement) {
+		styleElement.parentNode.removeChild(styleElement);
+		var idx = styleElementsInsertedAtTop.indexOf(styleElement);
+		if(idx >= 0) {
+			styleElementsInsertedAtTop.splice(idx, 1);
+		}
+	}
+
+	function createStyleElement(options) {
+		var styleElement = document.createElement("style");
+		styleElement.type = "text/css";
+		insertStyleElement(options, styleElement);
+		return styleElement;
+	}
+
+	function createLinkElement(options) {
+		var linkElement = document.createElement("link");
+		linkElement.rel = "stylesheet";
+		insertStyleElement(options, linkElement);
+		return linkElement;
+	}
+
+	function addStyle(obj, options) {
+		var styleElement, update, remove;
+
+		if (options.singleton) {
+			var styleIndex = singletonCounter++;
+			styleElement = singletonElement || (singletonElement = createStyleElement(options));
+			update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
+			remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
+		} else if(obj.sourceMap &&
+			typeof URL === "function" &&
+			typeof URL.createObjectURL === "function" &&
+			typeof URL.revokeObjectURL === "function" &&
+			typeof Blob === "function" &&
+			typeof btoa === "function") {
+			styleElement = createLinkElement(options);
+			update = updateLink.bind(null, styleElement);
+			remove = function() {
+				removeStyleElement(styleElement);
+				if(styleElement.href)
+					URL.revokeObjectURL(styleElement.href);
+			};
+		} else {
+			styleElement = createStyleElement(options);
+			update = applyToTag.bind(null, styleElement);
+			remove = function() {
+				removeStyleElement(styleElement);
+			};
+		}
+
+		update(obj);
+
+		return function updateStyle(newObj) {
+			if(newObj) {
+				if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
+					return;
+				update(obj = newObj);
+			} else {
+				remove();
+			}
+		};
+	}
+
+	var replaceText = (function () {
+		var textStore = [];
+
+		return function (index, replacement) {
+			textStore[index] = replacement;
+			return textStore.filter(Boolean).join('\n');
+		};
+	})();
+
+	function applyToSingletonTag(styleElement, index, remove, obj) {
+		var css = remove ? "" : obj.css;
+
+		if (styleElement.styleSheet) {
+			styleElement.styleSheet.cssText = replaceText(index, css);
+		} else {
+			var cssNode = document.createTextNode(css);
+			var childNodes = styleElement.childNodes;
+			if (childNodes[index]) styleElement.removeChild(childNodes[index]);
+			if (childNodes.length) {
+				styleElement.insertBefore(cssNode, childNodes[index]);
+			} else {
+				styleElement.appendChild(cssNode);
+			}
+		}
+	}
+
+	function applyToTag(styleElement, obj) {
+		var css = obj.css;
+		var media = obj.media;
+
+		if(media) {
+			styleElement.setAttribute("media", media)
+		}
+
+		if(styleElement.styleSheet) {
+			styleElement.styleSheet.cssText = css;
+		} else {
+			while(styleElement.firstChild) {
+				styleElement.removeChild(styleElement.firstChild);
+			}
+			styleElement.appendChild(document.createTextNode(css));
+		}
+	}
+
+	function updateLink(linkElement, obj) {
+		var css = obj.css;
+		var sourceMap = obj.sourceMap;
+
+		if(sourceMap) {
+			// http://stackoverflow.com/a/26603875
+			css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
+		}
+
+		var blob = new Blob([css], { type: "text/css" });
+
+		var oldSrc = linkElement.href;
+
+		linkElement.href = URL.createObjectURL(blob);
+
+		if(oldSrc)
+			URL.revokeObjectURL(oldSrc);
+	}
 
 
-/***/ },
+/***/ }),
 /* 5 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
 
 	/*** IMPORTS FROM imports-loader ***/
 	var Split = __webpack_require__(6);
@@ -413,9 +413,9 @@ var INSPECTOR =
 	module.exports = INSPECTOR;
 
 
-/***/ },
+/***/ }),
 /* 6 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
 
 	// The programming goals of Split.js are to deliver readable, understandable and
 	// maintainable code, while at the same time manually optimizing for tiny minified file size,
@@ -987,5 +987,5 @@ var INSPECTOR =
 	}).call(window);
 
 
-/***/ }
+/***/ })
 /******/ ]);

+ 70 - 18
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -287,8 +287,8 @@ var BABYLON;
         /**
         * Values
         */
-        var glTFAnimationPaths = ["translation", "rotation", "scale"];
-        var babylonAnimationPaths = ["position", "rotationQuaternion", "scaling"];
+        var glTFAnimationPaths = ["translation", "rotation", "scale", "weights"];
+        var babylonAnimationPaths = ["position", "rotationQuaternion", "scaling", "influence"];
         /**
         * Utils
         */
@@ -347,12 +347,14 @@ var BABYLON;
                         continue;
                     }
                     var isBone = targetNode instanceof BABYLON.Bone;
-                    // Get target path (position, rotation or scaling)
+                    var numTargets = 0;
+                    // Get target path (position, rotation, scaling, or weights)
                     var targetPath = channel.target.path;
                     var targetPathIndex = glTFAnimationPaths.indexOf(targetPath);
                     if (targetPathIndex !== -1) {
                         targetPath = babylonAnimationPaths[targetPathIndex];
                     }
+                    var isMorph = targetPath === "influence";
                     // Determine animation type
                     var animationType = BABYLON.Animation.ANIMATIONTYPE_MATRIX;
                     if (!isBone) {
@@ -360,6 +362,10 @@ var BABYLON;
                             animationType = BABYLON.Animation.ANIMATIONTYPE_QUATERNION;
                             targetNode.rotationQuaternion = new BABYLON.Quaternion();
                         }
+                        else if (isMorph) {
+                            animationType = BABYLON.Animation.ANIMATIONTYPE_FLOAT;
+                            numTargets = targetNode.morphTargetManager.numTargets;
+                        }
                         else {
                             animationType = BABYLON.Animation.ANIMATIONTYPE_VECTOR3;
                         }
@@ -373,17 +379,28 @@ var BABYLON;
                         babylonAnimation = lastAnimation;
                         modifyKey = true;
                     }
-                    if (!modifyKey) {
-                        var animationName = animation.name || "anim" + animationIndex;
-                        babylonAnimation = new BABYLON.Animation(animationName, isBone ? "_matrix" : targetPath, 1, animationType, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
+                    // Each morph animation may have more than one more, so we need a
+                    // multi dimensional array.
+                    if (isMorph) {
+                        for (var influence = 0; influence < numTargets; influence++) {
+                            keys[influence] = [];
+                        }
                     }
                     // For each frame
-                    for (var j = 0; j < bufferInput.length; j++) {
+                    for (var frameIndex = 0; frameIndex < bufferInput.length; frameIndex++) {
                         var value = null;
                         if (targetPath === "rotationQuaternion") {
                             value = BABYLON.Quaternion.FromArray([bufferOutput[arrayOffset], bufferOutput[arrayOffset + 1], bufferOutput[arrayOffset + 2], bufferOutput[arrayOffset + 3]]);
                             arrayOffset += 4;
                         }
+                        else if (isMorph) {
+                            value = [];
+                            // There is 1 value for each morph target for each frame
+                            for (var influence = 0; influence < numTargets; influence++) {
+                                value.push(bufferOutput[arrayOffset + influence]);
+                            }
+                            arrayOffset += numTargets;
+                        }
                         else {
                             value = BABYLON.Vector3.FromArray([bufferOutput[arrayOffset], bufferOutput[arrayOffset + 1], bufferOutput[arrayOffset + 2]]);
                             arrayOffset += 3;
@@ -396,7 +413,7 @@ var BABYLON;
                             // Warning on decompose
                             var mat = bone.getBaseMatrix();
                             if (modifyKey) {
-                                mat = lastAnimation.getKeys()[j].value;
+                                mat = lastAnimation.getKeys()[frameIndex].value;
                             }
                             mat.decompose(scaling, rotationQuaternion, translation);
                             if (targetPath === "position") {
@@ -411,23 +428,58 @@ var BABYLON;
                             value = BABYLON.Matrix.Compose(scaling, rotationQuaternion, translation);
                         }
                         if (!modifyKey) {
-                            keys.push({
-                                frame: bufferInput[j],
-                                value: value
-                            });
+                            if (isMorph) {
+                                for (var influence = 0; influence < numTargets; influence++) {
+                                    keys[influence].push({
+                                        frame: bufferInput[frameIndex],
+                                        value: value[influence]
+                                    });
+                                }
+                            }
+                            else {
+                                keys.push({
+                                    frame: bufferInput[frameIndex],
+                                    value: value
+                                });
+                            }
                         }
                         else {
-                            lastAnimation.getKeys()[j].value = value;
+                            lastAnimation.getKeys()[frameIndex].value = value;
                         }
                     }
                     // Finish
                     if (!modifyKey) {
-                        babylonAnimation.setKeys(keys);
-                        targetNode.animations.push(babylonAnimation);
+                        if (isMorph) {
+                            for (var influence = 0; influence < numTargets; influence++) {
+                                var morphTarget = targetNode.morphTargetManager.getTarget(influence);
+                                if (morphTarget.animations === undefined) {
+                                    morphTarget.animations = [];
+                                }
+                                var animationName = (animation.name || "anim" + animationIndex) + "_" + influence;
+                                babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
+                                babylonAnimation.setKeys(keys[influence]);
+                                morphTarget.animations.push(babylonAnimation);
+                            }
+                        }
+                        else {
+                            var animationName = animation.name || "anim" + animationIndex;
+                            babylonAnimation = new BABYLON.Animation(animationName, isBone ? "_matrix" : targetPath, 1, animationType, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
+                            babylonAnimation.setKeys(keys);
+                            targetNode.animations.push(babylonAnimation);
+                        }
                     }
                     lastAnimation = babylonAnimation;
-                    runtime.babylonScene.stopAnimation(targetNode);
-                    runtime.babylonScene.beginAnimation(targetNode, 0, bufferInput[bufferInput.length - 1], true, 1.0);
+                    if (isMorph) {
+                        for (var influence = 0; influence < numTargets; influence++) {
+                            var morph = targetNode.morphTargetManager.getTarget(influence);
+                            runtime.babylonScene.stopAnimation(morph);
+                            runtime.babylonScene.beginAnimation(morph, 0, bufferInput[bufferInput.length - 1], true, 1.0);
+                        }
+                    }
+                    else {
+                        runtime.babylonScene.stopAnimation(targetNode);
+                        runtime.babylonScene.beginAnimation(targetNode, 0, bufferInput[bufferInput.length - 1], true, 1.0);
+                    }
                 }
             }
         };
@@ -835,7 +887,7 @@ var BABYLON;
             geometry.setAllVerticesData(vertexData, false);
             babylonMesh.computeWorldMatrix(true);
             // Set morph target manager after all vertices data has been processed
-            if (morphTargetManager !== undefined && morphTargetManager.numInfluencers > 0) {
+            if (morphTargetManager !== undefined && morphTargetManager.numTargets > 0) {
                 babylonMesh.morphTargetManager = morphTargetManager;
             }
             // Apply submeshes

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 70 - 18
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -2437,8 +2437,8 @@ var BABYLON;
         /**
         * Values
         */
-        var glTFAnimationPaths = ["translation", "rotation", "scale"];
-        var babylonAnimationPaths = ["position", "rotationQuaternion", "scaling"];
+        var glTFAnimationPaths = ["translation", "rotation", "scale", "weights"];
+        var babylonAnimationPaths = ["position", "rotationQuaternion", "scaling", "influence"];
         /**
         * Utils
         */
@@ -2497,12 +2497,14 @@ var BABYLON;
                         continue;
                     }
                     var isBone = targetNode instanceof BABYLON.Bone;
-                    // Get target path (position, rotation or scaling)
+                    var numTargets = 0;
+                    // Get target path (position, rotation, scaling, or weights)
                     var targetPath = channel.target.path;
                     var targetPathIndex = glTFAnimationPaths.indexOf(targetPath);
                     if (targetPathIndex !== -1) {
                         targetPath = babylonAnimationPaths[targetPathIndex];
                     }
+                    var isMorph = targetPath === "influence";
                     // Determine animation type
                     var animationType = BABYLON.Animation.ANIMATIONTYPE_MATRIX;
                     if (!isBone) {
@@ -2510,6 +2512,10 @@ var BABYLON;
                             animationType = BABYLON.Animation.ANIMATIONTYPE_QUATERNION;
                             targetNode.rotationQuaternion = new BABYLON.Quaternion();
                         }
+                        else if (isMorph) {
+                            animationType = BABYLON.Animation.ANIMATIONTYPE_FLOAT;
+                            numTargets = targetNode.morphTargetManager.numTargets;
+                        }
                         else {
                             animationType = BABYLON.Animation.ANIMATIONTYPE_VECTOR3;
                         }
@@ -2523,17 +2529,28 @@ var BABYLON;
                         babylonAnimation = lastAnimation;
                         modifyKey = true;
                     }
-                    if (!modifyKey) {
-                        var animationName = animation.name || "anim" + animationIndex;
-                        babylonAnimation = new BABYLON.Animation(animationName, isBone ? "_matrix" : targetPath, 1, animationType, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
+                    // Each morph animation may have more than one more, so we need a
+                    // multi dimensional array.
+                    if (isMorph) {
+                        for (var influence = 0; influence < numTargets; influence++) {
+                            keys[influence] = [];
+                        }
                     }
                     // For each frame
-                    for (var j = 0; j < bufferInput.length; j++) {
+                    for (var frameIndex = 0; frameIndex < bufferInput.length; frameIndex++) {
                         var value = null;
                         if (targetPath === "rotationQuaternion") {
                             value = BABYLON.Quaternion.FromArray([bufferOutput[arrayOffset], bufferOutput[arrayOffset + 1], bufferOutput[arrayOffset + 2], bufferOutput[arrayOffset + 3]]);
                             arrayOffset += 4;
                         }
+                        else if (isMorph) {
+                            value = [];
+                            // There is 1 value for each morph target for each frame
+                            for (var influence = 0; influence < numTargets; influence++) {
+                                value.push(bufferOutput[arrayOffset + influence]);
+                            }
+                            arrayOffset += numTargets;
+                        }
                         else {
                             value = BABYLON.Vector3.FromArray([bufferOutput[arrayOffset], bufferOutput[arrayOffset + 1], bufferOutput[arrayOffset + 2]]);
                             arrayOffset += 3;
@@ -2546,7 +2563,7 @@ var BABYLON;
                             // Warning on decompose
                             var mat = bone.getBaseMatrix();
                             if (modifyKey) {
-                                mat = lastAnimation.getKeys()[j].value;
+                                mat = lastAnimation.getKeys()[frameIndex].value;
                             }
                             mat.decompose(scaling, rotationQuaternion, translation);
                             if (targetPath === "position") {
@@ -2561,23 +2578,58 @@ var BABYLON;
                             value = BABYLON.Matrix.Compose(scaling, rotationQuaternion, translation);
                         }
                         if (!modifyKey) {
-                            keys.push({
-                                frame: bufferInput[j],
-                                value: value
-                            });
+                            if (isMorph) {
+                                for (var influence = 0; influence < numTargets; influence++) {
+                                    keys[influence].push({
+                                        frame: bufferInput[frameIndex],
+                                        value: value[influence]
+                                    });
+                                }
+                            }
+                            else {
+                                keys.push({
+                                    frame: bufferInput[frameIndex],
+                                    value: value
+                                });
+                            }
                         }
                         else {
-                            lastAnimation.getKeys()[j].value = value;
+                            lastAnimation.getKeys()[frameIndex].value = value;
                         }
                     }
                     // Finish
                     if (!modifyKey) {
-                        babylonAnimation.setKeys(keys);
-                        targetNode.animations.push(babylonAnimation);
+                        if (isMorph) {
+                            for (var influence = 0; influence < numTargets; influence++) {
+                                var morphTarget = targetNode.morphTargetManager.getTarget(influence);
+                                if (morphTarget.animations === undefined) {
+                                    morphTarget.animations = [];
+                                }
+                                var animationName = (animation.name || "anim" + animationIndex) + "_" + influence;
+                                babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
+                                babylonAnimation.setKeys(keys[influence]);
+                                morphTarget.animations.push(babylonAnimation);
+                            }
+                        }
+                        else {
+                            var animationName = animation.name || "anim" + animationIndex;
+                            babylonAnimation = new BABYLON.Animation(animationName, isBone ? "_matrix" : targetPath, 1, animationType, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
+                            babylonAnimation.setKeys(keys);
+                            targetNode.animations.push(babylonAnimation);
+                        }
                     }
                     lastAnimation = babylonAnimation;
-                    runtime.babylonScene.stopAnimation(targetNode);
-                    runtime.babylonScene.beginAnimation(targetNode, 0, bufferInput[bufferInput.length - 1], true, 1.0);
+                    if (isMorph) {
+                        for (var influence = 0; influence < numTargets; influence++) {
+                            var morph = targetNode.morphTargetManager.getTarget(influence);
+                            runtime.babylonScene.stopAnimation(morph);
+                            runtime.babylonScene.beginAnimation(morph, 0, bufferInput[bufferInput.length - 1], true, 1.0);
+                        }
+                    }
+                    else {
+                        runtime.babylonScene.stopAnimation(targetNode);
+                        runtime.babylonScene.beginAnimation(targetNode, 0, bufferInput[bufferInput.length - 1], true, 1.0);
+                    }
                 }
             }
         };
@@ -2985,7 +3037,7 @@ var BABYLON;
             geometry.setAllVerticesData(vertexData, false);
             babylonMesh.computeWorldMatrix(true);
             // Set morph target manager after all vertices data has been processed
-            if (morphTargetManager !== undefined && morphTargetManager.numInfluencers > 0) {
+            if (morphTargetManager !== undefined && morphTargetManager.numTargets > 0) {
                 babylonMesh.morphTargetManager = morphTargetManager;
             }
             // Apply submeshes

文件差異過大導致無法顯示
+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.min.js