浏览代码

Merge master

David Catuhe 7 年之前
父节点
当前提交
dc15bbc58e
共有 66 个文件被更改,包括 37971 次插入37172 次删除
  1. 17855 17713
      Playground/babylon.d.txt
  2. 15929 15787
      dist/preview release/babylon.d.ts
  3. 54 54
      dist/preview release/babylon.js
  4. 760 481
      dist/preview release/babylon.max.js
  5. 760 481
      dist/preview release/babylon.no-module.max.js
  6. 50 50
      dist/preview release/babylon.worker.js
  7. 760 481
      dist/preview release/es6.js
  8. 4 0
      dist/preview release/gui/babylon.gui.d.ts
  9. 18 0
      dist/preview release/gui/babylon.gui.js
  10. 4 4
      dist/preview release/gui/babylon.gui.min.js
  11. 4 0
      dist/preview release/gui/babylon.gui.module.d.ts
  12. 4 4
      dist/preview release/inspector/babylon.inspector.bundle.js
  13. 3 3
      dist/preview release/inspector/babylon.inspector.min.js
  14. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  15. 0 7
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  16. 4 57
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  17. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  18. 0 7
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  19. 4 57
      dist/preview release/loaders/babylon.glTFFileLoader.js
  20. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  21. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  22. 0 7
      dist/preview release/loaders/babylonjs.loaders.d.ts
  23. 4 57
      dist/preview release/loaders/babylonjs.loaders.js
  24. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  25. 0 7
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  26. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  27. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  28. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  29. 3 3
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  30. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  31. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js
  32. 1 1
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js
  33. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  34. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  35. 55 690
      dist/preview release/typedocValidationBaseline.json
  36. 64 64
      dist/preview release/viewer/babylon.viewer.js
  37. 764 538
      dist/preview release/viewer/babylon.viewer.max.js
  38. 3 0
      dist/preview release/what's new.md
  39. 18 0
      gui/src/advancedDynamicTexture.ts
  40. 4 0
      gui/src/controls/container.ts
  41. 4 9
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  42. 0 28
      loaders/src/glTF/2.0/babylon.glTFLoaderUtilities.ts
  43. 42 57
      materialsLibrary/test/addbackground.js
  44. 2 1
      sandbox/index.html
  45. 1 1
      src/Animations/babylon.animatable.ts
  46. 3 0
      src/Animations/babylon.animation.ts
  47. 18 9
      src/Animations/babylon.runtimeAnimation.ts
  48. 63 47
      src/Bones/babylon.bone.ts
  49. 2 2
      src/Bones/babylon.boneIKController.ts
  50. 59 83
      src/Engine/babylon.engine.ts
  51. 24 11
      src/Helpers/babylon.environmentHelper.ts
  52. 128 43
      src/Materials/Background/babylon.backgroundMaterial.ts
  53. 3 1
      src/Materials/Textures/babylon.mirrorTexture.ts
  54. 414 266
      src/Math/babylon.math.ts
  55. 6 6
      src/Mesh/babylon.buffer.ts
  56. 3 2
      src/Mesh/babylon.geometry.ts
  57. 6 3
      src/Mesh/babylon.vertexBuffer.ts
  58. 7 7
      src/PostProcess/babylon.depthOfFieldEffect.ts
  59. 3 2
      src/Shaders/ShadersInclude/backgroundFragmentDeclaration.fx
  60. 1 2
      src/Shaders/ShadersInclude/backgroundUboDeclaration.fx
  61. 7 3
      src/Shaders/background.fragment.fx
  62. 22 7
      src/babylon.scene.ts
  63. 二进制
      tests/validation/ReferenceImages/gltf1CesiumMan.png
  64. 二进制
      tests/validation/ReferenceImages/texture cache.png
  65. 5 8
      tests/validation/config.json
  66. 1 3
      tests/validation/index.html

文件差异内容过多而无法显示
+ 17855 - 17713
Playground/babylon.d.txt


文件差异内容过多而无法显示
+ 15929 - 15787
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 54 - 54
dist/preview release/babylon.js


文件差异内容过多而无法显示
+ 760 - 481
dist/preview release/babylon.max.js


文件差异内容过多而无法显示
+ 760 - 481
dist/preview release/babylon.no-module.max.js


文件差异内容过多而无法显示
+ 50 - 50
dist/preview release/babylon.worker.js


文件差异内容过多而无法显示
+ 760 - 481
dist/preview release/es6.js


+ 4 - 0
dist/preview release/gui/babylon.gui.d.ts

@@ -58,6 +58,10 @@ declare module BABYLON.GUI {
         private _checkUpdate(camera);
         private _render();
         private _doPicking(x, y, type, pointerId, buttonIndex);
+        _cleanControlAfterRemovalFromList(list: {
+            [pointerId: number]: Control;
+        }, control: Control): void;
+        _cleanControlAfterRemoval(control: Control): void;
         attach(): void;
         attachToMesh(mesh: AbstractMesh, supportPointerMove?: boolean): void;
         moveFocusToControl(control: IFocusableControl): void;

+ 18 - 0
dist/preview release/gui/babylon.gui.js

@@ -391,6 +391,21 @@ var BABYLON;
                 }
                 this._manageFocus();
             };
+            AdvancedDynamicTexture.prototype._cleanControlAfterRemovalFromList = function (list, control) {
+                for (var pointerId in list) {
+                    if (!list.hasOwnProperty(pointerId)) {
+                        continue;
+                    }
+                    var lastControlOver = list[pointerId];
+                    if (lastControlOver === control) {
+                        delete list[pointerId];
+                    }
+                }
+            };
+            AdvancedDynamicTexture.prototype._cleanControlAfterRemoval = function (control) {
+                this._cleanControlAfterRemovalFromList(this._lastControlDown, control);
+                this._cleanControlAfterRemovalFromList(this._lastControlOver, control);
+            };
             AdvancedDynamicTexture.prototype.attach = function () {
                 var _this = this;
                 var scene = this.getScene();
@@ -2083,6 +2098,9 @@ var BABYLON;
                     control.parent = null;
                 }
                 control.linkWithMesh(null);
+                if (this._host) {
+                    this._host._cleanControlAfterRemoval(control);
+                }
                 this._markAsDirty();
                 return this;
             };

文件差异内容过多而无法显示
+ 4 - 4
dist/preview release/gui/babylon.gui.min.js


+ 4 - 0
dist/preview release/gui/babylon.gui.module.d.ts

@@ -63,6 +63,10 @@ declare module BABYLON.GUI {
         private _checkUpdate(camera);
         private _render();
         private _doPicking(x, y, type, pointerId, buttonIndex);
+        _cleanControlAfterRemovalFromList(list: {
+            [pointerId: number]: Control;
+        }, control: Control): void;
+        _cleanControlAfterRemoval(control: Control): void;
         attach(): void;
         attachToMesh(mesh: AbstractMesh, supportPointerMove?: boolean): void;
         moveFocusToControl(control: IFocusableControl): void;

文件差异内容过多而无法显示
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/inspector/babylon.inspector.min.js


文件差异内容过多而无法显示
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 0 - 7
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -191,13 +191,6 @@ declare module BABYLON.GLTF2 {
     class ArrayItem {
         static Assign(values?: IArrayItem[]): void;
     }
-    class AnimationMultiTarget {
-        subTargets: any[];
-        position: Vector3;
-        rotationQuaternion: Quaternion;
-        scaling: Vector3;
-        influence: number;
-    }
 }
 
 

+ 4 - 57
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -491,53 +491,6 @@ var BABYLON;
             return ArrayItem;
         }());
         GLTF2.ArrayItem = ArrayItem;
-        var AnimationMultiTarget = /** @class */ (function () {
-            function AnimationMultiTarget() {
-                this.subTargets = new Array();
-            }
-            Object.defineProperty(AnimationMultiTarget.prototype, "position", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.position = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "rotationQuaternion", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.rotationQuaternion = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "scaling", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.scaling = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "influence", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.influence = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            return AnimationMultiTarget;
-        }());
-        GLTF2.AnimationMultiTarget = AnimationMultiTarget;
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 
@@ -1339,12 +1292,11 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
-                            var multiTarget = new GLTF2.AnimationMultiTarget();
+                            var morphTargets = new Array();
                             _this._forEachPrimitive(targetNode, function (babylonMesh) {
-                                var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
-                                multiTarget.subTargets.push(morphTarget);
+                                morphTargets.push(babylonMesh.morphTargetManager.getTarget(targetIndex));
                             });
-                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTargets);
                         };
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                             _loop_1(targetIndex);
@@ -1355,12 +1307,7 @@ var BABYLON;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         if (targetNode._babylonAnimationTargets) {
-                            var multiTarget = new GLTF2.AnimationMultiTarget();
-                            for (var _i = 0, _a = targetNode._babylonAnimationTargets; _i < _a.length; _i++) {
-                                var target = _a[_i];
-                                multiTarget.subTargets.push(target);
-                            }
-                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, targetNode._babylonAnimationTargets);
                         }
                     }
                 });

文件差异内容过多而无法显示
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 0 - 7
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -747,13 +747,6 @@ declare module BABYLON.GLTF2 {
     class ArrayItem {
         static Assign(values?: IArrayItem[]): void;
     }
-    class AnimationMultiTarget {
-        subTargets: any[];
-        position: Vector3;
-        rotationQuaternion: Quaternion;
-        scaling: Vector3;
-        influence: number;
-    }
 }
 
 

+ 4 - 57
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -2689,53 +2689,6 @@ var BABYLON;
             return ArrayItem;
         }());
         GLTF2.ArrayItem = ArrayItem;
-        var AnimationMultiTarget = /** @class */ (function () {
-            function AnimationMultiTarget() {
-                this.subTargets = new Array();
-            }
-            Object.defineProperty(AnimationMultiTarget.prototype, "position", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.position = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "rotationQuaternion", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.rotationQuaternion = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "scaling", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.scaling = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "influence", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.influence = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            return AnimationMultiTarget;
-        }());
-        GLTF2.AnimationMultiTarget = AnimationMultiTarget;
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 
@@ -3537,12 +3490,11 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
-                            var multiTarget = new GLTF2.AnimationMultiTarget();
+                            var morphTargets = new Array();
                             _this._forEachPrimitive(targetNode, function (babylonMesh) {
-                                var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
-                                multiTarget.subTargets.push(morphTarget);
+                                morphTargets.push(babylonMesh.morphTargetManager.getTarget(targetIndex));
                             });
-                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTargets);
                         };
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                             _loop_1(targetIndex);
@@ -3553,12 +3505,7 @@ var BABYLON;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         if (targetNode._babylonAnimationTargets) {
-                            var multiTarget = new GLTF2.AnimationMultiTarget();
-                            for (var _i = 0, _a = targetNode._babylonAnimationTargets; _i < _a.length; _i++) {
-                                var target = _a[_i];
-                                multiTarget.subTargets.push(target);
-                            }
-                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, targetNode._babylonAnimationTargets);
                         }
                     }
                 });

文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


+ 0 - 7
dist/preview release/loaders/babylonjs.loaders.d.ts

@@ -842,13 +842,6 @@ declare module BABYLON.GLTF2 {
     class ArrayItem {
         static Assign(values?: IArrayItem[]): void;
     }
-    class AnimationMultiTarget {
-        subTargets: any[];
-        position: Vector3;
-        rotationQuaternion: Quaternion;
-        scaling: Vector3;
-        influence: number;
-    }
 }
 
 

+ 4 - 57
dist/preview release/loaders/babylonjs.loaders.js

@@ -3668,53 +3668,6 @@ var BABYLON;
             return ArrayItem;
         }());
         GLTF2.ArrayItem = ArrayItem;
-        var AnimationMultiTarget = /** @class */ (function () {
-            function AnimationMultiTarget() {
-                this.subTargets = new Array();
-            }
-            Object.defineProperty(AnimationMultiTarget.prototype, "position", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.position = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "rotationQuaternion", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.rotationQuaternion = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "scaling", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.scaling = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "influence", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.influence = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            return AnimationMultiTarget;
-        }());
-        GLTF2.AnimationMultiTarget = AnimationMultiTarget;
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 
@@ -4516,12 +4469,11 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
-                            var multiTarget = new GLTF2.AnimationMultiTarget();
+                            var morphTargets = new Array();
                             _this._forEachPrimitive(targetNode, function (babylonMesh) {
-                                var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
-                                multiTarget.subTargets.push(morphTarget);
+                                morphTargets.push(babylonMesh.morphTargetManager.getTarget(targetIndex));
                             });
-                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTargets);
                         };
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                             _loop_1(targetIndex);
@@ -4532,12 +4484,7 @@ var BABYLON;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         if (targetNode._babylonAnimationTargets) {
-                            var multiTarget = new GLTF2.AnimationMultiTarget();
-                            for (var _i = 0, _a = targetNode._babylonAnimationTargets; _i < _a.length; _i++) {
-                                var target = _a[_i];
-                                multiTarget.subTargets.push(target);
-                            }
-                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, targetNode._babylonAnimationTargets);
                         }
                     }
                 });

文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


+ 0 - 7
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -849,13 +849,6 @@ declare module BABYLON.GLTF2 {
     class ArrayItem {
         static Assign(values?: IArrayItem[]): void;
     }
-    class AnimationMultiTarget {
-        subTargets: any[];
-        position: Vector3;
-        rotationQuaternion: Quaternion;
-        scaling: Vector3;
-        influence: number;
-    }
 }
 
 

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/materialsLibrary/babylonjs.materials.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


+ 55 - 690
dist/preview release/typedocValidationBaseline.json

@@ -1,7 +1,7 @@
 {
-  "errors": 5347,
+  "errors": 5236,
   "babylon.typedoc.json": {
-    "errors": 5347,
+    "errors": 5236,
     "AnimationKeyInterpolation": {
       "Enumeration": {
         "Comments": {
@@ -2168,11 +2168,6 @@
       }
     },
     "Animation": {
-      "Class": {
-        "Comments": {
-          "MissingText": true
-        }
-      },
       "Constructor": {
         "new Animation": {
           "Comments": {
@@ -4705,15 +4700,6 @@
             }
           }
         },
-        "setScale": {
-          "Parameter": {
-            "y": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
         "updateMatrix": {
           "Comments": {
             "MissingText": true
@@ -16884,788 +16870,181 @@
         }
       }
     },
-    "Quaternion": {
+    "QuinticEase": {
+      "Class": {
+        "Comments": {
+          "MissingText": true
+        }
+      }
+    },
+    "RawTexture": {
       "Class": {
         "Comments": {
           "MissingText": true
         }
       },
       "Property": {
-        "w": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "x": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "y": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "z": {
+        "format": {
           "Comments": {
             "MissingText": true
           }
         }
       },
       "Method": {
-        "add": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "other": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "asArray": {
-          "Comments": {
-            "MissingReturn": true
-          }
-        },
-        "clone": {
-          "Comments": {
-            "MissingReturn": true
-          }
-        },
-        "conjugate": {
-          "Comments": {
-            "MissingReturn": true
-          }
-        },
-        "conjugateInPlace": {
-          "Comments": {
-            "MissingReturn": true
-          }
-        },
-        "conjugateToRef": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "ref": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "copyFrom": {
+        "update": {
           "Comments": {
-            "MissingReturn": true
+            "MissingText": true
           },
           "Parameter": {
-            "other": {
+            "data": {
               "Comments": {
                 "MissingText": true
               }
             }
           }
         },
-        "copyFromFloats": {
+        "CreateAlphaTexture": {
           "Comments": {
-            "MissingReturn": true
+            "MissingText": true
           },
           "Parameter": {
-            "x": {
+            "data": {
               "Comments": {
                 "MissingText": true
               }
             },
-            "y": {
+            "width": {
               "Comments": {
                 "MissingText": true
               }
             },
-            "z": {
+            "height": {
               "Comments": {
                 "MissingText": true
               }
             },
-            "w": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "equals": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "otherQuaternion": {
+            "scene": {
               "Comments": {
                 "MissingText": true
               }
-            }
-          }
-        },
-        "fromRotationMatrix": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "matrix": {
+            },
+            "generateMipMaps": {
               "Comments": {
                 "MissingText": true
               }
-            }
-          }
-        },
-        "getClassName": {
-          "Comments": {
-            "MissingReturn": true
-          }
-        },
-        "getHashCode": {
-          "Comments": {
-            "MissingReturn": true
-          }
-        },
-        "length": {
-          "Comments": {
-            "MissingReturn": true
-          }
-        },
-        "multiply": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "q1": {
+            },
+            "invertY": {
               "Comments": {
                 "MissingText": true
               }
-            }
-          }
-        },
-        "multiplyInPlace": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "q1": {
+            },
+            "samplingMode": {
               "Comments": {
                 "MissingText": true
               }
             }
           }
         },
-        "multiplyToRef": {
+        "CreateLuminanceAlphaTexture": {
           "Comments": {
-            "MissingReturn": true
+            "MissingText": true
           },
           "Parameter": {
-            "q1": {
+            "data": {
               "Comments": {
                 "MissingText": true
               }
             },
-            "result": {
+            "width": {
               "Comments": {
                 "MissingText": true
               }
-            }
-          }
-        },
-        "normalize": {
-          "Comments": {
-            "MissingReturn": true
-          }
-        },
-        "scale": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "value": {
+            },
+            "height": {
               "Comments": {
                 "MissingText": true
               }
-            }
-          }
-        },
-        "set": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "x": {
+            },
+            "scene": {
               "Comments": {
                 "MissingText": true
               }
             },
-            "y": {
+            "generateMipMaps": {
               "Comments": {
                 "MissingText": true
               }
             },
-            "z": {
+            "invertY": {
               "Comments": {
                 "MissingText": true
               }
             },
-            "w": {
+            "samplingMode": {
               "Comments": {
                 "MissingText": true
               }
             }
           }
         },
-        "subtract": {
+        "CreateLuminanceTexture": {
           "Comments": {
-            "MissingReturn": true
+            "MissingText": true
           },
           "Parameter": {
-            "other": {
+            "data": {
               "Comments": {
                 "MissingText": true
               }
-            }
-          }
-        },
-        "toRotationMatrix": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "result": {
+            },
+            "width": {
               "Comments": {
                 "MissingText": true
               }
-            }
-          }
-        },
-        "ToString": {
-          "Comments": {
-            "MissingReturn": true
-          }
-        },
-        "FromArray": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "array": {
+            },
+            "height": {
               "Comments": {
                 "MissingText": true
               }
             },
-            "offset": {
+            "scene": {
               "Comments": {
                 "MissingText": true
               }
-            }
-          }
-        },
-        "FromRotationMatrix": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "matrix": {
+            },
+            "generateMipMaps": {
               "Comments": {
                 "MissingText": true
               }
-            }
-          }
-        },
-        "FromRotationMatrixToRef": {
-          "Parameter": {
-            "matrix": {
+            },
+            "invertY": {
               "Comments": {
                 "MissingText": true
               }
             },
-            "result": {
+            "samplingMode": {
               "Comments": {
                 "MissingText": true
               }
             }
           }
         },
-        "Hermite": {
+        "CreateRGBATexture": {
           "Comments": {
-            "MissingReturn": true
+            "MissingText": true
           },
           "Parameter": {
-            "value1": {
+            "data": {
               "Comments": {
                 "MissingText": true
               }
             },
-            "tangent1": {
+            "width": {
               "Comments": {
                 "MissingText": true
               }
             },
-            "value2": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "tangent2": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "amount": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "Identity": {
-          "Comments": {
-            "MissingReturn": true
-          }
-        },
-        "Inverse": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "q": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "IsIdentity": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "quaternion": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "RotationAlphaBetaGamma": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "alpha": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "beta": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "gamma": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "RotationAlphaBetaGammaToRef": {
-          "Parameter": {
-            "alpha": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "beta": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "gamma": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "result": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "RotationAxis": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "axis": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "angle": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "RotationAxisToRef": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "axis": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "angle": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "result": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "RotationQuaternionFromAxis": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "axis1": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "axis2": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "axis3": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "ref": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "RotationQuaternionFromAxisToRef": {
-          "Parameter": {
-            "axis1": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "axis2": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "axis3": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "ref": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "RotationYawPitchRoll": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "yaw": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "pitch": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "roll": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "RotationYawPitchRollToRef": {
-          "Parameter": {
-            "yaw": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "pitch": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "roll": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "result": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "Slerp": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "left": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "right": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "amount": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "SlerpToRef": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "left": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "right": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "amount": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "result": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "Zero": {
-          "Comments": {
-            "MissingReturn": true
-          }
-        }
-      }
-    },
-    "QuinticEase": {
-      "Class": {
-        "Comments": {
-          "MissingText": true
-        }
-      }
-    },
-    "RawTexture": {
-      "Class": {
-        "Comments": {
-          "MissingText": true
-        }
-      },
-      "Property": {
-        "format": {
-          "Comments": {
-            "MissingText": true
-          }
-        }
-      },
-      "Method": {
-        "update": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "data": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "CreateAlphaTexture": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "data": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "width": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "height": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "scene": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "generateMipMaps": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "invertY": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "samplingMode": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "CreateLuminanceAlphaTexture": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "data": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "width": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "height": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "scene": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "generateMipMaps": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "invertY": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "samplingMode": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "CreateLuminanceTexture": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "data": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "width": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "height": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "scene": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "generateMipMaps": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "invertY": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "samplingMode": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "CreateRGBATexture": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "data": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "width": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "height": {
+            "height": {
               "Comments": {
                 "MissingText": true
               }
@@ -27240,20 +26619,6 @@
               }
             }
           }
-        },
-        "updateDirectly": {
-          "Parameter": {
-            "data": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "offset": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
         }
       }
     },

文件差异内容过多而无法显示
+ 64 - 64
dist/preview release/viewer/babylon.viewer.js


文件差异内容过多而无法显示
+ 764 - 538
dist/preview release/viewer/babylon.viewer.max.js


+ 3 - 0
dist/preview release/what's new.md

@@ -136,6 +136,7 @@
 - Reflection and refraction no longer apply a toLinear conversion twice when applying image processing as a post process - [#4060](https://github.com/BabylonJS/Babylon.js/issues/4060) ([trevordev](https://github.com/trevordev))
 - Fix ember.js compatibility in ```PostProcessRenderEffect``` ([sebavan](https://github.com/sebavan))
 - Fix ember.js compatibility in ```BloomEffect``` and ```Camera``` ([kaysabelle](https://github.com/kaysabelle))
+- Fix bug with glTF animation when animating bone scale. ([bghgary](https://github.com/bghgary)]
 
 ## Breaking changes
 
@@ -144,3 +145,5 @@
 - glTF 2.0 loader now creates a mesh for each primitive instead of merging the primitives together into one mesh. If a mesh only has one primitive, the behavior is the same as before. This change only affects meshes that have multiple primitives. ([bghgary](https://github.com/bghgary)]
 - Engine's onCanvasPointerOutObservable will now return a PointerEvent instead of the Engine. ([trevordev](https://github.com/trevordev))
 - Removed public references to default rendering pipeline's internal post process ([trevordev](https://github.com/trevordev))
+- Rename `setScale`, `getScale`, `getScaleToRef` of the `Bone` class to `setAdditionalScale`, `getAdditionalScale`, `getAdditionalScaleToRef`. ([bghgary](https://github.com/bghgary)]
+- Bone `scaling` now replaces the scale of the local matrix instead of adding scale. ([bghgary](https://github.com/bghgary)]

+ 18 - 0
gui/src/advancedDynamicTexture.ts

@@ -419,6 +419,24 @@ module BABYLON.GUI {
             this._manageFocus();
         }
 
+        public _cleanControlAfterRemovalFromList(list: {[pointerId:number]:Control}, control:Control) {
+            for (var pointerId in list) {
+                if (!list.hasOwnProperty(pointerId)) {
+                    continue;
+                }
+
+                var lastControlOver = list[pointerId];
+                if (lastControlOver === control) {
+                    delete list[pointerId];
+                }
+            }
+        }
+
+        public _cleanControlAfterRemoval(control: Control) {
+            this._cleanControlAfterRemovalFromList(this._lastControlDown, control);
+            this._cleanControlAfterRemovalFromList(this._lastControlOver, control);
+        }
+
         public attach(): void {
             var scene = this.getScene();
             if (!scene) {

+ 4 - 0
gui/src/controls/container.ts

@@ -120,6 +120,10 @@ module BABYLON.GUI {
 
             control.linkWithMesh(null);
 
+            if (this._host) {
+                this._host._cleanControlAfterRemoval(control);
+            }
+
             this._markAsDirty();
             return this;
         }

+ 4 - 9
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -920,13 +920,12 @@ module BABYLON.GLTF2 {
                             outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                         })));
 
-                        const multiTarget = new AnimationMultiTarget();
+                        const morphTargets = new Array<any>();
                         this._forEachPrimitive(targetNode, babylonMesh => {
-                            const morphTarget = babylonMesh.morphTargetManager!.getTarget(targetIndex);
-                            multiTarget.subTargets.push(morphTarget);
+                            morphTargets.push(babylonMesh.morphTargetManager!.getTarget(targetIndex));
                         });
 
-                        babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                        babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTargets);
                     }
                 }
                 else {
@@ -935,11 +934,7 @@ module BABYLON.GLTF2 {
                     babylonAnimation.setKeys(keys);
 
                     if (targetNode._babylonAnimationTargets) {
-                        const multiTarget = new AnimationMultiTarget();
-                        for (const target of targetNode._babylonAnimationTargets) {
-                            multiTarget.subTargets.push(target);
-                        }
-                        babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                        babylonAnimationGroup.addTargetedAnimation(babylonAnimation, targetNode._babylonAnimationTargets);
                     }
                 }
             });

+ 0 - 28
loaders/src/glTF/2.0/babylon.glTFLoaderUtilities.ts

@@ -14,32 +14,4 @@ module BABYLON.GLTF2 {
             }
         }
     }
-
-    export class AnimationMultiTarget {
-        public subTargets = new Array<any>();
-
-        public set position(value: Vector3) {
-            for (const subTarget of this.subTargets) {
-                subTarget.position = value;
-            }
-        }
-
-        public set rotationQuaternion(value: Quaternion) {
-            for (const subTarget of this.subTargets) {
-                subTarget.rotationQuaternion = value;
-            }
-        }
-
-        public set scaling(value: Vector3) {
-            for (const subTarget of this.subTargets) {
-                subTarget.scaling = value;
-            }
-        }
-
-        public set influence(value: number) {
-            for (const subTarget of this.subTargets) {
-                subTarget.influence = value;
-            }
-        }
-    }
 }

+ 42 - 57
materialsLibrary/test/addbackground.js

@@ -26,10 +26,19 @@ window.prepareBackgroundMaterial = function() {
 	mirror.mirrorPlane = new BABYLON.Plane(0, -1.0, 0, 0.0);
 	mirror.adaptiveBlurKernel = 64;
 	
+	var perceptualColor = new BABYLON.Color3(1, 1, 1);
+	var primaryColor = new BABYLON.Color3(1, 1, 1);
+
 	registerRangeUI("background", "primaryColorR", 0, 1, function(value) {
 		mirror.clearColor.r = value;
 		back.primaryColor.r = value;
 		backSky.primaryColor.r = value;
+		if (back.perceptualColor) {
+			back.perceptualColor.r = value;
+			backSky.perceptualColor.r = value;
+		}
+		perceptualColor.r = value;
+		primaryColor.r = value;
 	}, function() {
 		return back.primaryColor.r;
 	});
@@ -38,6 +47,12 @@ window.prepareBackgroundMaterial = function() {
 		mirror.clearColor.g = value;
 		back.primaryColor.g = value;
 		backSky.primaryColor.g = value;
+		if (back.perceptualColor) {
+			back.perceptualColor.g = value;
+			backSky.perceptualColor.g = value;
+		}
+		perceptualColor.g = value;
+		primaryColor.g = value;
 	}, function() {
 		return back.primaryColor.g;
 	});
@@ -46,71 +61,28 @@ window.prepareBackgroundMaterial = function() {
 		mirror.clearColor.b = value;
 		back.primaryColor.b = value;
 		backSky.primaryColor.b = value;
+		if (back.perceptualColor) {
+			back.perceptualColor.b = value;
+			backSky.perceptualColor.b = value;
+		}
+		perceptualColor.b = value;
+		primaryColor.b = value;
 	}, function() {
 		return back.primaryColor.b;
 	});
 
-	registerRangeUI("background", "primaryLevel", 0, 30, function(value) {
-		back.primaryLevel = value;
-		backSky.primaryLevel = value;
-	}, function() {
-		return back.primaryLevel;
-	});
-
-	registerRangeUI("background", "secondaryColorR", 0, 1, function(value) {
-		back.secondaryColor.r = value;
-		backSky.secondaryColor.r = value;
-	}, function() {
-		return back.secondaryColor.r;
-	});
-
-	registerRangeUI("background", "secondaryColorG", 0, 1, function(value) {
-		back.secondaryColor.g = value;
-		backSky.secondaryColor.g = value;
-	}, function() {
-		return back.secondaryColor.g;
-	});
-
-	registerRangeUI("background", "secondaryColorB", 0, 1, function(value) {
-		back.secondaryColor.b = value;
-		backSky.secondaryColor.b = value;
-	}, function() {
-		return back.secondaryColor.b;
-	});
-
-	registerRangeUI("background", "secondaryLevel", 0, 30, function(value) {
-		back.secondaryLevel = value;
-		backSky.secondaryLevel = value;
-	}, function() {
-		return back.secondaryLevel;
-	});
-
-	registerRangeUI("background", "tertiaryColorR", 0, 1, function(value) {
-		back.tertiaryColor.r = value;
-		backSky.tertiaryColor.r = value;
+	registerRangeUI("background", "primaryColorShadowLevel", 0, 1, function(value) {
+		back.primaryColorShadowLevel = value;
+		backSky.primaryColorShadowLevel = value;
 	}, function() {
-		return back.tertiaryColor.r;
+		return back.primaryColorShadowLevel;
 	});
 
-	registerRangeUI("background", "tertiaryColorG", 0, 1, function(value) {
-		back.tertiaryColor.g = value;
-		backSky.tertiaryColor.g = value;
+	registerRangeUI("background", "primaryColorHighlightLevel", 0, 1, function(value) {
+		back.primaryColorHighlightLevel = value;		
+		backSky.primaryColorHighlightLevel = value;
 	}, function() {
-		return back.tertiaryColor.g;
-	});
-
-	registerRangeUI("background", "tertiaryColorB", 0, 1, function(value) {
-		back.tertiaryColor.b = value;
-		backSky.tertiaryColor.b = value;
-	}, function() {
-		return back.tertiaryColor.b;
-	});
-
-	registerRangeUI("background", "tertiaryLevel", 0, 30, function(value) {
-		back.tertiaryLevel = value;		
-		backSky.tertiaryLevel = value;
-	}, function() {
-		return back.tertiaryLevel;
+		return back.primaryColorHighlightLevel;
 	});
 
 	registerRangeUI("background", "reflectionBlur", 0, 1, function(value) {
@@ -148,6 +120,19 @@ window.prepareBackgroundMaterial = function() {
 		back.useRGBColor = !back.useRGBColor;
 	});
 
+	registerButtonUI("background", "TogglePerceptualColor", function() {
+		if (back.perceptualColor) {
+			back.perceptualColor = null;
+			backSky.perceptualColor = null;
+			back.primaryColor = primaryColor.clone();
+			backSky.primaryColor = primaryColor.clone();
+		}
+		else {
+			back.perceptualColor = perceptualColor.clone();
+			backSky.perceptualColor = perceptualColor.clone();
+		}
+	});
+
 	registerButtonUI("background", "ToggleSkyRGB", function() {
 		backSky.useRGBColor = !backSky.useRGBColor;
 	});

+ 2 - 1
sandbox/index.html

@@ -22,6 +22,7 @@
     <meta name="msapplication-TileImage" content="http://www.babylonjs.com/img/favicon/ms-icon-144x144.png">
     <meta name="msapplication-config" content="http://www.babylonjs.com/img/favicon/browserconfig.xml">
     <meta name="theme-color" content="#ffffff">
+    <meta name="keywords" content="3D, Babylon.js, webgl, gltf, viewer">
 
     <link href="index.css" rel="stylesheet" />
     <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
@@ -49,7 +50,7 @@
         <img id="helpArrow" src="./Assets/FlecheTuto.png" />
     </div>
     <div id="help02" class="help2">
-        <span class="helpText">Or directly drag'n'drop your files in the browser</span>
+        <span class="helpText">Or directly drag'n'drop your files (in .babylon, .gltf, .glb, .obj format) in the browser</span>
     </div>
     <div id="footer" class="footer">
         <div class="footerLeft">

+ 1 - 1
src/Animations/babylon.animatable.ts

@@ -65,12 +65,12 @@
 
 
         constructor(scene: Scene, public target: any, public fromFrame: number = 0, public toFrame: number = 100, public loopAnimation: boolean = false, speedRatio: number = 1.0, public onAnimationEnd?: Nullable<() => void>, animations?: any) {
+            this._scene = scene;
             if (animations) {
                 this.appendAnimations(target, animations);
             }
 
             this._speedRatio = speedRatio;
-            this._scene = scene;
             scene._activeAnimatables.push(this);
         }
 

+ 3 - 0
src/Animations/babylon.animation.ts

@@ -96,6 +96,9 @@
         STEP = 1
     }
 
+    /**
+     * Class used to store any kind of animation
+     */
     export class Animation {
         /**
          * Use matrix interpolation instead of using direct key value when animating matrices

+ 18 - 9
src/Animations/babylon.runtimeAnimation.ts

@@ -15,9 +15,7 @@
         private _scene: Scene;
 
         private _currentValue: any;
-        /**
-         * @ignore
-         */
+        /** @ignore */
         public _workValue: any;
         private _activeTarget: any;
         private _targetPath: string = "";
@@ -245,6 +243,17 @@
          * @param weight defines the weight to apply to this value
          */
         public setValue(currentValue: any, weight = 1.0): void {
+            if (this._target instanceof Array) {
+                for (const target of this._target) {
+                    this._setValue(target, currentValue, weight);
+                }
+            }
+            else {
+                this._setValue(this._target, currentValue, weight);
+            }
+        }
+
+        private _setValue(target: any, currentValue: any, weight = 1.0): void {
             // Set value
             var path: any;
             var destination: any;
@@ -252,7 +261,7 @@
             let targetPropertyPath = this._animation.targetPropertyPath
 
             if (targetPropertyPath.length > 1) {
-                var property = this._target[targetPropertyPath[0]];
+                var property = target[targetPropertyPath[0]];
 
                 for (var index = 1; index < targetPropertyPath.length - 1; index++) {
                     property = property[targetPropertyPath[index]];
@@ -262,7 +271,7 @@
                 destination = property;
             } else {
                 path = targetPropertyPath[0];
-                destination = this._target;
+                destination = target;
             }
 
             this._targetPath = path;
@@ -270,8 +279,8 @@
             this._weight = weight;
 
             // Blending
-            let enableBlending = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
-            let blendingSpeed = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
+            let enableBlending = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
+            let blendingSpeed = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
             
             if (enableBlending && this._blendingFactor <= 1.0) {
                 if (!this._originalBlendValue) {
@@ -340,8 +349,8 @@
                 destination[path] = this._currentValue;
             }
 
-            if (this._target.markAsDirty) {
-                this._target.markAsDirty(this._animation.targetProperty);
+            if (target.markAsDirty) {
+                target.markAsDirty(this._animation.targetProperty);
             }
         }
 

+ 63 - 47
src/Bones/babylon.bone.ts

@@ -31,19 +31,15 @@
             return this._localMatrix;
         }
 
-        set _matrix(val: Matrix) {
-            if (this._localMatrix) {
-                this._localMatrix.copyFrom(val);
-            } else {
-                this._localMatrix = val;
-            }
+        set _matrix(value: Matrix) {
+            this._localMatrix.copyFrom(value);
         }
 
         constructor(public name: string, skeleton: Skeleton, parentBone: Nullable<Bone> = null, localMatrix: Nullable<Matrix> = null,
             restPose: Nullable<Matrix> = null, baseMatrix: Nullable<Matrix> = null, index: Nullable<number> = null) {
             super(name, skeleton.getScene());
             this._skeleton = skeleton;
-            this._localMatrix = localMatrix ? localMatrix : Matrix.Identity();
+            this._localMatrix = localMatrix ? localMatrix.clone() : Matrix.Identity();
             this._restPose = restPose ? restPose : this._localMatrix.clone();
             this._baseMatrix = baseMatrix ? baseMatrix : this._localMatrix.clone();
             this._index = index;
@@ -85,6 +81,8 @@
             if (updateDifferenceMatrix) {
                 this._updateDifferenceMatrix();
             }
+
+            this.markAsDirty();
         }
 
         public getLocalMatrix(): Matrix {
@@ -141,13 +139,17 @@
         }
 
         public get scaling(): Vector3 {
-            return this.getScale();
+            let value = Vector3.One();
+            this._localMatrix.decompose(value, undefined, undefined);
+            return value;
         }
 
         public set scaling(newScaling: Vector3) {
-            this.setScale(newScaling.x, newScaling.y, newScaling.z);
+            this._localMatrix.decompose(undefined, Bone._tmpQuat, Bone._tmpVecs[0]);
+            Matrix.ComposeToRef(newScaling, Bone._tmpQuat, Bone._tmpVecs[0], this._localMatrix);
+            this.markAsDirty();
         }
-        
+
         /**
          * Gets the animation properties override
          */
@@ -157,14 +159,14 @@
 
         // Methods
         public updateMatrix(matrix: Matrix, updateDifferenceMatrix = true): void {
-            this._baseMatrix = matrix.clone();
-            this._localMatrix = matrix.clone();
-
-            this._skeleton._markAsDirty();
+            this._baseMatrix.copyFrom(matrix);
+            this._localMatrix.copyFrom(matrix);
 
             if (updateDifferenceMatrix) {
                 this._updateDifferenceMatrix();
             }
+
+            this.markAsDirty();
         }
 
         public _updateDifferenceMatrix(rootMatrix?: Matrix): void {
@@ -367,13 +369,13 @@
         }
 
         /**
-         * Set the scale of the bone on the x, y and z axes.
-         * @param x The scale of the bone on the x axis.
-         * @param x The scale of the bone on the y axis.
-         * @param z The scale of the bone on the z axis.
+         * Adds an additional scale to the bone on the x, y and z axes.
+         * @param x The additional scale of the bone on the x axis.
+         * @param y The additional scale of the bone on the y axis.
+         * @param z The additional scale of the bone on the z axis.
          * @param scaleChildren Set this to true if children of the bone should be scaled.
          */
-        public setScale(x: number, y: number, z: number, scaleChildren = false): void {
+        public setAdditionalScale(x: number, y: number, z: number, scaleChildren = false): void {
 
             if (this.animations[0] && !this.animations[0].hasRunningRuntimeAnimations) {
                 if (!scaleChildren) {
@@ -406,7 +408,7 @@
             origLocMatInv.invert();
 
             var scaleMat = Bone._tmpMats[2];
-            Matrix.FromValuesToRef(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1, scaleMat);
+            Matrix.ScalingToRef(x, y, z, scaleMat);
             this._scaleMatrix.multiplyToRef(scaleMat, this._scaleMatrix);
             this._scaleVector.x *= x;
             this._scaleVector.y *= y;
@@ -460,15 +462,15 @@
          */
         public setYawPitchRoll(yaw: number, pitch: number, roll: number, space = Space.LOCAL, mesh?: AbstractMesh): void {
 
-            var rotMat = Bone._tmpMats[0];
-            Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, rotMat);
-
-            var rotMatInv = Bone._tmpMats[1];
+            var rotMatInv = Bone._tmpMats[0];
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
 
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
+            var rotMat = Bone._tmpMats[1];
+            Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, rotMat);
 
             rotMatInv.multiplyToRef(rotMat, rotMat);
-
             this._rotateWithMatrix(rotMat, space, mesh);
 
         }
@@ -502,11 +504,13 @@
          */
         public setAxisAngle(axis: Vector3, angle: number, space = Space.LOCAL, mesh?: AbstractMesh): void {
 
-            var rotMat = Bone._tmpMats[0];
-            Matrix.RotationAxisToRef(axis, angle, rotMat);
-            var rotMatInv = Bone._tmpMats[1];
+            var rotMatInv = Bone._tmpMats[0];
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
 
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
+            var rotMat = Bone._tmpMats[1];
+            Matrix.RotationAxisToRef(axis, angle, rotMat);
 
             rotMatInv.multiplyToRef(rotMat, rotMat);
             this._rotateWithMatrix(rotMat, space, mesh);
@@ -534,8 +538,9 @@
         public setRotationQuaternion(quat: Quaternion, space = Space.LOCAL, mesh?: AbstractMesh): void {
 
             var rotMatInv = Bone._tmpMats[0];
-
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
 
             var rotMat = Bone._tmpMats[1];
             Matrix.FromQuaternionToRef(quat, rotMat);
@@ -555,8 +560,9 @@
         public setRotationMatrix(rotMat: Matrix, space = Space.LOCAL, mesh?: AbstractMesh): void {
 
             var rotMatInv = Bone._tmpMats[0];
-
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
 
             var rotMat2 = Bone._tmpMats[1];
             rotMat2.copyFrom(rotMat);
@@ -616,7 +622,7 @@
 
         }
 
-        private _getNegativeRotationToRef(rotMatInv: Matrix, space = Space.LOCAL, mesh?: AbstractMesh): void {
+        private _getNegativeRotationToRef(rotMatInv: Matrix, space = Space.LOCAL, mesh?: AbstractMesh): boolean {
 
             if (space == Space.WORLD) {
                 var scaleMatrix = Bone._tmpMats[2];
@@ -631,11 +637,23 @@
                 }
 
                 rotMatInv.invert();
+                if (isNaN(rotMatInv.m[0])) {
+                    // Matrix failed to invert.
+                    // This can happen if scale is zero for example.
+                    return false;
+                }
+
                 scaleMatrix.m[0] *= this._scalingDeterminant;
                 rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
             } else {
                 rotMatInv.copyFrom(this.getLocalMatrix());
                 rotMatInv.invert();
+                if (isNaN(rotMatInv.m[0])) {
+                    // Matrix failed to invert.
+                    // This can happen if scale is zero for example.
+                    return false;
+                }
+
                 var scaleMatrix = Bone._tmpMats[2];
                 scaleMatrix.copyFrom(this._scaleMatrix);
 
@@ -651,26 +669,24 @@
                 rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
             }
 
+            return true;
+
         }
 
         /**
-         * Get the scale of the bone
-         * @returns the scale of the bone
+         * Get the additional scale of the bone
+         * @returns the additional scale of the bone
          */
-        public getScale(): Vector3 {
-
+        public getAdditionalScale(): Vector3 {
             return this._scaleVector.clone();
-
         }
 
         /**
-         * Copy the scale of the bone to a vector3.
-         * @param result The vector3 to copy the scale to
+         * Copy the additional scale of the bone to a vector3.
+         * @param result The vector3 to copy the additional scale to
          */
-        public getScaleToRef(result: Vector3): void {
-
+        public getAdditionalScaleToRef(result: Vector3): void {
             result.copyFrom(this._scaleVector);
-
         }
 
         /**
@@ -909,7 +925,7 @@
 
             if (space == Space.LOCAL) {
 
-                this.getLocalMatrix().decompose(Bone._tmpVecs[0], result, Bone._tmpVecs[1]);
+                this.getLocalMatrix().decompose(undefined, result, undefined);
 
             } else {
 
@@ -926,7 +942,7 @@
                 mat.m[1] *= this._scalingDeterminant;
                 mat.m[2] *= this._scalingDeterminant;
 
-                mat.decompose(Bone._tmpVecs[0], result, Bone._tmpVecs[1]);
+                mat.decompose(undefined, result, undefined);
 
             }
         }

+ 2 - 2
src/Bones/babylon.boneIKController.ts

@@ -83,8 +83,8 @@ module BABYLON {
             
             if (this._bone1.length) {
 
-                var boneScale1 = this._bone1.getScale();
-                var boneScale2 = this._bone2.getScale();
+                var boneScale1 = this._bone1.getAdditionalScale();
+                var boneScale2 = this._bone2.getAdditionalScale();
                 
                 this._bone1Length = this._bone1.length * boneScale1.y * this.mesh.scaling.y;
                 this._bone2Length = this._bone2.length * boneScale2.y * this.mesh.scaling.y;

+ 59 - 83
src/Engine/babylon.engine.ts

@@ -1013,7 +1013,7 @@
         private _internalTexturesCache = new Array<InternalTexture>();
         /** @ignore */
         protected _activeChannel = 0;
-        private _currentTextureChannel = -1;
+        private _currentTextureChannel = -1;    
         /** @ignore */
         protected _boundTexturesCache: { [key: string]: Nullable<InternalTexture> } = {};
         /** @ignore */
@@ -1662,13 +1662,16 @@
          */
         public resetTextureCache() {
             for (var key in this._boundTexturesCache) {
+                if (!this._boundTexturesCache.hasOwnProperty(key)) {
+                    continue;
+                }
                 let boundTexture = this._boundTexturesCache[key];
                 if (boundTexture) {
                     this._removeDesignatedSlot(boundTexture);
                 }
                 this._boundTexturesCache[key] = null;
-            }
-
+            }       
+            
             if (!this.disableTextureBindingOptimization) {
                 this._nextFreeTextureSlots = [];
                 for (let slot = 0; slot < this._maxSimultaneousTextures; slot++) {
@@ -4457,22 +4460,16 @@
             var filters = getSamplingParameters(samplingMode, texture.generateMipMaps, this._gl);
 
             if (texture.isCube) {
-                this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, texture, true);
-
-                this._gl.texParameteri(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_MAG_FILTER, filters.mag);
-                this._gl.texParameteri(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_MIN_FILTER, filters.min);
+                this._setTextureParameterInteger(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_MAG_FILTER, filters.mag, texture);
+                this._setTextureParameterInteger(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_MIN_FILTER, filters.min);
                 this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
             } else if (texture.is3D) {
-                this._bindTextureDirectly(this._gl.TEXTURE_3D, texture, true);
-
-                this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_MAG_FILTER, filters.mag);
-                this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_MIN_FILTER, filters.min);
+                this._setTextureParameterInteger(this._gl.TEXTURE_3D, this._gl.TEXTURE_MAG_FILTER, filters.mag, texture);
+                this._setTextureParameterInteger(this._gl.TEXTURE_3D, this._gl.TEXTURE_MIN_FILTER, filters.min);
                 this._bindTextureDirectly(this._gl.TEXTURE_3D, null);
             } else {
-                this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);
-
-                this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, filters.mag);
-                this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, filters.min);
+                this._setTextureParameterInteger(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, filters.mag, texture);
+                this._setTextureParameterInteger(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, filters.min);
                 this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
             }
 
@@ -6217,7 +6214,7 @@
         }
 
         /** @ignore */
-        protected _bindTextureDirectly(target: number, texture: Nullable<InternalTexture>, forTextureDataUpdate = false): void {
+        protected _bindTextureDirectly(target: number, texture: Nullable<InternalTexture>, forTextureDataUpdate = false, force = false): void {
             if (forTextureDataUpdate && texture && texture._designatedSlot > -1) {
                 this._activeChannel = texture._designatedSlot;
             }
@@ -6225,7 +6222,7 @@
             let currentTextureBound = this._boundTexturesCache[this._activeChannel];
             let isTextureForRendering = texture && texture._initialSlot > -1;
 
-            if (currentTextureBound !== texture) {
+            if (currentTextureBound !== texture || force) {
                 if (currentTextureBound) {
                     this._removeDesignatedSlot(currentTextureBound);
                 }
@@ -6353,6 +6350,18 @@
             uniform._currentState = destination;
         }
 
+        private _getTextureWrapMode(mode: number): number {
+            switch(mode) {
+                case Texture.WRAP_ADDRESSMODE:
+                    return this._gl.REPEAT;
+                case Texture.CLAMP_ADDRESSMODE:
+                    return this._gl.CLAMP_TO_EDGE;
+                case Texture.MIRROR_ADDRESSMODE:
+                    return this._gl.MIRRORED_REPEAT;
+            }
+            return this._gl.REPEAT;
+        }
+
         private _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray = false, depthStencilTexture = false): boolean {
             // Not ready?
             if (!texture) {
@@ -6397,111 +6406,67 @@
                 channel = this._getCorrectTextureChannel(channel, internalTexture);
             }
 
+            let needToBind = true;
             if (this._boundTexturesCache[channel] === internalTexture) {
                 this._moveBoundTextureOnTop(internalTexture);
                 if (!isPartOfTextureArray) {
                     this._bindSamplerUniformToChannel(internalTexture._initialSlot, channel);
                 }
-                return false;
+                
+                needToBind = false;
             }
 
             this._activeChannel = channel;
 
             if (internalTexture && internalTexture.is3D) {
-                this._bindTextureDirectly(this._gl.TEXTURE_3D, internalTexture, isPartOfTextureArray);
+                if (needToBind) {
+                    this._bindTextureDirectly(this._gl.TEXTURE_3D, internalTexture, isPartOfTextureArray);
+                }
 
                 if (internalTexture && internalTexture._cachedWrapU !== texture.wrapU) {
                     internalTexture._cachedWrapU = texture.wrapU;
-
-                    switch (texture.wrapU) {
-                        case Texture.WRAP_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_S, this._gl.REPEAT);
-                            break;
-                        case Texture.CLAMP_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_S, this._gl.CLAMP_TO_EDGE);
-                            break;
-                        case Texture.MIRROR_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_S, this._gl.MIRRORED_REPEAT);
-                            break;
-                    }
+                    this._setTextureParameterInteger(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_S, this._getTextureWrapMode(texture.wrapU), internalTexture);
                 }
 
                 if (internalTexture && internalTexture._cachedWrapV !== texture.wrapV) {
                     internalTexture._cachedWrapV = texture.wrapV;
-                    switch (texture.wrapV) {
-                        case Texture.WRAP_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_T, this._gl.REPEAT);
-                            break;
-                        case Texture.CLAMP_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_T, this._gl.CLAMP_TO_EDGE);
-                            break;
-                        case Texture.MIRROR_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_T, this._gl.MIRRORED_REPEAT);
-                            break;
-                    }
+                    this._setTextureParameterInteger(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_T, this._getTextureWrapMode(texture.wrapV), internalTexture);
                 }
 
                 if (internalTexture && internalTexture._cachedWrapR !== texture.wrapR) {
                     internalTexture._cachedWrapR = texture.wrapR;
-                    switch (texture.wrapR) {
-                        case Texture.WRAP_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_R, this._gl.REPEAT);
-                            break;
-                        case Texture.CLAMP_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_R, this._gl.CLAMP_TO_EDGE);
-                            break;
-                        case Texture.MIRROR_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_R, this._gl.MIRRORED_REPEAT);
-                            break;
-                    }
+                    this._setTextureParameterInteger(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_R, this._getTextureWrapMode(texture.wrapR), internalTexture);
                 }
 
                 this._setAnisotropicLevel(this._gl.TEXTURE_3D, texture);
             }
             else if (internalTexture && internalTexture.isCube) {
-                this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, internalTexture, isPartOfTextureArray);
+                if (needToBind) {
+                    this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, internalTexture, isPartOfTextureArray);
+                }                
 
                 if (internalTexture._cachedCoordinatesMode !== texture.coordinatesMode) {
                     internalTexture._cachedCoordinatesMode = texture.coordinatesMode;
                     // CUBIC_MODE and SKYBOX_MODE both require CLAMP_TO_EDGE.  All other modes use REPEAT.
                     var textureWrapMode = (texture.coordinatesMode !== Texture.CUBIC_MODE && texture.coordinatesMode !== Texture.SKYBOX_MODE) ? this._gl.REPEAT : this._gl.CLAMP_TO_EDGE;
-                    this._gl.texParameteri(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_WRAP_S, textureWrapMode);
-                    this._gl.texParameteri(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_WRAP_T, textureWrapMode);
+                    this._setTextureParameterInteger(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_WRAP_S, textureWrapMode, internalTexture);
+                    this._setTextureParameterInteger(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_WRAP_T, textureWrapMode);
                 }
 
                 this._setAnisotropicLevel(this._gl.TEXTURE_CUBE_MAP, texture);
             } else {
-                this._bindTextureDirectly(this._gl.TEXTURE_2D, internalTexture, isPartOfTextureArray);
+                if (needToBind) {               
+                    this._bindTextureDirectly(this._gl.TEXTURE_2D, internalTexture, isPartOfTextureArray);
+                }
 
                 if (internalTexture && internalTexture._cachedWrapU !== texture.wrapU) {
                     internalTexture._cachedWrapU = texture.wrapU;
-
-                    switch (texture.wrapU) {
-                        case Texture.WRAP_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_S, this._gl.REPEAT);
-                            break;
-                        case Texture.CLAMP_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_S, this._gl.CLAMP_TO_EDGE);
-                            break;
-                        case Texture.MIRROR_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_S, this._gl.MIRRORED_REPEAT);
-                            break;
-                    }
+                    this._setTextureParameterInteger(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_S, this._getTextureWrapMode(texture.wrapU), internalTexture);
                 }
 
                 if (internalTexture && internalTexture._cachedWrapV !== texture.wrapV) {
                     internalTexture._cachedWrapV = texture.wrapV;
-                    switch (texture.wrapV) {
-                        case Texture.WRAP_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_T, this._gl.REPEAT);
-                            break;
-                        case Texture.CLAMP_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_T, this._gl.CLAMP_TO_EDGE);
-                            break;
-                        case Texture.MIRROR_ADDRESSMODE:
-                            this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_T, this._gl.MIRRORED_REPEAT);
-                            break;
-                    }
+                    this._setTextureParameterInteger(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_T, this._getTextureWrapMode(texture.wrapV), internalTexture);
                 }
 
                 this._setAnisotropicLevel(this._gl.TEXTURE_2D, texture);
@@ -6535,7 +6500,7 @@
         }
 
         /** @ignore */
-        public _setAnisotropicLevel(key: number, texture: BaseTexture) {
+        public _setAnisotropicLevel(target: number, texture: BaseTexture) {
             var internalTexture = texture.getInternalTexture();
 
             if (!internalTexture) {
@@ -6545,7 +6510,6 @@
             var anisotropicFilterExtension = this._caps.textureAnisotropicFilterExtension;
             var value = texture.anisotropicFilteringLevel;
 
-
             if (internalTexture.samplingMode !== Texture.LINEAR_LINEAR_MIPNEAREST
                 && internalTexture.samplingMode !== Texture.LINEAR_LINEAR_MIPLINEAR
                 && internalTexture.samplingMode !== Texture.LINEAR_LINEAR) {
@@ -6553,11 +6517,23 @@
             }
 
             if (anisotropicFilterExtension && internalTexture._cachedAnisotropicFilteringLevel !== value) {
-                this._gl.texParameterf(key, anisotropicFilterExtension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(value, this._caps.maxAnisotropy));
+                this._setTextureParameterFloat(target, anisotropicFilterExtension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(value, this._caps.maxAnisotropy), internalTexture);
                 internalTexture._cachedAnisotropicFilteringLevel = value;
             }
         }
 
+        private _setTextureParameterFloat(target: number, parameter: number, value: number, texture: InternalTexture): void {
+            this._bindTextureDirectly(target, texture, true, true);
+            this._gl.texParameterf(target, parameter, value);
+        }
+
+        private _setTextureParameterInteger(target: number, parameter: number, value: number, texture?: InternalTexture) {
+            if (texture) {
+                this._bindTextureDirectly(target, texture, true, true);
+            }
+            this._gl.texParameteri(target, parameter, value);
+        }
+
         /**
          * Reads pixels from the current frame buffer. Please note that this function can be slow
          * @param x defines the x coordinate of the rectangle where pixels must be read

+ 24 - 11
src/Helpers/babylon.environmentHelper.ts

@@ -395,19 +395,38 @@ module BABYLON {
 
         /**
          * Sets the primary color of all the available elements.
-         * @param color 
+         * @param color the main color to affect to the ground and the background
+         * @param perceptual Specifies wether the chosen color has been set as intented to be seen e.g. in gamma space not accounting for exposure and tone mapping
          */
-        public setMainColor(color: Color3): void {
+        public setMainColor(color: Color3, perceptual = false): void {
             if (this.groundMaterial) {
-                this.groundMaterial.primaryColor = color;
+                if (perceptual) {
+                    this.groundMaterial.perceptualColor = color;
+                }
+                else {
+                    this.groundMaterial.primaryColor = color;
+                }
             }
 
             if (this.skyboxMaterial) {
-                this.skyboxMaterial.primaryColor = color;
+                if (perceptual) {
+                    this.skyboxMaterial.perceptualColor = color;
+                }
+                else {
+                    this.skyboxMaterial.primaryColor = color;
+                }
             }
 
             if (this.groundMirror) {
-                this.groundMirror.clearColor = new Color4(color.r, color.g, color.b, 1.0);
+                if (perceptual && this.groundMaterial) {
+                    this.groundMirror.clearColor = new Color4(this.groundMaterial.primaryColor.r, 
+                        this.groundMaterial.primaryColor.g, 
+                        this.groundMaterial.primaryColor.b, 
+                        1.0);
+                }
+                else {
+                    this.groundMirror.clearColor = new Color4(color.r, color.g, color.b, 1.0);
+                }
             }
         }
 
@@ -535,10 +554,7 @@ module BABYLON {
             this._groundMaterial.alpha = this._options.groundOpacity;
             this._groundMaterial.alphaMode = Engine.ALPHA_PREMULTIPLIED_PORTERDUFF;
             this._groundMaterial.shadowLevel = this._options.groundShadowLevel;
-            this._groundMaterial.primaryLevel = 1;
             this._groundMaterial.primaryColor = this._options.groundColor;
-            this._groundMaterial.secondaryLevel = 0;
-            this._groundMaterial.tertiaryLevel = 0;
             this._groundMaterial.useRGBColor = false;
             this._groundMaterial.enableNoise = true;
 
@@ -645,10 +661,7 @@ module BABYLON {
                 this._skyboxMaterial = new BackgroundMaterial("BackgroundSkyboxMaterial", this._scene);
             }
             this._skyboxMaterial.useRGBColor = false;
-            this._skyboxMaterial.primaryLevel = 1;
             this._skyboxMaterial.primaryColor = this._options.skyboxColor;
-            this._skyboxMaterial.secondaryLevel = 0;
-            this._skyboxMaterial.tertiaryLevel = 0;
             this._skyboxMaterial.enableNoise = true;
 
             this._skybox.material = this._skyboxMaterial;

+ 128 - 43
src/Materials/Background/babylon.backgroundMaterial.ts

@@ -60,6 +60,12 @@
         public USERGBCOLOR = false;
 
         /**
+         * True if highlight and shadow levels have been specified. It can help ensuring the main perceived color
+         * stays aligned with the desired configuration.
+         */
+        public USEHIGHLIGHTANDSHADOWCOLORS = false;
+
+        /**
          * True to add noise in order to reduce the banding effect.
          */
         public NOISE = false;
@@ -143,49 +149,60 @@
         @serializeAsColor3()
         protected _primaryColor: Color3;
         /**
-         * Key light Color (multiply against the R channel of the environement texture)
+         * Key light Color (multiply against the environement texture)
          */
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         public primaryColor = Color3.White();
-
-        @serialize()
-        protected _primaryLevel: float;
-        /**
-         * Key light Level (allowing HDR output of the background)
-         */
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public primaryLevel: float = 1;
+        
         @serializeAsColor3()
-        protected _secondaryColor: Color3;
+        protected _perceptualColor: Nullable<Color3>;
         /**
-         * Secondary light Color (multiply against the G channel of the environement texture)
+         * Key light Color in "perceptual value" meaning the color you would like to see on screen.
+         * This acts as a helper to set the primary color to a more "human friendly" value.
+         * Conversion to linear space as well as exposure and tone mapping correction will be applied to keep the
+         * output color as close as possible from the chosen value.
+         * (This does not account for contrast color grading and color curves as they are considered post effect and not directly
+         * part of lighting setup.)
          */
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public secondaryColor = Color3.Gray();
+        public get perceptualColor(): Nullable<Color3> {
+            return this._perceptualColor;
+        }
+        public set perceptualColor(value: Nullable<Color3>) {
+            this._perceptualColor = value;
+            this._computePrimaryColorFromPerceptualColor();
+            this._markAllSubMeshesAsLightsDirty();
+        }
 
         @serialize()
-        protected _secondaryLevel: float;
-        /**
-         * Secondary light Level (allowing HDR output of the background)
-         */
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public secondaryLevel: float = 1;
-
-        @serializeAsColor3()
-        protected _tertiaryColor: Color3;
+        protected _primaryColorShadowLevel: float = 0;
         /**
-         * Tertiary light Color (multiply against the B channel of the environement texture)
+         * Defines the level of the shadows (dark area of the reflection map) in order to help scaling the colors.
+         * The color opposite to the primary color is used at the level chosen to define what the black area would look.
          */
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public tertiaryColor = Color3.Black();
+        public get primaryColorShadowLevel(): float {
+            return this._primaryColorShadowLevel;
+        }
+        public set primaryColorShadowLevel(value: float) {
+            this._primaryColorShadowLevel = value;
+            this._computePrimaryColors();
+            this._markAllSubMeshesAsLightsDirty();
+        }
 
         @serialize()
-        protected _tertiaryLevel: float;
+        protected _primaryColorHighlightLevel: float = 0;
         /**
-         * Tertiary light Level (allowing HDR output of the background)
+         * Defines the level of the highliights (highlight area of the reflection map) in order to help scaling the colors.
+         * The primary color is used at the level chosen to define what the white area would look.
          */
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public tertiaryLevel: float = 1;
+        public get primaryColorHighlightLevel(): float {
+            return this._primaryColorHighlightLevel;
+        }
+        public set primaryColorHighlightLevel(value: float) {
+            this._primaryColorHighlightLevel = value;
+            this._computePrimaryColors();
+            this._markAllSubMeshesAsLightsDirty();
+        }
 
         @serializeAsTexture()
         protected _reflectionTexture: Nullable<BaseTexture>;
@@ -225,15 +242,6 @@
         public shadowLights: Nullable<IShadowLight[]> = null;
 
         @serialize()
-        protected _shadowBlurScale: int;
-        /**
-         * For the lights having a blurred shadow generator, this can add a second blur pass in order to reach
-         * soft lighting on the background.
-         */
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public shadowBlurScale: int = 1;
-
-        @serialize()
         protected _shadowLevel: float;
         /**
          * Helps adjusting the shadow to a softer level if required.
@@ -400,6 +408,7 @@
 
             // Attaches observer.
             this._imageProcessingObserver = this._imageProcessingConfiguration.onUpdateParameters.add(conf => {
+                this._computePrimaryColorFromPerceptualColor();
                 this._markAllSubMeshesAsImageProcessingDirty();
             });
         }
@@ -534,6 +543,9 @@
         // Temp values kept as cache in the material.
         private _renderTargets = new SmartArray<RenderTargetTexture>(16);
         private _reflectionControls = Vector4.Zero();
+        private _white = Color3.White();
+        private _primaryShadowColor = Color3.Black();
+        private _primaryHighlightColor = Color3.Black();
 
         /**
          * Instantiates a Background Material in the given scene
@@ -723,6 +735,10 @@
                 defines.NOISE = this._enableNoise;
             }
 
+            if (defines._areLightsDirty) {
+                defines.USEHIGHLIGHTANDSHADOWCOLORS = !this._useRGBColor && (this._primaryColorShadowLevel !== 0 || this._primaryColorHighlightLevel !== 0);
+            }
+
             if (defines._areImageProcessingDirty) {
                 if (!this._imageProcessingConfiguration.isReady()) {
                     return false;
@@ -790,7 +806,7 @@
                     "vFogInfos", "vFogColor", "pointSize",
                     "vClipPlane", "mBones",
 
-                    "vPrimaryColor", "vSecondaryColor", "vTertiaryColor",
+                    "vPrimaryColor", "vPrimaryColorShadow",
                     "vReflectionInfos", "reflectionMatrix", "vReflectionMicrosurfaceInfos", "fFovMultiplier",
 
                     "shadowLevel", "alpha",
@@ -849,13 +865,78 @@
         }
 
         /**
+         * Tone Mapping calibration (should match image processing tone mapping calibration value).
+         */
+        private static readonly _tonemappingCalibration = 1.590579;
+
+        /**
+         * Compute the primary color according to the chosen perceptual color.
+         */
+        private _computePrimaryColorFromPerceptualColor(): void {
+            if (!this._perceptualColor) {
+                return;
+            }
+
+            this._primaryColor.copyFrom(this._perceptualColor);
+
+            // Revert gamma space.
+            this._primaryColor.toLinearSpaceToRef(this._primaryColor);
+
+            // Revert image processing configuration.
+            if (this._imageProcessingConfiguration) {
+                // Revert tone mapping.
+                if (this._imageProcessingConfiguration.toneMappingEnabled) {
+                    // shader reference.
+                    // tonemapped.rgb = 1.0 - exp2(-tonemappingCalibration * color.rgb);
+                    // providing
+                    // log2(1.0 - tonemapped.rgb) / -tonemappingCalibration = color.rgb;
+
+                    // 1.0 - tonemapped.rgb
+                    this._white.subtractToRef(this._primaryColor, this._primaryColor);
+
+                    // log2(1.0 - tonemapped.rgb)
+                    this._primaryColor.r = Scalar.Log2(this._primaryColor.r);
+                    this._primaryColor.g = Scalar.Log2(this._primaryColor.g);
+                    this._primaryColor.b = Scalar.Log2(this._primaryColor.b);
+                    
+                    // log2(1.0 - tonemapped.rgb) / -tonemappingCalibration
+                    this._primaryColor.scaleToRef(-1 / BackgroundMaterial._tonemappingCalibration, this._primaryColor);
+                }
+
+                // Revert Exposure.
+                this._primaryColor.scaleToRef(1 / this._imageProcessingConfiguration.exposure, this._primaryColor);
+            }
+
+            this._computePrimaryColors();
+        }
+
+        /**
+         * Compute the highlights and shadow colors according to their chosen levels.
+         */
+        private _computePrimaryColors(): void {
+            if (this._primaryColorShadowLevel === 0 && this._primaryColorHighlightLevel === 0) {
+                return;
+            }
+
+            // Find the highlight color based on the configuration.
+            this._primaryColor.scaleToRef(this._primaryColorShadowLevel, this._primaryShadowColor);
+            this._primaryColor.subtractToRef(this._primaryShadowColor, this._primaryShadowColor);
+            this._primaryShadowColor.clampToRef(0, 1, this._primaryShadowColor);
+
+            // Find the shadow color based on the configuration.
+            this._white.subtractToRef(this._primaryColor, this._primaryHighlightColor);
+            this._primaryHighlightColor.scaleToRef(this._primaryColorHighlightLevel, this._primaryHighlightColor);
+            this._primaryColor.addToRef(this._primaryHighlightColor, this._primaryHighlightColor);
+            this._primaryHighlightColor.clampToRef(0, 1, this._primaryHighlightColor);
+        }
+
+        /**
          * Build the uniform buffer used in the material.
          */
         public buildUniformLayout(): void {
             // Order is important !
             this._uniformBuffer.addUniform("vPrimaryColor", 4);
-            this._uniformBuffer.addUniform("vSecondaryColor", 4);
-            this._uniformBuffer.addUniform("vTertiaryColor", 4);
+            this._uniformBuffer.addUniform("vPrimaryColorShadow", 4);
             this._uniformBuffer.addUniform("vDiffuseInfos", 2);
             this._uniformBuffer.addUniform("vReflectionInfos", 2);
             this._uniformBuffer.addUniform("diffuseMatrix", 16);
@@ -956,9 +1037,13 @@
                         this._uniformBuffer.updateFloat("pointSize", this.pointSize);
                     }
 
-                    this._uniformBuffer.updateColor4("vPrimaryColor", this._primaryColor, this._primaryLevel);
-                    this._uniformBuffer.updateColor4("vSecondaryColor", this._secondaryColor, this._secondaryLevel);
-                    this._uniformBuffer.updateColor4("vTertiaryColor", this._tertiaryColor, this._tertiaryLevel);
+                    if (defines.USEHIGHLIGHTANDSHADOWCOLORS) {
+                        this._uniformBuffer.updateColor4("vPrimaryColor", this._primaryHighlightColor, 1.0);
+                        this._uniformBuffer.updateColor4("vPrimaryColorShadow", this._primaryShadowColor, 1.0);
+                    }
+                    else {
+                        this._uniformBuffer.updateColor4("vPrimaryColor", this._primaryColor, 1.0);
+                    }
                 }
 
                 this._uniformBuffer.updateFloat("fFovMultiplier", this._fovMultiplier);

+ 3 - 1
src/Materials/Textures/babylon.mirrorTexture.ts

@@ -94,7 +94,9 @@
             this.ignoreCameraViewport = true;
             
             this._updateGammaSpace();
-            this._imageProcessingConfigChangeObserver = scene.imageProcessingConfiguration.onUpdateParameters.add(this._updateGammaSpace)
+            this._imageProcessingConfigChangeObserver = scene.imageProcessingConfiguration.onUpdateParameters.add(() => {
+                this._updateGammaSpace
+            });
 
             this.onBeforeRenderObservable.add(() => {
                 Matrix.ReflectionToRef(this.mirrorPlane, this._mirrorMatrix);

文件差异内容过多而无法显示
+ 414 - 266
src/Math/babylon.math.ts


+ 6 - 6
src/Mesh/babylon.buffer.ts

@@ -34,7 +34,7 @@
 
             this._data = data;
 
-            this.byteStride = useBytes ? stride : stride * 4;
+            this.byteStride = useBytes ? stride : stride * Float32Array.BYTES_PER_ELEMENT;
 
             if (!postponeInternalCreation) { // by default
                 this.create();
@@ -52,8 +52,8 @@
          * @returns the new vertex buffer
          */
         public createVertexBuffer(kind: string, offset: number, size: number, stride?: number, instanced?: boolean, useBytes = false): VertexBuffer {
-            const byteOffset = useBytes ? offset : offset * 4;
-            const byteStride = stride ? (useBytes ? stride : stride * 4) : this.byteStride;
+            const byteOffset = useBytes ? offset : offset * Float32Array.BYTES_PER_ELEMENT;
+            const byteStride = stride ? (useBytes ? stride : stride * Float32Array.BYTES_PER_ELEMENT) : this.byteStride;
 
             // a lot of these parameters are ignored as they are overriden by the buffer
             return new VertexBuffer(this._engine, this, kind, this._updatable, true, byteStride, instanced === undefined ? this._instanced : instanced, byteOffset, size, undefined, undefined, true);
@@ -79,7 +79,7 @@
          * @returns the stride in float32 units
          */
         public getStrideSize(): number {
-            return this.byteStride / 4;
+            return this.byteStride / Float32Array.BYTES_PER_ELEMENT;
         }
 
         // Methods
@@ -123,13 +123,13 @@
          * @param vertexCount the vertex count (optional)
          * @param useBytes set to true if the offset is in bytes
          */
-        public updateDirectly(data: DataArray, offset: number, vertexCount?: number, useBytes = false): void {
+        public updateDirectly(data: DataArray, offset: number, vertexCount?: number, useBytes: boolean = false): void {
             if (!this._buffer) {
                 return;
             }
 
             if (this._updatable) { // update buffer
-                this._engine.updateDynamicVertexBuffer(this._buffer, data, useBytes ? offset : offset * 4, (vertexCount ? vertexCount * this.byteStride : undefined));
+                this._engine.updateDynamicVertexBuffer(this._buffer, data, useBytes ? offset : offset * Float32Array.BYTES_PER_ELEMENT, (vertexCount ? vertexCount * this.byteStride : undefined));
                 this._data = null;
             }
         }

+ 3 - 2
src/Mesh/babylon.geometry.ts

@@ -271,15 +271,16 @@
          * @param kind defines the data kind (Position, normal, etc...)
          * @param data defines the data to use 
          * @param offset defines the offset in the target buffer where to store the data
+         * @param useBytes set to true if the offset is in bytes
          */
-        public updateVerticesDataDirectly(kind: string, data: Float32Array, offset: number): void {
+        public updateVerticesDataDirectly(kind: string, data: DataArray, offset: number, useBytes: boolean = false): void {
             var vertexBuffer = this.getVertexBuffer(kind);
 
             if (!vertexBuffer) {
                 return;
             }
 
-            vertexBuffer.updateDirectly(data, offset);
+            vertexBuffer.updateDirectly(data, offset, useBytes);
             this.notifyUpdate(kind);
         }
 

+ 6 - 3
src/Mesh/babylon.vertexBuffer.ts

@@ -232,10 +232,13 @@
 
         /**
          * Updates directly the underlying WebGLBuffer according to the passed numeric array or Float32Array.  
-         * Returns the directly updated WebGLBuffer. 
+         * Returns the directly updated WebGLBuffer.
+         * @param data the new data
+         * @param offset the new offset
+         * @param useBytes set to true if the offset is in bytes
          */
-        public updateDirectly(data: DataArray, offset: number): void {
-            return this._buffer.updateDirectly(data, offset);
+        public updateDirectly(data: DataArray, offset: number, useBytes: boolean = false): void {
+            this._buffer.updateDirectly(data, offset, undefined, useBytes);
         }
 
         /** 

+ 7 - 7
src/PostProcess/babylon.depthOfFieldEffect.ts

@@ -145,17 +145,17 @@ module BABYLON {
          * @param camera The camera to dispose the effect on.
          */
         public disposeEffects(camera:Camera){
-            for(var effect in this._effects){
-                this._effects[effect].dispose(camera);
-            }            
+            for(var effectIndex = 0; effectIndex < this._effects.length; effectIndex++){
+                this._effects[effectIndex].dispose(camera);
+            }
         }
 
         /**
          * Internal
          */
         public _updateEffects(){
-            for(var effect in this._effects){
-                this._effects[effect].updateEffect();
+            for(var effectIndex = 0; effectIndex <  this._effects.length; effectIndex++){
+                this._effects[effectIndex].updateEffect();
             }
         }
 
@@ -164,8 +164,8 @@ module BABYLON {
          * @returns if all the contained post processes are ready.
          */
         public _isReady(){
-            for(var effect in this._effects){
-                if(!this._effects[effect].isReady()){
+            for(var effectIndex = 0; effectIndex < this._effects.length; effectIndex++){
+                if(!this._effects[effectIndex].isReady()){
                     return false;
                 }
             }

+ 3 - 2
src/Shaders/ShadersInclude/backgroundFragmentDeclaration.fx

@@ -1,6 +1,7 @@
     uniform vec4 vPrimaryColor;
-    uniform vec4 vSecondaryColor;
-    uniform vec4 vTertiaryColor;
+#ifdef USEHIGHLIGHTANDSHADOWCOLORS
+    uniform vec4 vPrimaryColorShadow;
+#endif
     uniform float shadowLevel;
     uniform float alpha;
 

+ 1 - 2
src/Shaders/ShadersInclude/backgroundUboDeclaration.fx

@@ -3,8 +3,7 @@ layout(std140, column_major) uniform;
 uniform Material
 {
 	uniform vec4 vPrimaryColor;
-	uniform vec4 vSecondaryColor;
-	uniform vec4 vTertiaryColor;
+	uniform vec4 vPrimaryColorShadow;
 	uniform vec2 vDiffuseInfos;
 	uniform vec2 vReflectionInfos;
 	uniform mat4 diffuseMatrix;

+ 7 - 3
src/Shaders/background.fragment.fx

@@ -229,9 +229,13 @@ float finalAlpha = alpha;
 #ifdef USERGBCOLOR
     vec3 finalColor = colorBase;
 #else
-    vec3 finalColor = colorBase.r * vPrimaryColor.rgb * vPrimaryColor.a;
-    finalColor += colorBase.g * vSecondaryColor.rgb * vSecondaryColor.a;
-    finalColor += colorBase.b * vTertiaryColor.rgb * vTertiaryColor.a;
+    #ifdef USEHIGHLIGHTANDSHADOWCOLORS
+        vec3 mainColor = mix(vPrimaryColorShadow.rgb, vPrimaryColor.rgb, colorBase);
+    #else
+        vec3 mainColor = vPrimaryColor.rgb;
+    #endif
+
+    vec3 finalColor = colorBase * mainColor;
 #endif
 
 // ___________________________ FRESNELS _______________________________________

+ 22 - 7
src/babylon.scene.ts

@@ -2746,11 +2746,6 @@
                     let originalValue = originalAnimation.originalValue;
                     let finalTarget = originalAnimation.target;   
                     
-                    // Sanity check
-                    if (!originalValue.scaleAndAddToRef) {
-                        continue;
-                    }
-
                     let matrixDecomposeMode = Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
 
                     let finalValue: any;
@@ -2762,13 +2757,21 @@
 
                         if (holder.totalWeight < 1.0) {
                             // We need to mix the original value in     
-                            finalValue = originalValue.scale(1.0 - holder.totalWeight)
+                            if (originalValue.scale) {
+                                finalValue = originalValue.scale(1.0 - holder.totalWeight);
+                            } else {
+                                finalValue = originalValue * (1.0 - holder.totalWeight);
+                            }
                         } else {
                             // We need to normalize the weights
                             normalizer = holder.totalWeight;
                             let scale = originalAnimation.weight / normalizer;
                             if (scale !== 1) {
-                                finalValue = originalAnimation.currentValue.scale(scale);
+                                if (originalAnimation.currentValue.scale) {
+                                    finalValue = originalAnimation.currentValue.scale(scale);
+                                } else {
+                                    finalValue = originalAnimation.currentValue * scale;
+                                }
                             } else {
                                 finalValue = originalAnimation.currentValue;
                             }
@@ -2779,6 +2782,18 @@
                         for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
                             var runtimeAnimation = holder.animations[animIndex];   
                             var scale = runtimeAnimation.weight / normalizer;
+                            if (runtimeAnimation.currentValue.scaleAndAddToRef) {
+                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                            } else {
+                                finalValue += runtimeAnimation.currentValue * scale;
+                            }
+
+                            startIndex = 1;
+                        }
+
+                        for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
+                            var runtimeAnimation = holder.animations[animIndex];   
+                            var scale = runtimeAnimation.weight / normalizer;
                             runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
                         }
                     }

二进制
tests/validation/ReferenceImages/gltf1CesiumMan.png


二进制
tests/validation/ReferenceImages/texture cache.png


+ 5 - 8
tests/validation/config.json

@@ -279,14 +279,6 @@
       "referenceImage": "gltfTextureSampler.png"
     },
     {
-      "title": "GLTF 1.0 Skin Animation Test",
-      "renderCount": 20,
-      "scriptToRun": "/Demos/GLTF1CesiumMan/index.js",
-      "functionToCall": "createScene",
-      "referenceImage": "gltf1CesiumMan.png",
-      "excludeFromAutomaticTesting": true
-    },
-    {
       "title": "GLTF Buggy with Draco Mesh Compression",
       "playgroundId": "#JNW207#1",
       "referenceImage": "gltfBuggyDraco.png"
@@ -385,6 +377,11 @@
       "referenceImage": "pbr.png"
     },
     {
+      "title": "Texture cache",
+      "playgroundId": "#20OAV9#133",
+      "referenceImage": "texture cache.png"
+    },
+    {
       "title": "MultiSample render targets",
       "renderCount": 20,
       "playgroundId": "#12MKMN#0",

+ 1 - 3
tests/validation/index.html

@@ -3,9 +3,7 @@
 <head>
 	<title>BabylonJS - Build validation page</title>
 	<link href="index.css" rel="stylesheet" />	
-    <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
-    <script src="https://preview.babylonjs.com/draco_decoder.wasm" type="text/x-draco-decoder-wasm-binary"></script>
-    <script src="https://preview.babylonjs.com/draco_wasm_wrapper.js" type="text/x-draco-decoder-wasm-wrapper"></script>
+    <script src="https://preview.babylonjs.com/draco_decoder.js"></script>
 	<script src="https://unpkg.com/earcut@2.1.1/dist/earcut.min.js"></script>
 	<script src="../../Tools/DevLoader/BabylonLoader.js"></script>
 </head>