sebavan пре 6 година
родитељ
комит
9889be4bed
46 измењених фајлова са 5543 додато и 2298 уклоњено
  1. 2 2
      .github/ISSUE_TEMPLATE.md
  2. 3766 839
      Playground/babylon.d.txt
  3. 2 2
      Playground/debug.html
  4. 2 2
      Playground/index-local.html
  5. 2 2
      Playground/index.html
  6. 2 2
      Playground/indexStable.html
  7. BIN
      Playground/textures/panel_blue2x.9.direct.png
  8. BIN
      Playground/textures/panel_blue2x.9.inv.png
  9. BIN
      Playground/textures/panel_blue2x.9.png
  10. 1 1
      Playground/ts.html
  11. 1 1
      contributing.md
  12. 1212 1205
      dist/preview release/babylon.d.ts
  13. 1 1
      dist/preview release/babylon.js
  14. 39 2
      dist/preview release/babylon.max.js
  15. 39 2
      dist/preview release/babylon.no-module.max.js
  16. 1 1
      dist/preview release/babylon.worker.js
  17. 39 2
      dist/preview release/es6.js
  18. 1 1
      dist/preview release/glTF2Interface/package.json
  19. 26 0
      dist/preview release/gui/babylon.gui.d.ts
  20. 1 1
      dist/preview release/gui/babylon.gui.js
  21. 1 1
      dist/preview release/gui/babylon.gui.min.js
  22. 1 1
      dist/preview release/gui/babylon.gui.min.js.map
  23. 52 0
      dist/preview release/gui/babylon.gui.module.d.ts
  24. 2 2
      dist/preview release/gui/package.json
  25. 7 7
      dist/preview release/inspector/babylon.inspector.bundle.js
  26. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js.map
  27. 5 5
      dist/preview release/inspector/package.json
  28. 3 3
      dist/preview release/loaders/package.json
  29. 2 2
      dist/preview release/materialsLibrary/package.json
  30. 2 2
      dist/preview release/postProcessesLibrary/package.json
  31. 2 2
      dist/preview release/proceduralTexturesLibrary/package.json
  32. 3 3
      dist/preview release/serializers/package.json
  33. 29 77
      dist/preview release/viewer/babylon.viewer.d.ts
  34. 1 1
      dist/preview release/viewer/babylon.viewer.js
  35. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  36. 31 107
      dist/preview release/viewer/babylon.viewer.module.d.ts
  37. 3 0
      dist/preview release/what's new.md
  38. 206 0
      gui/src/2D/controls/image.ts
  39. 36 11
      gui/src/2D/controls/inputText.ts
  40. 2 1
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/imagePropertyGridComponent.tsx
  41. 1 1
      package.json
  42. 1 1
      readme.md
  43. 1 1
      src/Collisions/pickingInfo.ts
  44. 1 1
      src/Engines/engine.ts
  45. 11 0
      src/Materials/PBR/pbrBaseMaterial.ts
  46. 1 1
      src/Meshes/subMesh.ts

+ 2 - 2
.github/ISSUE_TEMPLATE.md

@@ -1,5 +1,5 @@
 Before creating an issue, please make sure to provide the following template (based on why you create the issue):
-(Please do not use Github issues for questions - We have a really active forum to help answering questions (http://www.html5gamedevs.com/forum/16-babylonjs/))
+(Please do not use Github issues for questions - We have a really active forum to help answering questions (https://forum.babylonjs.com/))
 
 # Bugs
 
@@ -9,7 +9,7 @@ Before creating an issue, please make sure to provide the following template (ba
 
 # Feature request
 
-- Link to [forum](http://www.html5gamedevs.com/forum/16-babylonjs/) discussion about the feature:
+- Link to [forum](https://forum.babylonjs.com/) discussion about the feature:
 - Feature description
 - Additional links that could help implementing the feature:
 

Разлика између датотеке није приказан због своје велике величине
+ 3766 - 839
Playground/babylon.d.txt


+ 2 - 2
Playground/debug.html

@@ -451,7 +451,7 @@
                     <a target='_new' href="https://www.netlify.com/">Deployed by Netlify</a>
                 </div>
                 <div class='link'>
-                    <a target='_new' href="http://www.html5gamedevs.com/forum/16-babylonjs/">Forum</a>
+                    <a target='_new' href="https://forum.babylonjs.com/">Forum</a>
                 </div>
                 <div class='link'>
                     <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>
@@ -504,4 +504,4 @@
         </script>
     </body>
 
-</html>
+</html>

+ 2 - 2
Playground/index-local.html

@@ -391,7 +391,7 @@
                 <a target='_new' href="https://www.netlify.com/">Deployed by Netlify</a>
             </div>
             <div class='link'>
-                <a target='_new' href="http://www.html5gamedevs.com/forum/16-babylonjs/">Forum</a>
+                <a target='_new' href="https://forum.babylonjs.com/">Forum</a>
             </div>
             <div class='link'>
                 <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>
@@ -454,4 +454,4 @@
     </script>
 </body>
 
-</html>
+</html>

+ 2 - 2
Playground/index.html

@@ -425,7 +425,7 @@
                     <a target='_new' href="https://www.netlify.com/">Deployed by Netlify</a>
                 </div>
                 <div class='link'>
-                    <a target='_new' href="http://www.html5gamedevs.com/forum/16-babylonjs/">Forum</a>
+                    <a target='_new' href="https://forum.babylonjs.com/">Forum</a>
                 </div>
                 <div class='link'>
                     <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>
@@ -487,4 +487,4 @@
         </script>
     </body>
 
-</html>
+</html>

+ 2 - 2
Playground/indexStable.html

@@ -416,7 +416,7 @@
                 <a target='_new' href="https://www.netlify.com/">Deployed by Netlify</a>
             </div>
             <div class='link'>
-                <a target='_new' href="http://www.html5gamedevs.com/forum/16-babylonjs/">Forum</a>
+                <a target='_new' href="https://forum.babylonjs.com/">Forum</a>
             </div>
             <div class='link'>
                 <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>
@@ -473,4 +473,4 @@
     </script>
 </body>
 
-</html>
+</html>

BIN
Playground/textures/panel_blue2x.9.direct.png


BIN
Playground/textures/panel_blue2x.9.inv.png


BIN
Playground/textures/panel_blue2x.9.png


+ 1 - 1
Playground/ts.html

@@ -418,7 +418,7 @@
                     <a target='_new' href="https://www.netlify.com/">Deployed by Netlify</a>
                 </div>
                 <div class='link'>
-                    <a target='_new' href="http://www.html5gamedevs.com/forum/16-babylonjs/">Forum</a>
+                    <a target='_new' href="https://forum.babylonjs.com/">Forum</a>
                 </div>
                 <div class='link'>
                     <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>

+ 1 - 1
contributing.md

@@ -26,7 +26,7 @@ You can always add to an API, you cannot ever remove anything from one. If the d
 
 ## Forum and Github issues
 
-Since the very beginning, Babylon.js relies on a great forum and a tremendous community: http://www.html5gamedevs.com/forum/16-babylonjs/.
+Since the very beginning, Babylon.js relies on a great forum and a tremendous community: https://forum.babylonjs.com/.
 Please use the forum for **ANY questions you may have**.
 
 Please use the Github issues (after discussing them on the forum) **only** for:

Разлика између датотеке није приказан због своје велике величине
+ 1212 - 1205
dist/preview release/babylon.d.ts


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/babylon.js


+ 39 - 2
dist/preview release/babylon.max.js

@@ -12974,7 +12974,7 @@ var BABYLON;
              * Returns the current version of the framework
              */
             get: function () {
-                return "4.0.0-alpha.10";
+                return "4.0.0-alpha.11";
             },
             enumerable: true,
             configurable: true
@@ -36691,6 +36691,7 @@ var BABYLON;
                 }
                 if (fastCheck || !intersectInfo || length < intersectInfo.distance) {
                     intersectInfo = new BABYLON.IntersectionInfo(null, null, length);
+                    intersectInfo.faceId = index / 2;
                     if (fastCheck) {
                         break;
                     }
@@ -59344,7 +59345,7 @@ var BABYLON;
             this.bu = 0;
             /** (See getTextureCoordinates) The barycentric V coordinate that is used when calulating the texture coordinates of the collision.*/
             this.bv = 0;
-            /** The id of the face on the mesh that was picked  */
+            /** The index of the face on the mesh that was picked, or the index of the Line if the picked Mesh is a LinesMesh */
             this.faceId = -1;
             /** Id of the the submesh that was picked */
             this.subMeshId = 0;
@@ -105304,6 +105305,9 @@ var BABYLON;
              */
             _this.scalePivot = null;
             _this._existingMeshScale = new BABYLON.Vector3();
+            // Dragging
+            _this._dragMesh = null;
+            _this.pointerDragBehavior = new BABYLON.PointerDragBehavior();
             // Do not update the gizmo's scale so it has a fixed size to the object its attached to
             _this._updateScale = false;
             _this._anchorMesh = new BABYLON.AbstractMesh("anchor", gizmoLayer.utilityLayerScene);
@@ -105394,6 +105398,7 @@ var BABYLON;
                         _this.updateBoundingBox();
                         BoundingBoxGizmo._RestorePivotPoint(_this.attachedMesh);
                     }
+                    _this._updateDummy();
                 });
                 // Selection/deselection
                 _dragBehavior.onDragStartObservable.add(function () {
@@ -105403,6 +105408,7 @@ var BABYLON;
                 _dragBehavior.onDragEndObservable.add(function () {
                     _this.onRotationSphereDragEndObservable.notifyObservers({});
                     _this._selectNode(null);
+                    _this._updateDummy();
                 });
                 this_1._rotateSpheresParent.addChild(sphere);
             };
@@ -105455,6 +105461,7 @@ var BABYLON;
                                 _this._anchorMesh.removeChild(_this.attachedMesh);
                                 BoundingBoxGizmo._RestorePivotPoint(_this.attachedMesh);
                             }
+                            _this._updateDummy();
                         });
                         // Selection/deselection
                         _dragBehavior.onDragStartObservable.add(function () {
@@ -105464,6 +105471,7 @@ var BABYLON;
                         _dragBehavior.onDragEndObservable.add(function () {
                             _this.onScaleBoxDragEndObservable.notifyObservers({});
                             _this._selectNode(null);
+                            _this._updateDummy();
                         });
                         this_2._scaleBoxesParent.addChild(box);
                     };
@@ -105502,6 +105510,11 @@ var BABYLON;
                     _this._updateRotationSpheres();
                     _this._updateScaleBoxes();
                 }
+                // If dragg mesh is enabled and dragging, update the attached mesh pose to match the drag mesh
+                if (_this._dragMesh && _this.attachedMesh && _this.pointerDragBehavior.dragging) {
+                    _this._lineBoundingBox.position.rotateByQuaternionToRef(_this._rootMesh.rotationQuaternion, _this._tmpVector);
+                    _this.attachedMesh.setAbsolutePosition(_this._dragMesh.position.add(_this._tmpVector.scale(-1)));
+                }
             });
             _this.updateBoundingBox();
             return _this;
@@ -105534,6 +105547,7 @@ var BABYLON;
             this._PivotCached--;
         };
         BoundingBoxGizmo.prototype._attachedMeshChanged = function (value) {
+            var _this = this;
             if (value) {
                 // Reset anchor mesh to match attached mesh's scale
                 // This is needed to avoid invalid box/sphere position on first drag
@@ -105542,6 +105556,9 @@ var BABYLON;
                 this._anchorMesh.removeChild(value);
                 BoundingBoxGizmo._RestorePivotPoint(value);
                 this.updateBoundingBox();
+                this.gizmoLayer.utilityLayerScene.onAfterRenderObservable.addOnce(function () {
+                    _this._updateDummy();
+                });
             }
         };
         BoundingBoxGizmo.prototype._selectNode = function (selectedMesh) {
@@ -105663,6 +105680,23 @@ var BABYLON;
                 }
             });
         };
+        BoundingBoxGizmo.prototype._updateDummy = function () {
+            if (this._dragMesh) {
+                this._dragMesh.position.copyFrom(this._lineBoundingBox.getAbsolutePosition());
+                this._dragMesh.scaling.copyFrom(this._lineBoundingBox.scaling);
+                this._dragMesh.rotationQuaternion.copyFrom(this._rootMesh.rotationQuaternion);
+            }
+        };
+        /**
+         * Enables a pointer drag behavior on the bounding box of the gizmo
+         */
+        BoundingBoxGizmo.prototype.enableDragBehavior = function () {
+            this._dragMesh = BABYLON.Mesh.CreateBox("dummy", 1, this.gizmoLayer.utilityLayerScene);
+            this._dragMesh.visibility = 0;
+            this._dragMesh.rotationQuaternion = new BABYLON.Quaternion();
+            this.pointerDragBehavior.useObjectOrienationForDragging = false;
+            this._dragMesh.addBehavior(this.pointerDragBehavior);
+        };
         /**
          * Disposes of the gizmo
          */
@@ -105672,6 +105706,9 @@ var BABYLON;
             this._lineBoundingBox.dispose();
             this._rotateSpheresParent.dispose();
             this._scaleBoxesParent.dispose();
+            if (this._dragMesh) {
+                this._dragMesh.dispose();
+            }
             _super.prototype.dispose.call(this);
         };
         /**

+ 39 - 2
dist/preview release/babylon.no-module.max.js

@@ -12941,7 +12941,7 @@ var BABYLON;
              * Returns the current version of the framework
              */
             get: function () {
-                return "4.0.0-alpha.10";
+                return "4.0.0-alpha.11";
             },
             enumerable: true,
             configurable: true
@@ -36658,6 +36658,7 @@ var BABYLON;
                 }
                 if (fastCheck || !intersectInfo || length < intersectInfo.distance) {
                     intersectInfo = new BABYLON.IntersectionInfo(null, null, length);
+                    intersectInfo.faceId = index / 2;
                     if (fastCheck) {
                         break;
                     }
@@ -59311,7 +59312,7 @@ var BABYLON;
             this.bu = 0;
             /** (See getTextureCoordinates) The barycentric V coordinate that is used when calulating the texture coordinates of the collision.*/
             this.bv = 0;
-            /** The id of the face on the mesh that was picked  */
+            /** The index of the face on the mesh that was picked, or the index of the Line if the picked Mesh is a LinesMesh */
             this.faceId = -1;
             /** Id of the the submesh that was picked */
             this.subMeshId = 0;
@@ -105271,6 +105272,9 @@ var BABYLON;
              */
             _this.scalePivot = null;
             _this._existingMeshScale = new BABYLON.Vector3();
+            // Dragging
+            _this._dragMesh = null;
+            _this.pointerDragBehavior = new BABYLON.PointerDragBehavior();
             // Do not update the gizmo's scale so it has a fixed size to the object its attached to
             _this._updateScale = false;
             _this._anchorMesh = new BABYLON.AbstractMesh("anchor", gizmoLayer.utilityLayerScene);
@@ -105361,6 +105365,7 @@ var BABYLON;
                         _this.updateBoundingBox();
                         BoundingBoxGizmo._RestorePivotPoint(_this.attachedMesh);
                     }
+                    _this._updateDummy();
                 });
                 // Selection/deselection
                 _dragBehavior.onDragStartObservable.add(function () {
@@ -105370,6 +105375,7 @@ var BABYLON;
                 _dragBehavior.onDragEndObservable.add(function () {
                     _this.onRotationSphereDragEndObservable.notifyObservers({});
                     _this._selectNode(null);
+                    _this._updateDummy();
                 });
                 this_1._rotateSpheresParent.addChild(sphere);
             };
@@ -105422,6 +105428,7 @@ var BABYLON;
                                 _this._anchorMesh.removeChild(_this.attachedMesh);
                                 BoundingBoxGizmo._RestorePivotPoint(_this.attachedMesh);
                             }
+                            _this._updateDummy();
                         });
                         // Selection/deselection
                         _dragBehavior.onDragStartObservable.add(function () {
@@ -105431,6 +105438,7 @@ var BABYLON;
                         _dragBehavior.onDragEndObservable.add(function () {
                             _this.onScaleBoxDragEndObservable.notifyObservers({});
                             _this._selectNode(null);
+                            _this._updateDummy();
                         });
                         this_2._scaleBoxesParent.addChild(box);
                     };
@@ -105469,6 +105477,11 @@ var BABYLON;
                     _this._updateRotationSpheres();
                     _this._updateScaleBoxes();
                 }
+                // If dragg mesh is enabled and dragging, update the attached mesh pose to match the drag mesh
+                if (_this._dragMesh && _this.attachedMesh && _this.pointerDragBehavior.dragging) {
+                    _this._lineBoundingBox.position.rotateByQuaternionToRef(_this._rootMesh.rotationQuaternion, _this._tmpVector);
+                    _this.attachedMesh.setAbsolutePosition(_this._dragMesh.position.add(_this._tmpVector.scale(-1)));
+                }
             });
             _this.updateBoundingBox();
             return _this;
@@ -105501,6 +105514,7 @@ var BABYLON;
             this._PivotCached--;
         };
         BoundingBoxGizmo.prototype._attachedMeshChanged = function (value) {
+            var _this = this;
             if (value) {
                 // Reset anchor mesh to match attached mesh's scale
                 // This is needed to avoid invalid box/sphere position on first drag
@@ -105509,6 +105523,9 @@ var BABYLON;
                 this._anchorMesh.removeChild(value);
                 BoundingBoxGizmo._RestorePivotPoint(value);
                 this.updateBoundingBox();
+                this.gizmoLayer.utilityLayerScene.onAfterRenderObservable.addOnce(function () {
+                    _this._updateDummy();
+                });
             }
         };
         BoundingBoxGizmo.prototype._selectNode = function (selectedMesh) {
@@ -105630,6 +105647,23 @@ var BABYLON;
                 }
             });
         };
+        BoundingBoxGizmo.prototype._updateDummy = function () {
+            if (this._dragMesh) {
+                this._dragMesh.position.copyFrom(this._lineBoundingBox.getAbsolutePosition());
+                this._dragMesh.scaling.copyFrom(this._lineBoundingBox.scaling);
+                this._dragMesh.rotationQuaternion.copyFrom(this._rootMesh.rotationQuaternion);
+            }
+        };
+        /**
+         * Enables a pointer drag behavior on the bounding box of the gizmo
+         */
+        BoundingBoxGizmo.prototype.enableDragBehavior = function () {
+            this._dragMesh = BABYLON.Mesh.CreateBox("dummy", 1, this.gizmoLayer.utilityLayerScene);
+            this._dragMesh.visibility = 0;
+            this._dragMesh.rotationQuaternion = new BABYLON.Quaternion();
+            this.pointerDragBehavior.useObjectOrienationForDragging = false;
+            this._dragMesh.addBehavior(this.pointerDragBehavior);
+        };
         /**
          * Disposes of the gizmo
          */
@@ -105639,6 +105673,9 @@ var BABYLON;
             this._lineBoundingBox.dispose();
             this._rotateSpheresParent.dispose();
             this._scaleBoxesParent.dispose();
+            if (this._dragMesh) {
+                this._dragMesh.dispose();
+            }
             _super.prototype.dispose.call(this);
         };
         /**

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/babylon.worker.js


+ 39 - 2
dist/preview release/es6.js

@@ -12941,7 +12941,7 @@ var BABYLON;
              * Returns the current version of the framework
              */
             get: function () {
-                return "4.0.0-alpha.10";
+                return "4.0.0-alpha.11";
             },
             enumerable: true,
             configurable: true
@@ -36658,6 +36658,7 @@ var BABYLON;
                 }
                 if (fastCheck || !intersectInfo || length < intersectInfo.distance) {
                     intersectInfo = new BABYLON.IntersectionInfo(null, null, length);
+                    intersectInfo.faceId = index / 2;
                     if (fastCheck) {
                         break;
                     }
@@ -59311,7 +59312,7 @@ var BABYLON;
             this.bu = 0;
             /** (See getTextureCoordinates) The barycentric V coordinate that is used when calulating the texture coordinates of the collision.*/
             this.bv = 0;
-            /** The id of the face on the mesh that was picked  */
+            /** The index of the face on the mesh that was picked, or the index of the Line if the picked Mesh is a LinesMesh */
             this.faceId = -1;
             /** Id of the the submesh that was picked */
             this.subMeshId = 0;
@@ -105271,6 +105272,9 @@ var BABYLON;
              */
             _this.scalePivot = null;
             _this._existingMeshScale = new BABYLON.Vector3();
+            // Dragging
+            _this._dragMesh = null;
+            _this.pointerDragBehavior = new BABYLON.PointerDragBehavior();
             // Do not update the gizmo's scale so it has a fixed size to the object its attached to
             _this._updateScale = false;
             _this._anchorMesh = new BABYLON.AbstractMesh("anchor", gizmoLayer.utilityLayerScene);
@@ -105361,6 +105365,7 @@ var BABYLON;
                         _this.updateBoundingBox();
                         BoundingBoxGizmo._RestorePivotPoint(_this.attachedMesh);
                     }
+                    _this._updateDummy();
                 });
                 // Selection/deselection
                 _dragBehavior.onDragStartObservable.add(function () {
@@ -105370,6 +105375,7 @@ var BABYLON;
                 _dragBehavior.onDragEndObservable.add(function () {
                     _this.onRotationSphereDragEndObservable.notifyObservers({});
                     _this._selectNode(null);
+                    _this._updateDummy();
                 });
                 this_1._rotateSpheresParent.addChild(sphere);
             };
@@ -105422,6 +105428,7 @@ var BABYLON;
                                 _this._anchorMesh.removeChild(_this.attachedMesh);
                                 BoundingBoxGizmo._RestorePivotPoint(_this.attachedMesh);
                             }
+                            _this._updateDummy();
                         });
                         // Selection/deselection
                         _dragBehavior.onDragStartObservable.add(function () {
@@ -105431,6 +105438,7 @@ var BABYLON;
                         _dragBehavior.onDragEndObservable.add(function () {
                             _this.onScaleBoxDragEndObservable.notifyObservers({});
                             _this._selectNode(null);
+                            _this._updateDummy();
                         });
                         this_2._scaleBoxesParent.addChild(box);
                     };
@@ -105469,6 +105477,11 @@ var BABYLON;
                     _this._updateRotationSpheres();
                     _this._updateScaleBoxes();
                 }
+                // If dragg mesh is enabled and dragging, update the attached mesh pose to match the drag mesh
+                if (_this._dragMesh && _this.attachedMesh && _this.pointerDragBehavior.dragging) {
+                    _this._lineBoundingBox.position.rotateByQuaternionToRef(_this._rootMesh.rotationQuaternion, _this._tmpVector);
+                    _this.attachedMesh.setAbsolutePosition(_this._dragMesh.position.add(_this._tmpVector.scale(-1)));
+                }
             });
             _this.updateBoundingBox();
             return _this;
@@ -105501,6 +105514,7 @@ var BABYLON;
             this._PivotCached--;
         };
         BoundingBoxGizmo.prototype._attachedMeshChanged = function (value) {
+            var _this = this;
             if (value) {
                 // Reset anchor mesh to match attached mesh's scale
                 // This is needed to avoid invalid box/sphere position on first drag
@@ -105509,6 +105523,9 @@ var BABYLON;
                 this._anchorMesh.removeChild(value);
                 BoundingBoxGizmo._RestorePivotPoint(value);
                 this.updateBoundingBox();
+                this.gizmoLayer.utilityLayerScene.onAfterRenderObservable.addOnce(function () {
+                    _this._updateDummy();
+                });
             }
         };
         BoundingBoxGizmo.prototype._selectNode = function (selectedMesh) {
@@ -105630,6 +105647,23 @@ var BABYLON;
                 }
             });
         };
+        BoundingBoxGizmo.prototype._updateDummy = function () {
+            if (this._dragMesh) {
+                this._dragMesh.position.copyFrom(this._lineBoundingBox.getAbsolutePosition());
+                this._dragMesh.scaling.copyFrom(this._lineBoundingBox.scaling);
+                this._dragMesh.rotationQuaternion.copyFrom(this._rootMesh.rotationQuaternion);
+            }
+        };
+        /**
+         * Enables a pointer drag behavior on the bounding box of the gizmo
+         */
+        BoundingBoxGizmo.prototype.enableDragBehavior = function () {
+            this._dragMesh = BABYLON.Mesh.CreateBox("dummy", 1, this.gizmoLayer.utilityLayerScene);
+            this._dragMesh.visibility = 0;
+            this._dragMesh.rotationQuaternion = new BABYLON.Quaternion();
+            this.pointerDragBehavior.useObjectOrienationForDragging = false;
+            this._dragMesh.addBehavior(this.pointerDragBehavior);
+        };
         /**
          * Disposes of the gizmo
          */
@@ -105639,6 +105673,9 @@ var BABYLON;
             this._lineBoundingBox.dispose();
             this._rotateSpheresParent.dispose();
             this._scaleBoxesParent.dispose();
+            if (this._dragMesh) {
+                this._dragMesh.dispose();
+            }
             _super.prototype.dispose.call(this);
         };
         /**

+ 1 - 1
dist/preview release/glTF2Interface/package.json

@@ -1,7 +1,7 @@
 {
     "name": "babylonjs-gltf2interface",
     "description": "A typescript declaration of babylon's gltf2 inteface.",
-    "version": "4.0.0-alpha.10",
+    "version": "4.0.0-alpha.11",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

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

@@ -1502,6 +1502,26 @@ declare module BABYLON.GUI {
                 */
             readonly isLoaded: boolean;
             /**
+                * Gets or sets a boolean indicating if nine patch slices (left, top, right, bottom) should be read from image data
+                */
+            populateNinePatchSlicesFromImage: boolean;
+            /**
+                * Gets or sets the left value for slicing (9-patch)
+                */
+            sliceLeft: number;
+            /**
+                * Gets or sets the right value for slicing (9-patch)
+                */
+            sliceRight: number;
+            /**
+                * Gets or sets the top value for slicing (9-patch)
+                */
+            sliceTop: number;
+            /**
+                * Gets or sets the bottom value for slicing (9-patch)
+                */
+            sliceBottom: number;
+            /**
                 * Gets or sets the left coordinate in the source image
                 */
             sourceLeft: number;
@@ -1567,6 +1587,8 @@ declare module BABYLON.GUI {
             static readonly STRETCH_UNIFORM: number;
             /** STRETCH_EXTEND */
             static readonly STRETCH_EXTEND: number;
+            /** NINE_PATCH */
+            static readonly STRETCH_NINE_PATCH: number;
     }
 }
 declare module BABYLON.GUI {
@@ -1595,6 +1617,8 @@ declare module BABYLON.GUI {
             onTextCutObservable: BABYLON.Observable<InputText>;
             /** BABYLON.Observable raised when paste event is triggered */
             onTextPasteObservable: BABYLON.Observable<InputText>;
+            /** BABYLON.Observable raised when a key event was processed */
+            onKeyboardEventProcessedObservable: BABYLON.Observable<KeyboardEvent>;
             /** Gets or sets the maximum width allowed by the control */
             maxWidth: string | number;
             /** Gets the maximum width allowed by the control in pixels */
@@ -1615,6 +1639,8 @@ declare module BABYLON.GUI {
             thickness: number;
             /** Gets or sets the background color when focused */
             focusedBackground: string;
+            /** Gets or sets the background color when focused */
+            focusedColor: string;
             /** Gets or sets the background color */
             background: string;
             /** Gets or sets the placeholder color */

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/gui/babylon.gui.js


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js.map


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

@@ -1622,6 +1622,26 @@ declare module 'babylonjs-gui/2D/controls/image' {
                 */
             readonly isLoaded: boolean;
             /**
+                * Gets or sets a boolean indicating if nine patch slices (left, top, right, bottom) should be read from image data
+                */
+            populateNinePatchSlicesFromImage: boolean;
+            /**
+                * Gets or sets the left value for slicing (9-patch)
+                */
+            sliceLeft: number;
+            /**
+                * Gets or sets the right value for slicing (9-patch)
+                */
+            sliceRight: number;
+            /**
+                * Gets or sets the top value for slicing (9-patch)
+                */
+            sliceTop: number;
+            /**
+                * Gets or sets the bottom value for slicing (9-patch)
+                */
+            sliceBottom: number;
+            /**
                 * Gets or sets the left coordinate in the source image
                 */
             sourceLeft: number;
@@ -1687,6 +1707,8 @@ declare module 'babylonjs-gui/2D/controls/image' {
             static readonly STRETCH_UNIFORM: number;
             /** STRETCH_EXTEND */
             static readonly STRETCH_EXTEND: number;
+            /** NINE_PATCH */
+            static readonly STRETCH_NINE_PATCH: number;
     }
 }
 
@@ -1720,6 +1742,8 @@ declare module 'babylonjs-gui/2D/controls/inputText' {
             onTextCutObservable: Observable<InputText>;
             /** Observable raised when paste event is triggered */
             onTextPasteObservable: Observable<InputText>;
+            /** Observable raised when a key event was processed */
+            onKeyboardEventProcessedObservable: Observable<KeyboardEvent>;
             /** Gets or sets the maximum width allowed by the control */
             maxWidth: string | number;
             /** Gets the maximum width allowed by the control in pixels */
@@ -1740,6 +1764,8 @@ declare module 'babylonjs-gui/2D/controls/inputText' {
             thickness: number;
             /** Gets or sets the background color when focused */
             focusedBackground: string;
+            /** Gets or sets the background color when focused */
+            focusedColor: string;
             /** Gets or sets the background color */
             background: string;
             /** Gets or sets the placeholder color */
@@ -4678,6 +4704,26 @@ declare module BABYLON.GUI {
                 */
             readonly isLoaded: boolean;
             /**
+                * Gets or sets a boolean indicating if nine patch slices (left, top, right, bottom) should be read from image data
+                */
+            populateNinePatchSlicesFromImage: boolean;
+            /**
+                * Gets or sets the left value for slicing (9-patch)
+                */
+            sliceLeft: number;
+            /**
+                * Gets or sets the right value for slicing (9-patch)
+                */
+            sliceRight: number;
+            /**
+                * Gets or sets the top value for slicing (9-patch)
+                */
+            sliceTop: number;
+            /**
+                * Gets or sets the bottom value for slicing (9-patch)
+                */
+            sliceBottom: number;
+            /**
                 * Gets or sets the left coordinate in the source image
                 */
             sourceLeft: number;
@@ -4743,6 +4789,8 @@ declare module BABYLON.GUI {
             static readonly STRETCH_UNIFORM: number;
             /** STRETCH_EXTEND */
             static readonly STRETCH_EXTEND: number;
+            /** NINE_PATCH */
+            static readonly STRETCH_NINE_PATCH: number;
     }
 }
 declare module BABYLON.GUI {
@@ -4771,6 +4819,8 @@ declare module BABYLON.GUI {
             onTextCutObservable: BABYLON.Observable<InputText>;
             /** BABYLON.Observable raised when paste event is triggered */
             onTextPasteObservable: BABYLON.Observable<InputText>;
+            /** BABYLON.Observable raised when a key event was processed */
+            onKeyboardEventProcessedObservable: BABYLON.Observable<KeyboardEvent>;
             /** Gets or sets the maximum width allowed by the control */
             maxWidth: string | number;
             /** Gets the maximum width allowed by the control in pixels */
@@ -4791,6 +4841,8 @@ declare module BABYLON.GUI {
             thickness: number;
             /** Gets or sets the background color when focused */
             focusedBackground: string;
+            /** Gets or sets the background color when focused */
+            focusedColor: string;
             /** Gets or sets the background color */
             background: string;
             /** Gets or sets the placeholder color */

+ 2 - 2
dist/preview release/gui/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "4.0.0-alpha.10",
+    "version": "4.0.0-alpha.11",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.10"
+        "babylonjs": "4.0.0-alpha.11"
     },
     "engines": {
         "node": "*"

Разлика између датотеке није приказан због своје велике величине
+ 7 - 7
dist/preview release/inspector/babylon.inspector.bundle.js


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js.map


+ 5 - 5
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "4.0.0-alpha.10",
+    "version": "4.0.0-alpha.11",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,10 +28,10 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.10",
-        "babylonjs-gui": "4.0.0-alpha.10",
-        "babylonjs-loaders": "4.0.0-alpha.10",
-        "babylonjs-serializers": "4.0.0-alpha.10"
+        "babylonjs": "4.0.0-alpha.11",
+        "babylonjs-gui": "4.0.0-alpha.11",
+        "babylonjs-loaders": "4.0.0-alpha.11",
+        "babylonjs-serializers": "4.0.0-alpha.11"
     },
     "engines": {
         "node": "*"

+ 3 - 3
dist/preview release/loaders/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "4.0.0-alpha.10",
+    "version": "4.0.0-alpha.11",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,8 +27,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "4.0.0-alpha.10",
-        "babylonjs": "4.0.0-alpha.10"
+        "babylonjs-gltf2interface": "4.0.0-alpha.11",
+        "babylonjs": "4.0.0-alpha.11"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/materialsLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.0.0-alpha.10",
+    "version": "4.0.0-alpha.11",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.10"
+        "babylonjs": "4.0.0-alpha.11"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/postProcessesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.0.0-alpha.10",
+    "version": "4.0.0-alpha.11",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.10"
+        "babylonjs": "4.0.0-alpha.11"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/proceduralTexturesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.0.0-alpha.10",
+    "version": "4.0.0-alpha.11",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.10"
+        "babylonjs": "4.0.0-alpha.11"
     },
     "engines": {
         "node": "*"

+ 3 - 3
dist/preview release/serializers/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "4.0.0-alpha.10",
+    "version": "4.0.0-alpha.11",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,8 +27,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.0.0-alpha.10",
-        "babylonjs-gltf2interface": "4.0.0-alpha.10"
+        "babylonjs": "4.0.0-alpha.11",
+        "babylonjs-gltf2interface": "4.0.0-alpha.11"
     },
     "engines": {
         "node": "*"

+ 29 - 77
dist/preview release/viewer/babylon.viewer.d.ts

@@ -482,37 +482,6 @@ declare module BabylonViewer {
     export const telemetryManager: TelemetryManager;
 }
 declare module BabylonViewer {
-    /**
-        * An instance of the class is in charge of loading the model correctly.
-        * This class will continously be expended with tasks required from the specific loaders Babylon has.
-        *
-        * A Model loader is unique per (Abstract)Viewer. It is being generated by the viewer
-        */
-    export class ModelLoader {
-            readonly baseUrl: string;
-            /**
-                * Create a new Model loader
-                * @param _viewer the viewer using this model loader
-                */
-            constructor(_observablesManager: ObservablesManager, _configurationContainer?: ConfigurationContainer | undefined);
-            /**
-                * Adds a new plugin to the loader process.
-                *
-                * @param plugin the plugin name or the plugin itself
-                */
-            addPlugin(plugin: ILoaderPlugin | string): void;
-            /**
-                * Load a model using predefined configuration
-                * @param modelConfiguration the modelConfiguration to use to load the model
-                */
-            load(modelConfiguration: IModelConfiguration): ViewerModel;
-            cancelLoad(model: ViewerModel): void;
-            /**
-                * dispose the model loader.
-                * If loaders are registered and are in the middle of loading, they will be disposed and the request(s) will be cancelled.
-                */
-            dispose(): void;
-    }
 }
 declare module BabylonViewer {
     /**
@@ -1545,19 +1514,6 @@ declare module BabylonViewer {
     }
 }
 declare module BabylonViewer {
-    /**
-        * Get a loader plugin according to its name.
-        * The plugin will be cached and will be reused if called for again.
-        *
-        * @param name the name of the plugin
-        */
-    export function getLoaderPluginByName(name: string): ILoaderPlugin;
-    /**
-        *
-        */
-    export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
-}
-declare module BabylonViewer {
 }
 declare module BabylonViewer {
     export interface IEnvironmentMapConfiguration {
@@ -1693,43 +1649,39 @@ declare module BabylonViewer {
     }
 }
 declare module BabylonViewer {
-    export class TelemetryLoaderPlugin implements ILoaderPlugin {
-        onInit(loader: BABYLON.ISceneLoaderPlugin | BABYLON.ISceneLoaderPluginAsync, model: ViewerModel): void;
-        onLoaded(model: ViewerModel): void;
-        onError(message: string, exception: any): void;
-        onComplete(): void;
-    }
-}
-declare module BabylonViewer {
-    /**
-      * A loder plugin to use MSFT_lod extension correctly (glTF)
-      */
-    export class MSFTLodLoaderPlugin implements ILoaderPlugin {
-        onInit(loader: BABYLON.ISceneLoaderPlugin | BABYLON.ISceneLoaderPluginAsync, model: ViewerModel): void;
-        onExtensionLoaded(extension: BABYLON.IGLTFLoaderExtension): void;
-    }
-}
-declare module BabylonViewer {
-    /**
-      * Force-apply material configuration right after a material was loaded.
-      */
-    export class ApplyMaterialConfigPlugin implements ILoaderPlugin {
-        onInit(loader: BABYLON.ISceneLoaderPlugin | BABYLON.ISceneLoaderPluginAsync, model: ViewerModel): void;
-        onMaterialLoaded(material: BABYLON.Material): void;
+    export interface ICameraConfiguration {
+        position?: {
+            x: number;
+            y: number;
+            z: number;
+        };
+        rotation?: {
+            x: number;
+            y: number;
+            z: number;
+            w: number;
+        };
+        fov?: number;
+        fovMode?: number;
+        minZ?: number;
+        maxZ?: number;
+        inertia?: number;
+        exposure?: number;
+        pinchPrecision?: number;
+        behaviors?: {
+            [name: string]: boolean | number | ICameraBehaviorConfiguration;
+        };
+        disableCameraControl?: boolean;
+        disableCtrlForPanning?: boolean;
+        disableAutoFocus?: boolean;
+        [propName: string]: any;
     }
-}
-declare module BabylonViewer {
-    /**
-      * A (PBR) material will be extended using this function.
-      * This function will hold extra default configuration for the viewer, if not implemented in Babylon itself.
-      */
-    export class ExtendedMaterialLoaderPlugin implements ILoaderPlugin {
-        onMaterialLoaded(baseMaterial: BABYLON.Material): void;
+    export interface ICameraBehaviorConfiguration {
+        type: number;
+        [propName: string]: any;
     }
 }
 declare module BabylonViewer {
-}
-declare module BabylonViewer {
     /**
         * The Color Grading Configuration groups the different settings used to define the color grading used in the viewer.
         */

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 31 - 107
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -527,42 +527,7 @@ declare module 'babylonjs-viewer/managers/telemetryManager' {
 }
 
 declare module 'babylonjs-viewer/loader/modelLoader' {
-    import { ConfigurationContainer } from 'babylonjs-viewer/configuration/configurationContainer';
-    import { IModelConfiguration } from 'babylonjs-viewer/configuration/interfaces/modelConfiguration';
-    import { ObservablesManager } from 'babylonjs-viewer/managers/observablesManager';
-    import { ViewerModel } from 'babylonjs-viewer/model/viewerModel';
-    import { ILoaderPlugin } from 'babylonjs-viewer/loader/plugins';
-    /**
-        * An instance of the class is in charge of loading the model correctly.
-        * This class will continously be expended with tasks required from the specific loaders Babylon has.
-        *
-        * A Model loader is unique per (Abstract)Viewer. It is being generated by the viewer
-        */
-    export class ModelLoader {
-            readonly baseUrl: string;
-            /**
-                * Create a new Model loader
-                * @param _viewer the viewer using this model loader
-                */
-            constructor(_observablesManager: ObservablesManager, _configurationContainer?: ConfigurationContainer | undefined);
-            /**
-                * Adds a new plugin to the loader process.
-                *
-                * @param plugin the plugin name or the plugin itself
-                */
-            addPlugin(plugin: ILoaderPlugin | string): void;
-            /**
-                * Load a model using predefined configuration
-                * @param modelConfiguration the modelConfiguration to use to load the model
-                */
-            load(modelConfiguration: IModelConfiguration): ViewerModel;
-            cancelLoad(model: ViewerModel): void;
-            /**
-                * dispose the model loader.
-                * If loaders are registered and are in the middle of loading, they will be disposed and the request(s) will be cancelled.
-                */
-            dispose(): void;
-    }
+    
 }
 
 declare module 'babylonjs-viewer/model/viewerModel' {
@@ -1642,26 +1607,6 @@ declare module 'babylonjs-viewer/configuration/interfaces/modelConfiguration' {
     }
 }
 
-declare module 'babylonjs-viewer/loader/plugins' {
-    import { TelemetryLoaderPlugin } from "babylonjs-viewer/loader/plugins/telemetryLoaderPlugin";
-    import { ILoaderPlugin } from "babylonjs-viewer/loader/plugins/loaderPlugin";
-    import { MSFTLodLoaderPlugin } from 'babylonjs-viewer/loader/plugins/msftLodLoaderPlugin';
-    import { ApplyMaterialConfigPlugin } from 'babylonjs-viewer/loader/plugins/applyMaterialConfig';
-    import { ExtendedMaterialLoaderPlugin } from 'babylonjs-viewer/loader/plugins/extendedMaterialLoaderPlugin';
-    export { TelemetryLoaderPlugin, ILoaderPlugin, MSFTLodLoaderPlugin, ApplyMaterialConfigPlugin, ExtendedMaterialLoaderPlugin };
-    /**
-        * Get a loader plugin according to its name.
-        * The plugin will be cached and will be reused if called for again.
-        *
-        * @param name the name of the plugin
-        */
-    export function getLoaderPluginByName(name: string): ILoaderPlugin;
-    /**
-        *
-        */
-    export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
-}
-
 declare module 'babylonjs-viewer/configuration/interfaces' {
     export * from 'babylonjs-viewer/configuration/interfaces/cameraConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/colorGradingConfiguration';
@@ -1820,61 +1765,40 @@ declare module 'babylonjs-viewer/configuration/interfaces/modelAnimationConfigur
     }
 }
 
-declare module 'babylonjs-viewer/loader/plugins/telemetryLoaderPlugin' {
-    import { ILoaderPlugin } from "babylonjs-viewer/loader/plugins/loaderPlugin";
-    import { ViewerModel } from "babylonjs-viewer/model/viewerModel";
-    import { ISceneLoaderPlugin, ISceneLoaderPluginAsync } from "babylonjs";
-    export class TelemetryLoaderPlugin implements ILoaderPlugin {
-        onInit(loader: ISceneLoaderPlugin | ISceneLoaderPluginAsync, model: ViewerModel): void;
-        onLoaded(model: ViewerModel): void;
-        onError(message: string, exception: any): void;
-        onComplete(): void;
-    }
-}
-
-declare module 'babylonjs-viewer/loader/plugins/msftLodLoaderPlugin' {
-    import { ISceneLoaderPlugin, ISceneLoaderPluginAsync } from 'babylonjs';
-    import { IGLTFLoaderExtension } from 'babylonjs-loaders';
-    import { ViewerModel } from 'babylonjs-viewer/model/viewerModel';
-    import { ILoaderPlugin } from 'babylonjs-viewer/loader/plugins/loaderPlugin';
-    /**
-      * A loder plugin to use MSFT_lod extension correctly (glTF)
-      */
-    export class MSFTLodLoaderPlugin implements ILoaderPlugin {
-        onInit(loader: ISceneLoaderPlugin | ISceneLoaderPluginAsync, model: ViewerModel): void;
-        onExtensionLoaded(extension: IGLTFLoaderExtension): void;
-    }
-}
-
-declare module 'babylonjs-viewer/loader/plugins/applyMaterialConfig' {
-    import { ISceneLoaderPlugin, ISceneLoaderPluginAsync, Material } from 'babylonjs';
-    import { ViewerModel } from 'babylonjs-viewer/model/viewerModel';
-    import { ILoaderPlugin } from 'babylonjs-viewer/loader/plugins/loaderPlugin';
-    /**
-      * Force-apply material configuration right after a material was loaded.
-      */
-    export class ApplyMaterialConfigPlugin implements ILoaderPlugin {
-        onInit(loader: ISceneLoaderPlugin | ISceneLoaderPluginAsync, model: ViewerModel): void;
-        onMaterialLoaded(material: Material): void;
+declare module 'babylonjs-viewer/configuration/interfaces/cameraConfiguration' {
+    export interface ICameraConfiguration {
+        position?: {
+            x: number;
+            y: number;
+            z: number;
+        };
+        rotation?: {
+            x: number;
+            y: number;
+            z: number;
+            w: number;
+        };
+        fov?: number;
+        fovMode?: number;
+        minZ?: number;
+        maxZ?: number;
+        inertia?: number;
+        exposure?: number;
+        pinchPrecision?: number;
+        behaviors?: {
+            [name: string]: boolean | number | ICameraBehaviorConfiguration;
+        };
+        disableCameraControl?: boolean;
+        disableCtrlForPanning?: boolean;
+        disableAutoFocus?: boolean;
+        [propName: string]: any;
     }
-}
-
-declare module 'babylonjs-viewer/loader/plugins/extendedMaterialLoaderPlugin' {
-    import { Material } from 'babylonjs';
-    import { ILoaderPlugin } from 'babylonjs-viewer/loader/plugins/loaderPlugin';
-    /**
-      * A (PBR) material will be extended using this function.
-      * This function will hold extra default configuration for the viewer, if not implemented in Babylon itself.
-      */
-    export class ExtendedMaterialLoaderPlugin implements ILoaderPlugin {
-        onMaterialLoaded(baseMaterial: Material): void;
+    export interface ICameraBehaviorConfiguration {
+        type: number;
+        [propName: string]: any;
     }
 }
 
-declare module 'babylonjs-viewer/configuration/interfaces/cameraConfiguration' {
-    
-}
-
 declare module 'babylonjs-viewer/configuration/interfaces/colorGradingConfiguration' {
     /**
         * The Color Grading Configuration groups the different settings used to define the color grading used in the viewer.

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

@@ -21,11 +21,13 @@
   - Added support for clipboard events to let users perform `cut`, `copy` and `paste` events ([Saket Saurabh](https://github.com/ssaket))
   - Added new [ScrollViewer](https://doc.babylonjs.com/how_to/scrollviewer) with mouse wheel scrolling for larger containers to be viewed using Sliders ([JohnK](https://github.com/BabylonJSGuide/) / [Deltakosh](https://github.com/deltakosh))
   - Moved to a measure / draw mechanism ([Deltakosh](https://github.com/deltakosh))
+  - Added support for [nine patch stretch](https://www.babylonjs-playground.com/#G5H9IN#2) mode for images. ([Deltakosh](https://github.com/deltakosh))
 
 ## Updates
 
 ### GUI
 
+- Added `inputText.onKeyboardEventProcessedObservable` ([Deltakosh](https://github.com/deltakosh))
 - Added `button.image` and `button.textBlock` to simplify access to button internal parts ([Deltakosh](https://github.com/deltakosh))
 - Added `sldier.displayThumb` to show/hide slider's thumb ([Deltakosh](https://github.com/deltakosh))
 - Added `grid.rowCount`, `grid.columnCount` and `grid.getChildrenAt()` ([Deltakosh](https://github.com/deltakosh))
@@ -137,6 +139,7 @@
 - Fixed inspector dynamic loading ([Sebavan](https://github.com/Sebavan))
 - Fixed infiniteDistance not working anymore ([Sebavan](https://github.com/Sebavan))
 - Fixed bug in SolidParticle BoundingSphere update within the SolidParticleSystem ([barroij](https://github.com/barroij))
+- Update Picking so that when the picked Mesh is a LinesMesh, the index of the picked line is returned in the `faceId` property of the `PickingInfo`, as we do with face index the picked Mesh is made of triangle faces ([barroij](https://github.com/barroij))
 
 ### Viewer
 

+ 206 - 0
gui/src/2D/controls/image.ts

@@ -6,6 +6,8 @@ import { Measure } from "2D";
  * Class used to create 2D images
  */
 export class Image extends Control {
+    private static _WorkingCanvas: Nullable<HTMLCanvasElement> = null;
+
     private _domImage: HTMLImageElement;
     private _imageWidth: number;
     private _imageHeight: number;
@@ -23,6 +25,12 @@ export class Image extends Control {
     private _cellHeight: number = 0;
     private _cellId: number = -1;
 
+    private _populateNinePatchSlicesFromImage = false;
+    private _sliceLeft: number;
+    private _sliceRight: number;
+    private _sliceTop: number;
+    private _sliceBottom: number;
+
     /**
      * Observable notified when the content is loaded
      */
@@ -36,6 +44,93 @@ export class Image extends Control {
     }
 
     /**
+     * Gets or sets a boolean indicating if nine patch slices (left, top, right, bottom) should be read from image data
+     */
+    public get populateNinePatchSlicesFromImage(): boolean {
+        return this._populateNinePatchSlicesFromImage;
+    }
+
+    public set populateNinePatchSlicesFromImage(value: boolean) {
+        if (this._populateNinePatchSlicesFromImage === value) {
+            return;
+        }
+
+        this._populateNinePatchSlicesFromImage = value;
+
+        if (this._populateNinePatchSlicesFromImage && this._loaded) {
+            this._extractNinePatchSliceDataFromImage();
+        }
+    }
+
+    /**
+     * Gets or sets the left value for slicing (9-patch)
+     */
+    public get sliceLeft(): number {
+        return this._sliceLeft;
+    }
+
+    public set sliceLeft(value: number) {
+        if (this._sliceLeft === value) {
+            return;
+        }
+
+        this._sliceLeft = value;
+
+        this._markAsDirty();
+    }
+
+    /**
+     * Gets or sets the right value for slicing (9-patch)
+     */
+    public get sliceRight(): number {
+        return this._sliceRight;
+    }
+
+    public set sliceRight(value: number) {
+        if (this._sliceRight === value) {
+            return;
+        }
+
+        this._sliceRight = value;
+
+        this._markAsDirty();
+    }
+
+    /**
+     * Gets or sets the top value for slicing (9-patch)
+     */
+    public get sliceTop(): number {
+        return this._sliceTop;
+    }
+
+    public set sliceTop(value: number) {
+        if (this._sliceTop === value) {
+            return;
+        }
+
+        this._sliceTop = value;
+
+        this._markAsDirty();
+    }
+
+    /**
+     * Gets or sets the bottom value for slicing (9-patch)
+     */
+    public get sliceBottom(): number {
+        return this._sliceBottom;
+    }
+
+    public set sliceBottom(value: number) {
+        if (this._sliceBottom === value) {
+            return;
+        }
+
+        this._sliceBottom = value;
+
+        this._markAsDirty();
+    }
+
+    /**
      * Gets or sets the left coordinate in the source image
      */
     public get sourceLeft(): number {
@@ -163,6 +258,10 @@ export class Image extends Control {
         this._imageHeight = this._domImage.height;
         this._loaded = true;
 
+        if (this._populateNinePatchSlicesFromImage) {
+            this._extractNinePatchSliceDataFromImage();
+        }
+
         if (this._autoScale) {
             this.synchronizeSizeWithContent();
         }
@@ -172,6 +271,56 @@ export class Image extends Control {
         this._markAsDirty();
     }
 
+    private _extractNinePatchSliceDataFromImage() {
+        if (!Image._WorkingCanvas) {
+            Image._WorkingCanvas = document.createElement('canvas');
+        }
+        const canvas = Image._WorkingCanvas;
+        const context = canvas.getContext('2d')!;
+        const width = this._domImage.width;
+        const height = this._domImage.height;
+
+        canvas.width = width;
+        canvas.height = height;
+
+        context.drawImage(this._domImage, 0, 0, width, height);
+        const imageData = context.getImageData(0, 0, width, height);
+
+        // Left and right
+        this._sliceLeft = -1;
+        this._sliceRight = -1;
+        for (var x = 0; x < width; x++) {
+            const alpha = imageData.data[x * 4 + 3];
+
+            if (alpha > 127 && this._sliceLeft === -1) {
+                this._sliceLeft = x;
+                continue;
+            }
+
+            if (alpha < 127 && this._sliceLeft > -1) {
+                this._sliceRight = x;
+                break;
+            }
+        }
+
+        // top and bottom
+        this._sliceTop = -1;
+        this._sliceBottom = -1;
+        for (var y = 0; y < height; y++) {
+            const alpha = imageData.data[y * width * 4 + 3];
+
+            if (alpha > 127 && this._sliceTop === -1) {
+                this._sliceTop = y;
+                continue;
+            }
+
+            if (alpha < 127 && this._sliceTop > -1) {
+                this._sliceBottom = y;
+                break;
+            }
+        }
+    }
+
     /**
      * Gets or sets image source url
      */
@@ -345,12 +494,67 @@ export class Image extends Control {
                     context.drawImage(this._domImage, x, y, width, height,
                         this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
                     break;
+                case Image.STRETCH_NINE_PATCH:
+                    this._renderNinePatch(context);
+                    break;
             }
         }
 
         context.restore();
     }
 
+    private _renderCornerPatch(context: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, targetX: number, targetY: number): void {
+        context.drawImage(this._domImage, x, y, width, height, this._currentMeasure.left + targetX, this._currentMeasure.top + targetY, width, height);
+    }
+
+    private _renderNinePatch(context: CanvasRenderingContext2D): void {
+        let height = this._imageHeight;
+        let leftWidth = this._sliceLeft;
+        let topHeight = this._sliceTop;
+        let bottomHeight = this._imageHeight - this._sliceBottom;
+        let rightWidth = this._imageWidth - this._sliceRight;
+        let left = 0;
+        let top = 0;
+
+        if (this._populateNinePatchSlicesFromImage) {
+            left = 1;
+            top = 1;
+            height -= 2;
+            leftWidth -= 1;
+            topHeight -= 1;
+            bottomHeight -= 1;
+            rightWidth -= 1;
+        }
+
+        const centerWidth = this._sliceRight - this._sliceLeft + 1;
+        const targetCenterWidth = this._currentMeasure.width - rightWidth - this.sliceLeft + 1;
+        const targetTopHeight = this._currentMeasure.height - height + this._sliceBottom;
+
+        // Corners
+        this._renderCornerPatch(context, left, top, leftWidth, topHeight, 0, 0);
+        this._renderCornerPatch(context, left, this._sliceBottom, leftWidth, height - this._sliceBottom, 0, targetTopHeight);
+
+        this._renderCornerPatch(context, this._sliceRight, top, rightWidth, topHeight, this._currentMeasure.width - rightWidth, 0);
+        this._renderCornerPatch(context, this._sliceRight, this._sliceBottom, rightWidth, height - this._sliceBottom, this._currentMeasure.width - rightWidth, targetTopHeight);
+
+        // Center
+        context.drawImage(this._domImage, this._sliceLeft, this._sliceTop, centerWidth, this._sliceBottom - this._sliceTop + 1,
+            this._currentMeasure.left + leftWidth, this._currentMeasure.top + topHeight, targetCenterWidth, targetTopHeight - topHeight + 1);
+
+        // Borders
+        context.drawImage(this._domImage, left, this._sliceTop, leftWidth, this._sliceBottom - this._sliceTop,
+            this._currentMeasure.left, this._currentMeasure.top + topHeight, leftWidth, targetTopHeight - topHeight);
+
+        context.drawImage(this._domImage, this._sliceRight, this._sliceTop, leftWidth, this._sliceBottom - this._sliceTop,
+            this._currentMeasure.left + this._currentMeasure.width - rightWidth, this._currentMeasure.top + topHeight, leftWidth, targetTopHeight - topHeight);
+
+        context.drawImage(this._domImage, this._sliceLeft, top, centerWidth, topHeight,
+            this._currentMeasure.left + leftWidth, this._currentMeasure.top, targetCenterWidth, topHeight);
+
+        context.drawImage(this._domImage, this._sliceLeft, this._sliceBottom, centerWidth, bottomHeight,
+            this._currentMeasure.left + leftWidth, this._currentMeasure.top + targetTopHeight, targetCenterWidth, bottomHeight);
+    }
+
     public dispose() {
         super.dispose();
         this.onImageLoadedObservable.clear();
@@ -365,4 +569,6 @@ export class Image extends Control {
     public static readonly STRETCH_UNIFORM = 2;
     /** STRETCH_EXTEND */
     public static readonly STRETCH_EXTEND = 3;
+    /** NINE_PATCH */
+    public static readonly STRETCH_NINE_PATCH = 4;
 }

+ 36 - 11
gui/src/2D/controls/inputText.ts

@@ -12,6 +12,7 @@ export class InputText extends Control implements IFocusableControl {
     private _placeholderText = "";
     private _background = "#222222";
     private _focusedBackground = "#000000";
+    private _focusedColor = "white";
     private _placeholderColor = "gray";
     private _thickness = 1;
     private _margin = new ValueAndUnit(10, ValueAndUnit.UNITMODE_PIXEL);
@@ -61,6 +62,8 @@ export class InputText extends Control implements IFocusableControl {
     public onTextCutObservable = new Observable<InputText>();
     /** Observable raised when paste event is triggered */
     public onTextPasteObservable = new Observable<InputText>();
+    /** Observable raised when a key event was processed */
+    public onKeyboardEventProcessedObservable = new Observable<KeyboardEvent>();
 
     /** Gets or sets the maximum width allowed by the control */
     public get maxWidth(): string | number {
@@ -183,6 +186,20 @@ export class InputText extends Control implements IFocusableControl {
         this._markAsDirty();
     }
 
+    /** Gets or sets the background color when focused */
+    public get focusedColor(): string {
+        return this._focusedColor;
+    }
+
+    public set focusedColor(value: string) {
+        if (this._focusedColor === value) {
+            return;
+        }
+
+        this._focusedColor = value;
+        this._markAsDirty();
+    }
+
     /** Gets or sets the background color */
     public get background(): string {
         return this._background;
@@ -727,6 +744,8 @@ export class InputText extends Control implements IFocusableControl {
     public processKeyboard(evt: KeyboardEvent): void {
         // process pressed key
         this.processKey(evt.keyCode, evt.key, evt);
+
+        this.onKeyboardEventProcessedObservable.notifyObservers(evt);
     }
 
     /** @hidden */
@@ -829,9 +848,7 @@ export class InputText extends Control implements IFocusableControl {
         let rootY = this._fontOffset.ascent + (this._currentMeasure.height - this._fontOffset.height) / 2;
         let availableWidth = this._width.getValueInPixel(this._host, this._tempParentMeasure.width) - marginWidth;
 
-        if (this._isFocused) {
-            context.save();
-        }
+        context.save();
         context.beginPath();
         context.rect(clipTextLeft, this._currentMeasure.top + (this._currentMeasure.height - this._fontOffset.height) / 2, availableWidth + 2, this._currentMeasure.height);
         context.clip();
@@ -923,20 +940,27 @@ export class InputText extends Control implements IFocusableControl {
                 context.fillRect(highlightCursorLeft, this._currentMeasure.top + (this._currentMeasure.height - this._fontOffset.height) / 2, width, this._fontOffset.height);
                 context.globalAlpha = 1.0;
             }
+        }
+        context.restore();
 
-            context.restore();
-
-            // Border
-            if (this._thickness) {
+        // Border
+        if (this._thickness) {
+            if (this._isFocused) {
+                if (this.focusedColor) {
+                    context.strokeStyle = this.focusedColor;
+                }
+            } else {
                 if (this.color) {
                     context.strokeStyle = this.color;
                 }
-                context.lineWidth = this._thickness;
-
-                context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2,
-                    this._currentMeasure.width - this._thickness, this._currentMeasure.height - this._thickness);
             }
+
+            context.lineWidth = this._thickness;
+
+            context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2,
+                this._currentMeasure.width - this._thickness, this._currentMeasure.height - this._thickness);
         }
+
         context.restore();
     }
 
@@ -994,5 +1018,6 @@ export class InputText extends Control implements IFocusableControl {
         this.onTextCutObservable.clear();
         this.onTextPasteObservable.clear();
         this.onTextHighlightObservable.clear();
+        this.onKeyboardEventProcessedObservable.clear();
     }
 }

+ 2 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/gui/imagePropertyGridComponent.tsx

@@ -27,7 +27,8 @@ export class ImagePropertyGridComponent extends React.Component<IImagePropertyGr
             { label: "None", value: BABYLON.GUI.Image.STRETCH_NONE },
             { label: "Fill", value: BABYLON.GUI.Image.STRETCH_FILL },
             { label: "Uniform", value: BABYLON.GUI.Image.STRETCH_UNIFORM },
-            { label: "Extend", value: BABYLON.GUI.Image.STRETCH_EXTEND }
+            { label: "Extend", value: BABYLON.GUI.Image.STRETCH_EXTEND },
+            { label: "NinePatch", value: BABYLON.GUI.Image.STRETCH_NINE_PATCH }
         ];
 
         return (

+ 1 - 1
package.json

@@ -9,7 +9,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "4.0.0-alpha.10",
+    "version": "4.0.0-alpha.11",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
readme.md

@@ -8,7 +8,7 @@ Getting started? Play directly with the Babylon.js API using our [playground](ht
 [![Percentage of issues still open](https://isitmaintained.com/badge/open/babylonJS/babylon.js.svg)](https://isitmaintained.com/project/babylonJS/babylon.js "Percentage of issues still open")
 [![Build Size](https://img.badgesize.io/BabylonJS/Babylon.js/master/dist/preview%20release/babylon.js.svg?compression=gzip)](https://img.badgesize.io/BabylonJS/Babylon.js/master/dist/preview%20release/babylon.js.svg?compression=gzip)
 
-**Any questions?** Here is our official [forum](http://www.html5gamedevs.com/forum/16-babylonjs/) on www.html5gamedevs.com.
+**Any questions?** Here is our official [forum](https://forum.babylonjs.com/).
 
 ## CDN
 

+ 1 - 1
src/Collisions/pickingInfo.ts

@@ -43,7 +43,7 @@ import { Sprite } from "Sprites/sprite";
         public bu = 0;
         /** (See getTextureCoordinates) The barycentric V coordinate that is used when calulating the texture coordinates of the collision.*/
         public bv = 0;
-        /** The id of the face on the mesh that was picked  */
+        /** The index of the face on the mesh that was picked, or the index of the Line if the picked Mesh is a LinesMesh */
         public faceId = -1;
         /** Id of the the submesh that was picked */
         public subMeshId = 0;

+ 1 - 1
src/Engines/engine.ts

@@ -516,7 +516,7 @@ declare type RenderTargetTexture = import("Materials/Textures/renderTargetTextur
          * Returns the current version of the framework
          */
         public static get Version(): string {
-            return "4.0.0-alpha.10";
+            return "4.0.0-alpha.11";
         }
 
         /**

+ 11 - 0
src/Materials/PBR/pbrBaseMaterial.ts

@@ -1171,6 +1171,17 @@ import "Shaders/pbr.vertex";
 
                         defines.REFLECTIONMAP_3D = reflectionTexture.isCube;
 
+                        defines.REFLECTIONMAP_CUBIC = false;
+                        defines.REFLECTIONMAP_EXPLICIT = false;
+                        defines.REFLECTIONMAP_PLANAR = false;
+                        defines.REFLECTIONMAP_PROJECTION = false;
+                        defines.REFLECTIONMAP_SKYBOX = false;
+                        defines.REFLECTIONMAP_SPHERICAL = false;
+                        defines.REFLECTIONMAP_EQUIRECTANGULAR = false;
+                        defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
+                        defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
+                        defines.REFLECTIONMAP_SKYBOX_TRANSFORMED = false;
+
                         switch (reflectionTexture.coordinatesMode) {
                             case Texture.EXPLICIT_MODE:
                                 defines.REFLECTIONMAP_EXPLICIT = true;

+ 1 - 1
src/Meshes/subMesh.ts

@@ -382,7 +382,7 @@ declare type Mesh = import("./mesh").Mesh;
 
                 if (fastCheck || !intersectInfo || length < intersectInfo.distance) {
                     intersectInfo = new IntersectionInfo(null, null, length);
-
+                    intersectInfo.faceId = index / 2;
                     if (fastCheck) {
                         break;
                     }