소스 검색

Merge pull request #2804 from BabylonJS/master

Nightly
David Catuhe 8 년 전
부모
커밋
468c03d1b2
30개의 변경된 파일9199개의 추가작업 그리고 9031개의 파일을 삭제
  1. 36 15
      Playground/js/index.js
  2. 1360 1354
      dist/preview release/babylon.d.ts
  3. 43 43
      dist/preview release/babylon.js
  4. 53 15
      dist/preview release/babylon.max.js
  5. 1360 1354
      dist/preview release/babylon.module.d.ts
  6. 44 44
      dist/preview release/babylon.worker.js
  7. 2926 2920
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  8. 46 46
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  9. 53 15
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  10. 2926 2920
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts
  11. 3 3
      dist/preview release/gui/babylon.gui.min.js
  12. 263 263
      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. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  16. 2 2
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  17. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  18. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  19. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  20. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  21. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  22. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js
  23. 1 0
      dist/preview release/what's new.md
  24. 6 9
      sandbox/index.js
  25. 16 1
      src/Behaviors/Cameras/babylon.framingBehavior.ts
  26. 1 1
      src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.ts
  27. 1 1
      src/Cameras/babylon.arcRotateCamera.ts
  28. 16 5
      src/Gamepad/babylon.gamepad.ts
  29. 30 8
      src/Gamepad/babylon.xboxGamepad.ts
  30. 1 0
      src/Loading/babylon.loadingScreen.ts

+ 36 - 15
Playground/js/index.js

@@ -183,6 +183,9 @@
         }
 
         var createNewScript = function () {
+            // check if checked is on
+            let iCanClear = checkSafeMode("Are you sure you want to create a new playground?");
+            if (!iCanClear) return;
             location.hash = "";
             currentSnippetToken = null;
             currentSnippetTitle = null;
@@ -196,6 +199,9 @@
         }
 
         var clear = function () {
+            // check if checked is on
+            let iCanClear = checkSafeMode("Are you sure you want to clear the playground?");
+            if (!iCanClear) return;
             location.hash = "";
             currentSnippetToken = null;
             jsEditor.setValue('');
@@ -203,6 +209,21 @@
             jsEditor.focus();
         }
 
+        var checkSafeMode = function (message) {
+            var safeToggle = document.getElementById("safemodeToggle1600");
+            if (safeToggle.classList.contains('checked')) {
+                let confirm = window.confirm(message);
+                if (!confirm) {
+                    return false;
+                } else {
+                    document.getElementById("safemodeToggle1600").classList.toggle('checked');
+                    return true;
+                }
+            } else {
+                return true;
+            }
+        }
+
         var showError = function (errorMessage, errorEvent) {
             var errorContent =
                 '<div class="alert alert-error"><button type="button" class="close" data-dismiss="alert">&times;</button>';
@@ -287,14 +308,14 @@
                 var showDebugLayer = false;
                 var initialTabIndex = 0;
 
-                if(document.getElementsByClassName('insp-wrapper').length > 0){                  
-                    for(var i = 0; i < engine.scenes.length; i++){
-                        if(engine.scenes[i]._debugLayer){
+                if (document.getElementsByClassName('insp-wrapper').length > 0) {
+                    for (var i = 0; i < engine.scenes.length; i++) {
+                        if (engine.scenes[i]._debugLayer) {
                             //TODO: once inspector is updated on netlify, use getActiveTabIndex instead of the following loop
                             //initialTabIndex = engine.scenes[i]._debugLayer._inspector.getActiveTabIndex();
                             var tabs = engine.scenes[i]._debugLayer._inspector._tabbar._tabs;
-                            for(var j = 0; j < tabs.length; j++){
-                                if(tabs[j].isActive()){
+                            for (var j = 0; j < tabs.length; j++) {
+                                if (tabs[j].isActive()) {
                                     initialTabIndex = j;
                                     break;
                                 }
@@ -303,7 +324,7 @@
                         }
                     }
                     showInspector = true;
-                }else if(document.getElementById('DebugLayer')){
+                } else if (document.getElementById('DebugLayer')) {
                     showDebugLayer = true;
                 }
 
@@ -388,13 +409,13 @@
                     document.getElementById("statusBar").innerHTML = "";
                 });
 
-                if(scene){
-                    if(showInspector){
-                        scene.debugLayer.show({initialTab:initialTabIndex});
-                        scene.executeWhenReady(function(){
+                if (scene) {
+                    if (showInspector) {
+                        scene.debugLayer.show({ initialTab: initialTabIndex });
+                        scene.executeWhenReady(function () {
                             scene.debugLayer._inspector.refresh();
                         })
-                    }else if(showDebugLayer){
+                    } else if (showDebugLayer) {
                         scene.debugLayer.show();
                     }
                 }
@@ -594,7 +615,7 @@
 
         // Fullscreen
         document.getElementById("renderCanvas").addEventListener("webkitfullscreenchange", function () {
-            if(document.webkitIsFullScreen) goFullPage();
+            if (document.webkitIsFullScreen) goFullPage();
             else exitFullPage();
         }, false);
 
@@ -617,11 +638,11 @@
         var editorGoFullscreen = function () {
             var editorDiv = document.getElementById("jsEditor");
             if (editorDiv.requestFullscreen) {
-            editorDiv.requestFullscreen();
+                editorDiv.requestFullscreen();
             } else if (editorDiv.mozRequestFullScreen) {
-            editorDiv.mozRequestFullScreen();
+                editorDiv.mozRequestFullScreen();
             } else if (editorDiv.webkitRequestFullscreen) {
-            editorDiv.webkitRequestFullscreen();
+                editorDiv.webkitRequestFullscreen();
             }
 
         }

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1360 - 1354
dist/preview release/babylon.d.ts


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 43 - 43
dist/preview release/babylon.js


+ 53 - 15
dist/preview release/babylon.max.js

@@ -35463,7 +35463,7 @@ var BABYLON;
                         //Nothing to do with the error. Execution will continue.
                     }
                     // Manage panning with pan button click
-                    _this._isPanClick = evt.button === _this.camera._panningMouseButton;
+                    _this._isPanClick = evt.button === _this.camera._panningMouseButton && evt.pointerType !== "mouse";
                     // manage pointers
                     cacheSoloPointer = { x: evt.clientX, y: evt.clientY, pointerId: evt.pointerId, type: evt.pointerType };
                     if (pointA === undefined) {
@@ -36034,7 +36034,7 @@ var BABYLON;
             this.alpha = this._storedAlpha;
             this.beta = this._storedBeta;
             this.radius = this._storedRadius;
-            this.setTarget(this._storedTarget);
+            this.setTarget(this._storedTarget.clone());
             this.inertialAlphaOffset = 0;
             this.inertialBetaOffset = 0;
             this.inertialRadiusOffset = 0;
@@ -48662,6 +48662,7 @@ var BABYLON;
             this._loadingDiv.id = "babylonjsLoadingDiv";
             this._loadingDiv.style.opacity = "0";
             this._loadingDiv.style.transition = "opacity 1.5s ease";
+            this._loadingDiv.style.pointerEvents = "none";
             // Loading text
             this._loadingTextDiv = document.createElement("div");
             this._loadingTextDiv.style.position = "absolute";
@@ -51933,6 +51934,8 @@ var BABYLON;
         __extends(GenericPad, _super);
         function GenericPad(id, index, browserGamepad) {
             var _this = _super.call(this, id, index, browserGamepad) || this;
+            _this.onButtonDownObservable = new BABYLON.Observable();
+            _this.onButtonUpObservable = new BABYLON.Observable();
             _this.type = Gamepad.GENERIC;
             _this._buttons = new Array(browserGamepad.buttons.length);
             return _this;
@@ -51945,11 +51948,17 @@ var BABYLON;
         };
         GenericPad.prototype._setButtonValue = function (newValue, currentValue, buttonIndex) {
             if (newValue !== currentValue) {
-                if (this._onbuttondown && newValue === 1) {
-                    this._onbuttondown(buttonIndex);
+                if (newValue === 1) {
+                    if (this._onbuttondown) {
+                        this._onbuttondown(buttonIndex);
+                    }
+                    this.onButtonDownObservable.notifyObservers(buttonIndex);
                 }
-                if (this._onbuttonup && newValue === 0) {
-                    this._onbuttonup(buttonIndex);
+                if (newValue === 0) {
+                    if (this._onbuttonup) {
+                        this._onbuttonup(buttonIndex);
+                    }
+                    this.onButtonUpObservable.notifyObservers(buttonIndex);
                 }
             }
             return newValue;
@@ -51997,6 +52006,10 @@ var BABYLON;
             var _this = _super.call(this, id, index, gamepad, 0, 1, (xboxOne ? 3 : 2), (xboxOne ? 4 : 3)) || this;
             _this._leftTrigger = 0;
             _this._rightTrigger = 0;
+            _this.onButtonDownObservable = new BABYLON.Observable();
+            _this.onButtonUpObservable = new BABYLON.Observable();
+            _this.onPadDownObservable = new BABYLON.Observable();
+            _this.onPadUpObservable = new BABYLON.Observable();
             _this._buttonA = 0;
             _this._buttonB = 0;
             _this._buttonX = 0;
@@ -52062,22 +52075,34 @@ var BABYLON;
         };
         Xbox360Pad.prototype._setButtonValue = function (newValue, currentValue, buttonType) {
             if (newValue !== currentValue) {
-                if (this._onbuttondown && newValue === 1) {
-                    this._onbuttondown(buttonType);
+                if (newValue === 1) {
+                    if (this._onbuttondown) {
+                        this._onbuttondown(buttonType);
+                    }
+                    this.onButtonDownObservable.notifyObservers(buttonType);
                 }
-                if (this._onbuttonup && newValue === 0) {
-                    this._onbuttonup(buttonType);
+                if (newValue === 0) {
+                    if (this._onbuttonup) {
+                        this._onbuttonup(buttonType);
+                    }
+                    this.onButtonUpObservable.notifyObservers(buttonType);
                 }
             }
             return newValue;
         };
         Xbox360Pad.prototype._setDPadValue = function (newValue, currentValue, buttonType) {
             if (newValue !== currentValue) {
-                if (this._ondpaddown && newValue === 1) {
-                    this._ondpaddown(buttonType);
+                if (newValue === 1) {
+                    if (this._ondpaddown) {
+                        this._ondpaddown(buttonType);
+                    }
+                    this.onPadDownObservable.notifyObservers(buttonType);
                 }
-                if (this._ondpadup && newValue === 0) {
-                    this._ondpadup(buttonType);
+                if (newValue === 0) {
+                    if (this._ondpadup) {
+                        this._ondpadup(buttonType);
+                    }
+                    this.onPadUpObservable.notifyObservers(buttonType);
                 }
             }
             return newValue;
@@ -72128,6 +72153,7 @@ var BABYLON;
          * @param onAnimationEnd Callback triggered at the end of the framing animation
          */
         FramingBehavior.prototype.zoomOnBoundingInfo = function (minimumWorld, maximumWorld, focusOnOriginXZ, onAnimationEnd) {
+            var _this = this;
             if (focusOnOriginXZ === void 0) { focusOnOriginXZ = false; }
             if (onAnimationEnd === void 0) { onAnimationEnd = null; }
             var zoomTarget;
@@ -72163,11 +72189,20 @@ var BABYLON;
                     this._attachedCamera.lowerRadiusLimit = this._attachedCamera.minZ;
                 }
             }
+            // Set sensibilities
+            var extend = maximumWorld.subtract(minimumWorld).length();
+            this._attachedCamera.panningSensibility = 5000 / extend;
+            this._attachedCamera.wheelPrecision = 100 / radius;
             // transition to new radius
             if (!this._radiusTransition) {
                 this._radiusTransition = BABYLON.Animation.CreateAnimation("radius", BABYLON.Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
             }
-            this._animatables.push(BABYLON.Animation.TransitionTo("radius", radius, this._attachedCamera, this._attachedCamera.getScene(), 60, this._radiusTransition, this._framingTime, onAnimationEnd));
+            this._animatables.push(BABYLON.Animation.TransitionTo("radius", radius, this._attachedCamera, this._attachedCamera.getScene(), 60, this._radiusTransition, this._framingTime, function () {
+                if (onAnimationEnd) {
+                    onAnimationEnd();
+                }
+                _this._attachedCamera.storeState();
+            }));
         };
         /**
          * Calculates the lowest radius for the camera based on the bounding box of the mesh.
@@ -72205,6 +72240,9 @@ var BABYLON;
          */
         FramingBehavior.prototype._maintainCameraAboveGround = function () {
             var _this = this;
+            if (this._elevationReturnTime < 0) {
+                return;
+            }
             var timeSinceInteraction = BABYLON.Tools.Now - this._lastInteractionTime;
             var defaultBeta = Math.PI * 0.5 - this._defaultElevation;
             var limitBeta = Math.PI * 0.5;

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1360 - 1354
dist/preview release/babylon.module.d.ts


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 44 - 44
dist/preview release/babylon.worker.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 2926 - 2920
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 46 - 46
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


+ 53 - 15
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js

@@ -35463,7 +35463,7 @@ var BABYLON;
                         //Nothing to do with the error. Execution will continue.
                     }
                     // Manage panning with pan button click
-                    _this._isPanClick = evt.button === _this.camera._panningMouseButton;
+                    _this._isPanClick = evt.button === _this.camera._panningMouseButton && evt.pointerType !== "mouse";
                     // manage pointers
                     cacheSoloPointer = { x: evt.clientX, y: evt.clientY, pointerId: evt.pointerId, type: evt.pointerType };
                     if (pointA === undefined) {
@@ -36034,7 +36034,7 @@ var BABYLON;
             this.alpha = this._storedAlpha;
             this.beta = this._storedBeta;
             this.radius = this._storedRadius;
-            this.setTarget(this._storedTarget);
+            this.setTarget(this._storedTarget.clone());
             this.inertialAlphaOffset = 0;
             this.inertialBetaOffset = 0;
             this.inertialRadiusOffset = 0;
@@ -48662,6 +48662,7 @@ var BABYLON;
             this._loadingDiv.id = "babylonjsLoadingDiv";
             this._loadingDiv.style.opacity = "0";
             this._loadingDiv.style.transition = "opacity 1.5s ease";
+            this._loadingDiv.style.pointerEvents = "none";
             // Loading text
             this._loadingTextDiv = document.createElement("div");
             this._loadingTextDiv.style.position = "absolute";
@@ -51933,6 +51934,8 @@ var BABYLON;
         __extends(GenericPad, _super);
         function GenericPad(id, index, browserGamepad) {
             var _this = _super.call(this, id, index, browserGamepad) || this;
+            _this.onButtonDownObservable = new BABYLON.Observable();
+            _this.onButtonUpObservable = new BABYLON.Observable();
             _this.type = Gamepad.GENERIC;
             _this._buttons = new Array(browserGamepad.buttons.length);
             return _this;
@@ -51945,11 +51948,17 @@ var BABYLON;
         };
         GenericPad.prototype._setButtonValue = function (newValue, currentValue, buttonIndex) {
             if (newValue !== currentValue) {
-                if (this._onbuttondown && newValue === 1) {
-                    this._onbuttondown(buttonIndex);
+                if (newValue === 1) {
+                    if (this._onbuttondown) {
+                        this._onbuttondown(buttonIndex);
+                    }
+                    this.onButtonDownObservable.notifyObservers(buttonIndex);
                 }
-                if (this._onbuttonup && newValue === 0) {
-                    this._onbuttonup(buttonIndex);
+                if (newValue === 0) {
+                    if (this._onbuttonup) {
+                        this._onbuttonup(buttonIndex);
+                    }
+                    this.onButtonUpObservable.notifyObservers(buttonIndex);
                 }
             }
             return newValue;
@@ -51997,6 +52006,10 @@ var BABYLON;
             var _this = _super.call(this, id, index, gamepad, 0, 1, (xboxOne ? 3 : 2), (xboxOne ? 4 : 3)) || this;
             _this._leftTrigger = 0;
             _this._rightTrigger = 0;
+            _this.onButtonDownObservable = new BABYLON.Observable();
+            _this.onButtonUpObservable = new BABYLON.Observable();
+            _this.onPadDownObservable = new BABYLON.Observable();
+            _this.onPadUpObservable = new BABYLON.Observable();
             _this._buttonA = 0;
             _this._buttonB = 0;
             _this._buttonX = 0;
@@ -52062,22 +52075,34 @@ var BABYLON;
         };
         Xbox360Pad.prototype._setButtonValue = function (newValue, currentValue, buttonType) {
             if (newValue !== currentValue) {
-                if (this._onbuttondown && newValue === 1) {
-                    this._onbuttondown(buttonType);
+                if (newValue === 1) {
+                    if (this._onbuttondown) {
+                        this._onbuttondown(buttonType);
+                    }
+                    this.onButtonDownObservable.notifyObservers(buttonType);
                 }
-                if (this._onbuttonup && newValue === 0) {
-                    this._onbuttonup(buttonType);
+                if (newValue === 0) {
+                    if (this._onbuttonup) {
+                        this._onbuttonup(buttonType);
+                    }
+                    this.onButtonUpObservable.notifyObservers(buttonType);
                 }
             }
             return newValue;
         };
         Xbox360Pad.prototype._setDPadValue = function (newValue, currentValue, buttonType) {
             if (newValue !== currentValue) {
-                if (this._ondpaddown && newValue === 1) {
-                    this._ondpaddown(buttonType);
+                if (newValue === 1) {
+                    if (this._ondpaddown) {
+                        this._ondpaddown(buttonType);
+                    }
+                    this.onPadDownObservable.notifyObservers(buttonType);
                 }
-                if (this._ondpadup && newValue === 0) {
-                    this._ondpadup(buttonType);
+                if (newValue === 0) {
+                    if (this._ondpadup) {
+                        this._ondpadup(buttonType);
+                    }
+                    this.onPadUpObservable.notifyObservers(buttonType);
                 }
             }
             return newValue;
@@ -72128,6 +72153,7 @@ var BABYLON;
          * @param onAnimationEnd Callback triggered at the end of the framing animation
          */
         FramingBehavior.prototype.zoomOnBoundingInfo = function (minimumWorld, maximumWorld, focusOnOriginXZ, onAnimationEnd) {
+            var _this = this;
             if (focusOnOriginXZ === void 0) { focusOnOriginXZ = false; }
             if (onAnimationEnd === void 0) { onAnimationEnd = null; }
             var zoomTarget;
@@ -72163,11 +72189,20 @@ var BABYLON;
                     this._attachedCamera.lowerRadiusLimit = this._attachedCamera.minZ;
                 }
             }
+            // Set sensibilities
+            var extend = maximumWorld.subtract(minimumWorld).length();
+            this._attachedCamera.panningSensibility = 5000 / extend;
+            this._attachedCamera.wheelPrecision = 100 / radius;
             // transition to new radius
             if (!this._radiusTransition) {
                 this._radiusTransition = BABYLON.Animation.CreateAnimation("radius", BABYLON.Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
             }
-            this._animatables.push(BABYLON.Animation.TransitionTo("radius", radius, this._attachedCamera, this._attachedCamera.getScene(), 60, this._radiusTransition, this._framingTime, onAnimationEnd));
+            this._animatables.push(BABYLON.Animation.TransitionTo("radius", radius, this._attachedCamera, this._attachedCamera.getScene(), 60, this._radiusTransition, this._framingTime, function () {
+                if (onAnimationEnd) {
+                    onAnimationEnd();
+                }
+                _this._attachedCamera.storeState();
+            }));
         };
         /**
          * Calculates the lowest radius for the camera based on the bounding box of the mesh.
@@ -72205,6 +72240,9 @@ var BABYLON;
          */
         FramingBehavior.prototype._maintainCameraAboveGround = function () {
             var _this = this;
+            if (this._elevationReturnTime < 0) {
+                return;
+            }
             var timeSinceInteraction = BABYLON.Tools.Now - this._lastInteractionTime;
             var defaultBeta = Math.PI * 0.5 - this._defaultElevation;
             var limitBeta = Math.PI * 0.5;

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 2926 - 2920
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 3 - 3
dist/preview release/gui/babylon.gui.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 263 - 263
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


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


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

@@ -17,6 +17,7 @@
 - Added support for Particle animation in ParticleSystem ([Ibraheem Osama](https://github.com/IbraheemOsama))
 
 ## Updates
+- New observables for gamepads: `onButtonDownObservable`, `onButtonUpObservable`, `onPadDownObservable`, `onPadUpObservable` ([deltakosh](https://github.com/deltakosh))
 - New `camera.storeState()` and `camera.restoreState()` functions to store / restore cameras position / rotation / fov. (Doc here)[http://doc.babylonjs.com/tutorials/cameras#state] ([deltakosh](https://github.com/deltakosh))
 - POW2 textures rescale is now done by shaders (It was previously done using canvas) ([deltakosh](https://github.com/deltakosh))
 - Added `SceneLoader.CleanBoneMatrixWeights` to force the loader to normalize matrix weights when loading bones (off by default) ([deltakosh](https://github.com/deltakosh)) 

+ 6 - 9
sandbox/index.js

@@ -18,6 +18,10 @@
     var enableDebugLayer = false;
     var currentPluginName;
 
+    canvas.addEventListener("contextmenu", function(evt) {
+        evt.preventDefault();
+    }, false);
+
     currentHelpCounter = localStorage.getItem("helpcounter");
 
     BABYLON.Engine.ShadersRepository = "/src/Shaders/";
@@ -79,15 +83,8 @@
             bouncingBehavior.autoTransitionRange = true;        
 
             if (currentScene.meshes.length) {
-                // Let's zoom on the first object with geometry
-                for (var index = 0; index < currentScene.meshes.length; index++) {
-                    var mesh = currentScene.meshes[index];
-
-                    if (mesh.getTotalVertices()) {
-                        currentScene.activeCamera.setTarget(mesh);
-                        break;
-                    }
-                }
+                var worldExtends = currentScene.getWorldExtends();
+                framingBehavior.zoomOnBoundingInfo(worldExtends.min, worldExtends.max);
             }
         }
 

+ 16 - 1
src/Behaviors/Cameras/babylon.framingBehavior.ts

@@ -261,13 +261,24 @@ module BABYLON {
 				}
 			}
 
+			// Set sensibilities
+			let extend = maximumWorld.subtract(minimumWorld).length();
+			this._attachedCamera.panningSensibility = 5000 / extend;
+			this._attachedCamera.wheelPrecision = 100 / radius;
+
 			// transition to new radius
 			if (!this._radiusTransition) {
 				this._radiusTransition = Animation.CreateAnimation("radius", Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
 			}
 
 			this._animatables.push(Animation.TransitionTo("radius", radius, this._attachedCamera, this._attachedCamera.getScene(), 
-				60, this._radiusTransition, this._framingTime, onAnimationEnd));
+				60, this._radiusTransition, this._framingTime, () => {
+					if (onAnimationEnd) {
+						onAnimationEnd();
+					}
+
+					this._attachedCamera.storeState();
+				}));
 		}
 		
 		/**
@@ -311,6 +322,10 @@ module BABYLON {
 		 * is automatically returned to its default position (expected to be above ground plane). 
 		 */
 		private _maintainCameraAboveGround(): void {
+			if (this._elevationReturnTime < 0) {
+				return;
+			}
+
 			let timeSinceInteraction = Tools.Now - this._lastInteractionTime;
 			let defaultBeta = Math.PI * 0.5 - this._defaultElevation;
 			let limitBeta = Math.PI * 0.5;

+ 1 - 1
src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.ts

@@ -61,7 +61,7 @@ module BABYLON {
                     }
 
                     // Manage panning with pan button click
-                    this._isPanClick = evt.button === this.camera._panningMouseButton;
+                    this._isPanClick = evt.button === this.camera._panningMouseButton && evt.pointerType !== "mouse";
 
                     // manage pointers
                     cacheSoloPointer = { x: evt.clientX, y: evt.clientY, pointerId: evt.pointerId, type: evt.pointerType };

+ 1 - 1
src/Cameras/babylon.arcRotateCamera.ts

@@ -385,7 +385,7 @@ module BABYLON {
             this.alpha = this._storedAlpha;
             this.beta = this._storedBeta;
             this.radius = this._storedRadius;
-            this.setTarget(this._storedTarget);
+            this.setTarget(this._storedTarget.clone());
 
             this.inertialAlphaOffset = 0;
             this.inertialBetaOffset = 0;

+ 16 - 5
src/Gamepad/babylon.gamepad.ts

@@ -94,7 +94,10 @@
     export class GenericPad extends Gamepad {
         private _buttons: Array<number>;
         private _onbuttondown: (buttonPressed: number) => void;
-        private _onbuttonup: (buttonReleased: number) => void;
+        private _onbuttonup: (buttonReleased: number) => void;        
+
+        public onButtonDownObservable = new Observable<number>();
+        public onButtonUpObservable = new Observable<number>();
 
         public onbuttondown(callback: (buttonPressed: number) => void) {
             this._onbuttondown = callback;
@@ -111,11 +114,19 @@
 
         private _setButtonValue(newValue: number, currentValue: number, buttonIndex: number): number {
             if (newValue !== currentValue) {
-                if (this._onbuttondown && newValue === 1) {
-                    this._onbuttondown(buttonIndex);
+                if (newValue === 1) {
+                    if (this._onbuttondown) {
+                        this._onbuttondown(buttonIndex);
+                    }
+
+                    this.onButtonDownObservable.notifyObservers(buttonIndex);
                 }
-                if (this._onbuttonup && newValue === 0) {
-                    this._onbuttonup(buttonIndex);
+                if (newValue === 0) {
+                    if (this._onbuttonup) {
+                        this._onbuttonup(buttonIndex);
+                    }
+
+                    this.onButtonUpObservable.notifyObservers(buttonIndex);
                 }
             }
             return newValue;

+ 30 - 8
src/Gamepad/babylon.xboxGamepad.ts

@@ -32,6 +32,11 @@
         private _ondpaddown: (dPadPressed: Xbox360Dpad) => void;
         private _ondpadup: (dPadReleased: Xbox360Dpad) => void;
 
+        public onButtonDownObservable = new Observable<Xbox360Button>();
+        public onButtonUpObservable = new Observable<Xbox360Button>();        
+        public onPadDownObservable = new Observable<Xbox360Dpad>();
+        public onPadUpObservable = new Observable<Xbox360Dpad>();        
+
         private _buttonA: number = 0;
         private _buttonB: number = 0;
         private _buttonX: number = 0;
@@ -99,11 +104,20 @@
 
         private _setButtonValue(newValue: number, currentValue: number, buttonType: Xbox360Button): number {
             if (newValue !== currentValue) {
-                if (this._onbuttondown && newValue === 1) {
-                    this._onbuttondown(buttonType);
+                if (newValue === 1) {
+                    if (this._onbuttondown) {
+                        this._onbuttondown(buttonType);
+                    }
+
+                    this.onButtonDownObservable.notifyObservers(buttonType);
                 }
-                if (this._onbuttonup && newValue === 0) {
-                    this._onbuttonup(buttonType);
+                if (newValue === 0) {
+
+                    if (this._onbuttonup) {
+                        this._onbuttonup(buttonType);
+                    }
+                    
+                    this.onButtonUpObservable.notifyObservers(buttonType);
                 }
             }
             return newValue;
@@ -111,11 +125,19 @@
 
         private _setDPadValue(newValue: number, currentValue: number, buttonType: Xbox360Dpad): number {
             if (newValue !== currentValue) {
-                if (this._ondpaddown && newValue === 1) {
-                    this._ondpaddown(buttonType);
+                if (newValue === 1) {
+                    if (this._ondpaddown) {
+                        this._ondpaddown(buttonType);
+                    }
+                    
+                    this.onPadDownObservable.notifyObservers(buttonType);
                 }
-                if (this._ondpadup && newValue === 0) {
-                    this._ondpadup(buttonType);
+                if (newValue === 0) {
+                    if (this._ondpadup) {
+                        this._ondpadup(buttonType);
+                    }
+
+                    this.onPadUpObservable.notifyObservers(buttonType);
                 }
             }
             return newValue;

+ 1 - 0
src/Loading/babylon.loadingScreen.ts

@@ -29,6 +29,7 @@ module BABYLON {
             this._loadingDiv.id = "babylonjsLoadingDiv";
             this._loadingDiv.style.opacity = "0";
             this._loadingDiv.style.transition = "opacity 1.5s ease";
+            this._loadingDiv.style.pointerEvents = "none";
 
             // Loading text
             this._loadingTextDiv = document.createElement("div");