David Catuhe 7 年之前
父节点
当前提交
e0e2e8a43f

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


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


+ 290 - 21
dist/preview release/babylon.max.js

@@ -69553,6 +69553,11 @@ var BABYLON;
 //# sourceMappingURL=babylon.touchCamera.js.map
 
 
+
+
+
+
+
 var BABYLON;
 (function (BABYLON) {
     var ProceduralTexture = /** @class */ (function (_super) {
@@ -69705,6 +69710,9 @@ var BABYLON;
             }
             this.releaseInternalTexture();
             this._texture = this._engine.createRenderTargetTexture(size, generateMipMaps);
+            // Update properties
+            this._size = size;
+            this._generateMipMaps = generateMipMaps;
         };
         ProceduralTexture.prototype._checkUniform = function (uniformName) {
             if (this._uniforms.indexOf(uniformName) === -1) {
@@ -69858,6 +69866,18 @@ var BABYLON;
             }
             _super.prototype.dispose.call(this);
         };
+        __decorate([
+            BABYLON.serialize()
+        ], ProceduralTexture.prototype, "_size", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], ProceduralTexture.prototype, "_generateMipMaps", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], ProceduralTexture.prototype, "isEnabled", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], ProceduralTexture.prototype, "refreshRate", null);
         return ProceduralTexture;
     }(BABYLON.Texture));
     BABYLON.ProceduralTexture = ProceduralTexture;
@@ -87789,6 +87809,10 @@ var BABYLON;
                     if (!prePointerInfo.skipOnPointerObservable) {
                         _this.utilityLayerScene.onPointerObservable.notifyObservers(new BABYLON.PointerInfo(prePointerInfo.type, prePointerInfo.event, utilityScenePick));
                     }
+                    var pointerEvent = (prePointerInfo.event);
+                    if (prePointerInfo.type === BABYLON.PointerEventTypes.POINTERUP && _this._pointerCaptures[pointerEvent.pointerId]) {
+                        _this._pointerCaptures[pointerEvent.pointerId] = false;
+                    }
                     return;
                 }
                 if (_this.utilityLayerScene.autoClearDepthAndStencil) {
@@ -87887,13 +87911,20 @@ var BABYLON;
     var PointerDragBehavior = /** @class */ (function () {
         /**
          * Creates a pointer drag behavior that can be attached to a mesh
-         * @param options The drag axis or normal of the plane that will be dragged across.
+         * @param options The drag axis or normal of the plane that will be dragged across. If no options are specified the drag plane will always face the ray's origin (eg. camera)
          */
         function PointerDragBehavior(options) {
             this.options = options;
             this._draggingID = -1;
+            // Debug mode will display drag planes to help visualize behavior
+            this._debugMode = false;
+            this._maxDragAngle = Math.PI / 5;
             /**
              *  Fires each time the attached mesh is dragged with the pointer
+             *  * delta between last drag position and current drag position in world space
+             *  * dragDistance along the drag axis
+             *  * dragPlaneNormal normal of the current drag plane used during the drag
+             *  * dragPlanePoint in world space where the drag intersects the drag plane
              */
             this.onDragObservable = new BABYLON.Observable();
             /**
@@ -87917,6 +87948,9 @@ var BABYLON;
              */
             this.enabled = true;
             var optionCount = 0;
+            if (options === undefined) {
+                options = {};
+            }
             if (options.dragAxis) {
                 optionCount++;
             }
@@ -87926,9 +87960,6 @@ var BABYLON;
             if (optionCount > 1) {
                 throw "Multiple drag modes specified in dragBehavior options. Only one expected";
             }
-            if (optionCount < 1) {
-                throw "At least one drag mode option must be specified";
-            }
         }
         Object.defineProperty(PointerDragBehavior.prototype, "name", {
             /**
@@ -87954,14 +87985,20 @@ var BABYLON;
             this._attachedNode = ownerNode;
             // Initialize drag plane to not interfere with existing scene
             if (!PointerDragBehavior._planeScene) {
-                PointerDragBehavior._planeScene = new BABYLON.Scene(this._scene.getEngine());
-                this._scene.getEngine().scenes.pop();
+                if (this._debugMode) {
+                    PointerDragBehavior._planeScene = this._scene;
+                }
+                else {
+                    PointerDragBehavior._planeScene = new BABYLON.Scene(this._scene.getEngine());
+                    this._scene.getEngine().scenes.pop();
+                }
             }
-            this._dragPlane = BABYLON.Mesh.CreatePlane("pointerDragPlane", 1000, PointerDragBehavior._planeScene, false, BABYLON.Mesh.DOUBLESIDE);
+            this._dragPlane = BABYLON.Mesh.CreatePlane("pointerDragPlane", this._debugMode ? 1 : 10000, PointerDragBehavior._planeScene, false, BABYLON.Mesh.DOUBLESIDE);
             // State of the drag
             var dragging = false;
             var lastPosition = new BABYLON.Vector3(0, 0, 0);
             var delta = new BABYLON.Vector3(0, 0, 0);
+            var dragLength = 0;
             var pickPredicate = function (m) {
                 return _this._attachedNode == m || m.isDescendantOf(_this._attachedNode);
             };
@@ -87991,21 +88028,28 @@ var BABYLON;
                 else if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE) {
                     if (_this._draggingID == pointerInfo.event.pointerId && dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray) {
                         var pickedPoint = _this._pickWithRayOnDragPlane(pointerInfo.pickInfo.ray);
-                        _this._updateDragPlanePosition(pointerInfo.pickInfo.ray);
+                        // Get angle between drag plane and ray. Only update the drag plane at non steep angles to avoid jumps in delta position
+                        var angle = Math.acos(BABYLON.Vector3.Dot(_this._dragPlane.forward, pointerInfo.pickInfo.ray.direction));
+                        if (angle < _this._maxDragAngle) {
+                            _this._updateDragPlanePosition(pointerInfo.pickInfo.ray);
+                        }
                         if (pickedPoint) {
                             // depending on the drag mode option drag accordingly
                             if (_this.options.dragAxis) {
-                                //get the closest point on the dragaxis from the selected mesh to the picked point location
-                                // https://www.opengl.org/discussion_boards/showthread.php/159717-Closest-point-on-a-Vector-to-a-point
-                                _this.options.dragAxis.scaleToRef(BABYLON.Vector3.Dot(pickedPoint.subtract(lastPosition), _this.options.dragAxis), delta);
+                                // Convert local drag axis to world
+                                var worldDragAxis = BABYLON.Vector3.TransformCoordinates(_this.options.dragAxis, _this._attachedNode.getWorldMatrix().getRotationMatrix());
+                                // Project delta drag from the drag plane onto the drag axis
+                                dragLength = BABYLON.Vector3.Dot(pickedPoint.subtract(lastPosition), worldDragAxis);
+                                worldDragAxis.scaleToRef(dragLength, delta);
                             }
                             else {
+                                dragLength = delta.length();
                                 pickedPoint.subtractToRef(lastPosition, delta);
                             }
                             if (_this.moveAttached) {
                                 _this._attachedNode.position.addInPlace(delta);
                             }
-                            _this.onDragObservable.notifyObservers({ delta: delta, dragPlanePoint: pickedPoint });
+                            _this.onDragObservable.notifyObservers({ dragDistance: dragLength, delta: delta, dragPlanePoint: pickedPoint, dragPlaneNormal: _this._dragPlane.forward });
                             lastPosition.copyFrom(pickedPoint);
                         }
                     }
@@ -88027,12 +88071,12 @@ var BABYLON;
         };
         // Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera
         PointerDragBehavior.prototype._updateDragPlanePosition = function (ray) {
-            var pointA = this._dragPlaneParent ? this._dragPlaneParent.position : this._attachedNode.position; // center
+            var pointA = this._dragPlaneParent ? this._dragPlaneParent.absolutePosition : this._attachedNode.absolutePosition;
             if (this.options.dragAxis) {
-                var camPos = ray.origin;
+                var localAxis = BABYLON.Vector3.TransformCoordinates(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix());
                 // Calculate plane normal in direction of camera but perpendicular to drag axis
-                var pointB = pointA.add(this.options.dragAxis); // towards drag axis
-                var pointC = pointA.add(camPos.subtract(pointA).normalize()); // towards camera
+                var pointB = pointA.add(localAxis); // towards drag axis
+                var pointC = pointA.add(ray.origin.subtract(pointA).normalize()); // towards camera
                 // Get perpendicular line from direction to camera and drag axis
                 var lineA = pointB.subtract(pointA);
                 var lineB = pointC.subtract(pointA);
@@ -88040,11 +88084,15 @@ var BABYLON;
                 // Get perpendicular line from previous result and drag axis to adjust lineB to be perpendiculat to camera
                 var norm = BABYLON.Vector3.Cross(lineA, perpLine).normalize();
                 this._dragPlane.position.copyFrom(pointA);
-                this._dragPlane.lookAt(pointA.add(norm));
+                this._dragPlane.lookAt(pointA.subtract(norm));
             }
             else if (this.options.dragPlaneNormal) {
                 this._dragPlane.position.copyFrom(pointA);
-                this._dragPlane.lookAt(pointA.add(this.options.dragPlaneNormal));
+                this._dragPlane.lookAt(pointA.subtract(this.options.dragPlaneNormal));
+            }
+            else {
+                this._dragPlane.position.copyFrom(pointA);
+                this._dragPlane.lookAt(ray.origin);
             }
             this._dragPlane.computeWorldMatrix(true);
         };
@@ -88076,10 +88124,14 @@ var BABYLON;
         function Gizmo(/** The utility layer the gizmo will be added to */ gizmoLayer) {
             var _this = this;
             this.gizmoLayer = gizmoLayer;
+            /**
+             * When set, the gizmo will always appear the same size no matter where the camera is (default: false)
+             */
+            this._updateScale = true;
             this._interactionsEnabled = true;
             this._rootMesh = new BABYLON.Mesh("gizmoRootNode", gizmoLayer.utilityLayerScene);
             this._beforeRenderObserver = this.gizmoLayer.utilityLayerScene.onBeforeRenderObservable.add(function () {
-                if (_this.gizmoLayer.utilityLayerScene.activeCamera && _this.attachedMesh) {
+                if (_this._updateScale && _this.gizmoLayer.utilityLayerScene.activeCamera && _this.attachedMesh) {
                     var dist = _this.attachedMesh.position.subtract(_this.gizmoLayer.utilityLayerScene.activeCamera.position).length() / 3;
                     _this._rootMesh.scaling.set(dist, dist, dist);
                 }
@@ -88155,7 +88207,7 @@ var BABYLON;
             arrowTail.position.z += 0.2;
             _this._rootMesh.lookAt(_this._rootMesh.position.subtract(dragAxis));
             // Add drag behavior to handle events when the gizmo is dragged
-            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis });
+            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: new BABYLON.Vector3(0, 0, 1) });
             _this._dragBehavior.moveAttached = false;
             _this._rootMesh.addBehavior(_this._dragBehavior);
             _this._dragBehavior.onDragObservable.add(function (event) {
@@ -88220,7 +88272,7 @@ var BABYLON;
             arrowTail.position.z += 0.2;
             _this._rootMesh.lookAt(_this._rootMesh.position.subtract(dragAxis));
             // Add drag behavior to handle events when the gizmo is dragged
-            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis });
+            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: new BABYLON.Vector3(0, 0, 1) });
             _this._dragBehavior.moveAttached = false;
             _this._rootMesh.addBehavior(_this._dragBehavior);
             _this._dragBehavior.onDragObservable.add(function (event) {
@@ -88485,6 +88537,223 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.scaleGizmo.js.map
 
+
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Bounding box gizmo
+     */
+    var BoundingBoxGizmo = /** @class */ (function (_super) {
+        __extends(BoundingBoxGizmo, _super);
+        /**
+         * Creates an BoundingBoxGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param color The color of the gizmo
+         */
+        function BoundingBoxGizmo(gizmoLayer, color) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            _this._boundingDimensions = new BABYLON.Vector3(1, 1, 1);
+            _this._renderObserver = null;
+            // Do not update the gizmo's scale so it has a fixed size to the object its attached to
+            _this._updateScale = false;
+            // Create Material
+            var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            coloredMaterial.disableLighting = true;
+            coloredMaterial.emissiveColor = color;
+            // Build bounding box out of lines
+            _this._lineBoundingBox = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
+            _this._lineBoundingBox.rotationQuaternion = new BABYLON.Quaternion();
+            var lines = [];
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(_this._boundingDimensions.x, 0, 0)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, _this._boundingDimensions.y, 0)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 0, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(_this._boundingDimensions.x, 0, 0), new BABYLON.Vector3(_this._boundingDimensions.x, _this._boundingDimensions.y, 0)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(_this._boundingDimensions.x, 0, 0), new BABYLON.Vector3(_this._boundingDimensions.x, 0, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, _this._boundingDimensions.y, 0), new BABYLON.Vector3(_this._boundingDimensions.x, _this._boundingDimensions.y, 0)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, _this._boundingDimensions.y, 0), new BABYLON.Vector3(0, _this._boundingDimensions.y, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, 0, _this._boundingDimensions.z), new BABYLON.Vector3(_this._boundingDimensions.x, 0, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, 0, _this._boundingDimensions.z), new BABYLON.Vector3(0, _this._boundingDimensions.y, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(_this._boundingDimensions.x, _this._boundingDimensions.y, _this._boundingDimensions.z), new BABYLON.Vector3(0, _this._boundingDimensions.y, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(_this._boundingDimensions.x, _this._boundingDimensions.y, _this._boundingDimensions.z), new BABYLON.Vector3(_this._boundingDimensions.x, 0, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(_this._boundingDimensions.x, _this._boundingDimensions.y, _this._boundingDimensions.z), new BABYLON.Vector3(_this._boundingDimensions.x, _this._boundingDimensions.y, 0)] }, gizmoLayer.utilityLayerScene));
+            lines.forEach(function (l) {
+                l.color = color;
+                l.position.addInPlace(new BABYLON.Vector3(-_this._boundingDimensions.x / 2, -_this._boundingDimensions.y / 2, -_this._boundingDimensions.z / 2));
+                l.isPickable = false;
+                _this._lineBoundingBox.addChild(l);
+            });
+            _this._rootMesh.addChild(_this._lineBoundingBox);
+            // Create rotation spheres
+            _this._rotateSpheresParent = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
+            _this._rotateSpheresParent.rotationQuaternion = new BABYLON.Quaternion();
+            var _loop_1 = function (i_1) {
+                var sphere = BABYLON.MeshBuilder.CreateSphere("", { diameter: 0.1 }, gizmoLayer.utilityLayerScene);
+                sphere.rotationQuaternion = new BABYLON.Quaternion();
+                sphere.material = coloredMaterial;
+                // Drag behavior
+                _dragBehavior = new BABYLON.PointerDragBehavior({});
+                _dragBehavior.moveAttached = false;
+                sphere.addBehavior(_dragBehavior);
+                _dragBehavior.onDragObservable.add(function (event) {
+                    if (_this.attachedMesh) {
+                        var worldDragDirection = sphere.forward;
+                        // Project the world right on to the drag plane
+                        var toSub = event.dragPlaneNormal.scale(BABYLON.Vector3.Dot(event.dragPlaneNormal, worldDragDirection));
+                        var dragAxis = worldDragDirection.subtract(toSub).normalizeToNew();
+                        // project drag delta on to the resulting drag axis and rotate based on that
+                        var projectDist = BABYLON.Vector3.Dot(dragAxis, event.delta);
+                        // Rotate based on axis
+                        if (i_1 >= 8) {
+                            _this.attachedMesh.rotation.z -= projectDist;
+                        }
+                        else if (i_1 >= 4) {
+                            _this.attachedMesh.rotation.y -= projectDist;
+                        }
+                        else {
+                            _this.attachedMesh.rotation.x -= projectDist;
+                        }
+                    }
+                });
+                // Selection/deselection
+                _dragBehavior.onDragStartObservable.add(function () {
+                    _this._selectNode(sphere);
+                });
+                _dragBehavior.onDragEndObservable.add(function () {
+                    _this._selectNode(null);
+                });
+                this_1._rotateSpheresParent.addChild(sphere);
+            };
+            var this_1 = this, _dragBehavior;
+            for (var i_1 = 0; i_1 < 12; i_1++) {
+                _loop_1(i_1);
+            }
+            _this._rootMesh.addChild(_this._rotateSpheresParent);
+            // Create scale cubes
+            _this._scaleBoxesParent = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
+            _this._scaleBoxesParent.rotationQuaternion = new BABYLON.Quaternion();
+            for (var i = 0; i < 2; i++) {
+                for (var j = 0; j < 2; j++) {
+                    var _loop_2 = function () {
+                        var box = BABYLON.MeshBuilder.CreateBox("", { size: 0.1 }, gizmoLayer.utilityLayerScene);
+                        box.material = coloredMaterial;
+                        // Dragging logic
+                        var dragAxis = new BABYLON.Vector3(i == 0 ? -1 : 1, j == 0 ? -1 : 1, k == 0 ? -1 : 1);
+                        _dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis });
+                        _dragBehavior.moveAttached = false;
+                        box.addBehavior(_dragBehavior);
+                        _dragBehavior.onDragObservable.add(function (event) {
+                            if (_this.attachedMesh) {
+                                // Current boudning box dimensions
+                                var boundingInfo = _this.attachedMesh.getBoundingInfo().boundingBox;
+                                var boundBoxDimensions = boundingInfo.maximum.subtract(boundingInfo.minimum).multiplyInPlace(_this.attachedMesh.scaling);
+                                // Get the change in bounding box size/2 and add this to the mesh's position to offset from scaling with center pivot point
+                                var deltaScale = new BABYLON.Vector3(event.dragDistance, event.dragDistance, event.dragDistance);
+                                var scaleRatio = deltaScale.divide(_this.attachedMesh.scaling).scaleInPlace(0.5);
+                                var moveDirection = boundBoxDimensions.multiply(scaleRatio).multiplyInPlace(dragAxis);
+                                var worldMoveDirection = BABYLON.Vector3.TransformCoordinates(moveDirection, _this.attachedMesh.getWorldMatrix().getRotationMatrix());
+                                // Update scale and position
+                                _this.attachedMesh.scaling.addInPlace(deltaScale);
+                                _this.attachedMesh.position.addInPlace(worldMoveDirection);
+                            }
+                        });
+                        // Selection/deselection
+                        _dragBehavior.onDragStartObservable.add(function () {
+                            _this._selectNode(box);
+                        });
+                        _dragBehavior.onDragEndObservable.add(function () {
+                            _this._selectNode(null);
+                        });
+                        this_2._scaleBoxesParent.addChild(box);
+                    };
+                    var this_2 = this, _dragBehavior;
+                    for (var k = 0; k < 2; k++) {
+                        _loop_2();
+                    }
+                }
+            }
+            _this._rootMesh.addChild(_this._scaleBoxesParent);
+            // Update bounding box positions
+            _this._renderObserver = _this.gizmoLayer.originalScene.onBeforeRenderObservable.add(function () {
+                _this._updateBoundingBox();
+            });
+            _this._updateBoundingBox();
+            return _this;
+        }
+        BoundingBoxGizmo.prototype._selectNode = function (selectedMesh) {
+            this._rotateSpheresParent.getChildMeshes()
+                .concat(this._scaleBoxesParent.getChildMeshes()).forEach(function (m, i) {
+                m.isVisible = (!selectedMesh || m == selectedMesh);
+            });
+        };
+        BoundingBoxGizmo.prototype._updateBoundingBox = function () {
+            if (this.attachedMesh) {
+                // Update bounding dimensions/positions
+                var boundingInfo = this.attachedMesh.getBoundingInfo().boundingBox;
+                var boundBoxDimensions = boundingInfo.maximum.subtract(boundingInfo.minimum).multiplyInPlace(this.attachedMesh.scaling);
+                this._boundingDimensions.copyFrom(boundBoxDimensions);
+                this._lineBoundingBox.scaling.copyFrom(this._boundingDimensions);
+                if (!this.attachedMesh.rotationQuaternion) {
+                    this.attachedMesh.rotationQuaternion = new BABYLON.Quaternion();
+                }
+                this._lineBoundingBox.rotationQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+                this._rotateSpheresParent.rotationQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+                this._scaleBoxesParent.rotationQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+            }
+            // Update rotation sphere locations
+            var rotateSpheres = this._rotateSpheresParent.getChildMeshes();
+            for (var i = 0; i < 3; i++) {
+                for (var j = 0; j < 2; j++) {
+                    for (var k = 0; k < 2; k++) {
+                        var index = ((i * 4) + (j * 2)) + k;
+                        if (i == 0) {
+                            rotateSpheres[index].position.set(this._boundingDimensions.x / 2, this._boundingDimensions.y * j, this._boundingDimensions.z * k);
+                            rotateSpheres[index].position.addInPlace(new BABYLON.Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
+                            rotateSpheres[index].lookAt(BABYLON.Vector3.Cross(BABYLON.Vector3.Right(), rotateSpheres[index].position.normalizeToNew()).normalizeToNew().add(rotateSpheres[index].position));
+                        }
+                        if (i == 1) {
+                            rotateSpheres[index].position.set(this._boundingDimensions.x * j, this._boundingDimensions.y / 2, this._boundingDimensions.z * k);
+                            rotateSpheres[index].position.addInPlace(new BABYLON.Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
+                            rotateSpheres[index].lookAt(BABYLON.Vector3.Cross(BABYLON.Vector3.Up(), rotateSpheres[index].position.normalizeToNew()).normalizeToNew().add(rotateSpheres[index].position));
+                        }
+                        if (i == 2) {
+                            rotateSpheres[index].position.set(this._boundingDimensions.x * j, this._boundingDimensions.y * k, this._boundingDimensions.z / 2);
+                            rotateSpheres[index].position.addInPlace(new BABYLON.Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
+                            rotateSpheres[index].lookAt(BABYLON.Vector3.Cross(BABYLON.Vector3.Forward(), rotateSpheres[index].position.normalizeToNew()).normalizeToNew().add(rotateSpheres[index].position));
+                        }
+                    }
+                }
+            }
+            // Update scale box locations
+            var scaleBoxes = this._scaleBoxesParent.getChildMeshes();
+            for (var i = 0; i < 2; i++) {
+                for (var j = 0; j < 2; j++) {
+                    for (var k = 0; k < 2; k++) {
+                        var index = ((i * 4) + (j * 2)) + k;
+                        if (scaleBoxes[index]) {
+                            scaleBoxes[index].position.set(this._boundingDimensions.x * i, this._boundingDimensions.y * j, this._boundingDimensions.z * k);
+                            scaleBoxes[index].position.addInPlace(new BABYLON.Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
+                        }
+                    }
+                }
+            }
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        BoundingBoxGizmo.prototype.dispose = function () {
+            this.gizmoLayer.originalScene.onBeforeRenderObservable.remove(this._renderObserver);
+            this._lineBoundingBox.dispose();
+            this._rotateSpheresParent.dispose();
+            this._scaleBoxesParent.dispose();
+            _super.prototype.dispose.call(this);
+        };
+        return BoundingBoxGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.BoundingBoxGizmo = BoundingBoxGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.boundingBoxGizmo.js.map
+
 var BABYLON;
 (function (BABYLON) {
     /**

+ 290 - 21
dist/preview release/babylon.no-module.max.js

@@ -69520,6 +69520,11 @@ var BABYLON;
 //# sourceMappingURL=babylon.touchCamera.js.map
 
 
+
+
+
+
+
 var BABYLON;
 (function (BABYLON) {
     var ProceduralTexture = /** @class */ (function (_super) {
@@ -69672,6 +69677,9 @@ var BABYLON;
             }
             this.releaseInternalTexture();
             this._texture = this._engine.createRenderTargetTexture(size, generateMipMaps);
+            // Update properties
+            this._size = size;
+            this._generateMipMaps = generateMipMaps;
         };
         ProceduralTexture.prototype._checkUniform = function (uniformName) {
             if (this._uniforms.indexOf(uniformName) === -1) {
@@ -69825,6 +69833,18 @@ var BABYLON;
             }
             _super.prototype.dispose.call(this);
         };
+        __decorate([
+            BABYLON.serialize()
+        ], ProceduralTexture.prototype, "_size", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], ProceduralTexture.prototype, "_generateMipMaps", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], ProceduralTexture.prototype, "isEnabled", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], ProceduralTexture.prototype, "refreshRate", null);
         return ProceduralTexture;
     }(BABYLON.Texture));
     BABYLON.ProceduralTexture = ProceduralTexture;
@@ -87756,6 +87776,10 @@ var BABYLON;
                     if (!prePointerInfo.skipOnPointerObservable) {
                         _this.utilityLayerScene.onPointerObservable.notifyObservers(new BABYLON.PointerInfo(prePointerInfo.type, prePointerInfo.event, utilityScenePick));
                     }
+                    var pointerEvent = (prePointerInfo.event);
+                    if (prePointerInfo.type === BABYLON.PointerEventTypes.POINTERUP && _this._pointerCaptures[pointerEvent.pointerId]) {
+                        _this._pointerCaptures[pointerEvent.pointerId] = false;
+                    }
                     return;
                 }
                 if (_this.utilityLayerScene.autoClearDepthAndStencil) {
@@ -87854,13 +87878,20 @@ var BABYLON;
     var PointerDragBehavior = /** @class */ (function () {
         /**
          * Creates a pointer drag behavior that can be attached to a mesh
-         * @param options The drag axis or normal of the plane that will be dragged across.
+         * @param options The drag axis or normal of the plane that will be dragged across. If no options are specified the drag plane will always face the ray's origin (eg. camera)
          */
         function PointerDragBehavior(options) {
             this.options = options;
             this._draggingID = -1;
+            // Debug mode will display drag planes to help visualize behavior
+            this._debugMode = false;
+            this._maxDragAngle = Math.PI / 5;
             /**
              *  Fires each time the attached mesh is dragged with the pointer
+             *  * delta between last drag position and current drag position in world space
+             *  * dragDistance along the drag axis
+             *  * dragPlaneNormal normal of the current drag plane used during the drag
+             *  * dragPlanePoint in world space where the drag intersects the drag plane
              */
             this.onDragObservable = new BABYLON.Observable();
             /**
@@ -87884,6 +87915,9 @@ var BABYLON;
              */
             this.enabled = true;
             var optionCount = 0;
+            if (options === undefined) {
+                options = {};
+            }
             if (options.dragAxis) {
                 optionCount++;
             }
@@ -87893,9 +87927,6 @@ var BABYLON;
             if (optionCount > 1) {
                 throw "Multiple drag modes specified in dragBehavior options. Only one expected";
             }
-            if (optionCount < 1) {
-                throw "At least one drag mode option must be specified";
-            }
         }
         Object.defineProperty(PointerDragBehavior.prototype, "name", {
             /**
@@ -87921,14 +87952,20 @@ var BABYLON;
             this._attachedNode = ownerNode;
             // Initialize drag plane to not interfere with existing scene
             if (!PointerDragBehavior._planeScene) {
-                PointerDragBehavior._planeScene = new BABYLON.Scene(this._scene.getEngine());
-                this._scene.getEngine().scenes.pop();
+                if (this._debugMode) {
+                    PointerDragBehavior._planeScene = this._scene;
+                }
+                else {
+                    PointerDragBehavior._planeScene = new BABYLON.Scene(this._scene.getEngine());
+                    this._scene.getEngine().scenes.pop();
+                }
             }
-            this._dragPlane = BABYLON.Mesh.CreatePlane("pointerDragPlane", 1000, PointerDragBehavior._planeScene, false, BABYLON.Mesh.DOUBLESIDE);
+            this._dragPlane = BABYLON.Mesh.CreatePlane("pointerDragPlane", this._debugMode ? 1 : 10000, PointerDragBehavior._planeScene, false, BABYLON.Mesh.DOUBLESIDE);
             // State of the drag
             var dragging = false;
             var lastPosition = new BABYLON.Vector3(0, 0, 0);
             var delta = new BABYLON.Vector3(0, 0, 0);
+            var dragLength = 0;
             var pickPredicate = function (m) {
                 return _this._attachedNode == m || m.isDescendantOf(_this._attachedNode);
             };
@@ -87958,21 +87995,28 @@ var BABYLON;
                 else if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE) {
                     if (_this._draggingID == pointerInfo.event.pointerId && dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray) {
                         var pickedPoint = _this._pickWithRayOnDragPlane(pointerInfo.pickInfo.ray);
-                        _this._updateDragPlanePosition(pointerInfo.pickInfo.ray);
+                        // Get angle between drag plane and ray. Only update the drag plane at non steep angles to avoid jumps in delta position
+                        var angle = Math.acos(BABYLON.Vector3.Dot(_this._dragPlane.forward, pointerInfo.pickInfo.ray.direction));
+                        if (angle < _this._maxDragAngle) {
+                            _this._updateDragPlanePosition(pointerInfo.pickInfo.ray);
+                        }
                         if (pickedPoint) {
                             // depending on the drag mode option drag accordingly
                             if (_this.options.dragAxis) {
-                                //get the closest point on the dragaxis from the selected mesh to the picked point location
-                                // https://www.opengl.org/discussion_boards/showthread.php/159717-Closest-point-on-a-Vector-to-a-point
-                                _this.options.dragAxis.scaleToRef(BABYLON.Vector3.Dot(pickedPoint.subtract(lastPosition), _this.options.dragAxis), delta);
+                                // Convert local drag axis to world
+                                var worldDragAxis = BABYLON.Vector3.TransformCoordinates(_this.options.dragAxis, _this._attachedNode.getWorldMatrix().getRotationMatrix());
+                                // Project delta drag from the drag plane onto the drag axis
+                                dragLength = BABYLON.Vector3.Dot(pickedPoint.subtract(lastPosition), worldDragAxis);
+                                worldDragAxis.scaleToRef(dragLength, delta);
                             }
                             else {
+                                dragLength = delta.length();
                                 pickedPoint.subtractToRef(lastPosition, delta);
                             }
                             if (_this.moveAttached) {
                                 _this._attachedNode.position.addInPlace(delta);
                             }
-                            _this.onDragObservable.notifyObservers({ delta: delta, dragPlanePoint: pickedPoint });
+                            _this.onDragObservable.notifyObservers({ dragDistance: dragLength, delta: delta, dragPlanePoint: pickedPoint, dragPlaneNormal: _this._dragPlane.forward });
                             lastPosition.copyFrom(pickedPoint);
                         }
                     }
@@ -87994,12 +88038,12 @@ var BABYLON;
         };
         // Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera
         PointerDragBehavior.prototype._updateDragPlanePosition = function (ray) {
-            var pointA = this._dragPlaneParent ? this._dragPlaneParent.position : this._attachedNode.position; // center
+            var pointA = this._dragPlaneParent ? this._dragPlaneParent.absolutePosition : this._attachedNode.absolutePosition;
             if (this.options.dragAxis) {
-                var camPos = ray.origin;
+                var localAxis = BABYLON.Vector3.TransformCoordinates(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix());
                 // Calculate plane normal in direction of camera but perpendicular to drag axis
-                var pointB = pointA.add(this.options.dragAxis); // towards drag axis
-                var pointC = pointA.add(camPos.subtract(pointA).normalize()); // towards camera
+                var pointB = pointA.add(localAxis); // towards drag axis
+                var pointC = pointA.add(ray.origin.subtract(pointA).normalize()); // towards camera
                 // Get perpendicular line from direction to camera and drag axis
                 var lineA = pointB.subtract(pointA);
                 var lineB = pointC.subtract(pointA);
@@ -88007,11 +88051,15 @@ var BABYLON;
                 // Get perpendicular line from previous result and drag axis to adjust lineB to be perpendiculat to camera
                 var norm = BABYLON.Vector3.Cross(lineA, perpLine).normalize();
                 this._dragPlane.position.copyFrom(pointA);
-                this._dragPlane.lookAt(pointA.add(norm));
+                this._dragPlane.lookAt(pointA.subtract(norm));
             }
             else if (this.options.dragPlaneNormal) {
                 this._dragPlane.position.copyFrom(pointA);
-                this._dragPlane.lookAt(pointA.add(this.options.dragPlaneNormal));
+                this._dragPlane.lookAt(pointA.subtract(this.options.dragPlaneNormal));
+            }
+            else {
+                this._dragPlane.position.copyFrom(pointA);
+                this._dragPlane.lookAt(ray.origin);
             }
             this._dragPlane.computeWorldMatrix(true);
         };
@@ -88043,10 +88091,14 @@ var BABYLON;
         function Gizmo(/** The utility layer the gizmo will be added to */ gizmoLayer) {
             var _this = this;
             this.gizmoLayer = gizmoLayer;
+            /**
+             * When set, the gizmo will always appear the same size no matter where the camera is (default: false)
+             */
+            this._updateScale = true;
             this._interactionsEnabled = true;
             this._rootMesh = new BABYLON.Mesh("gizmoRootNode", gizmoLayer.utilityLayerScene);
             this._beforeRenderObserver = this.gizmoLayer.utilityLayerScene.onBeforeRenderObservable.add(function () {
-                if (_this.gizmoLayer.utilityLayerScene.activeCamera && _this.attachedMesh) {
+                if (_this._updateScale && _this.gizmoLayer.utilityLayerScene.activeCamera && _this.attachedMesh) {
                     var dist = _this.attachedMesh.position.subtract(_this.gizmoLayer.utilityLayerScene.activeCamera.position).length() / 3;
                     _this._rootMesh.scaling.set(dist, dist, dist);
                 }
@@ -88122,7 +88174,7 @@ var BABYLON;
             arrowTail.position.z += 0.2;
             _this._rootMesh.lookAt(_this._rootMesh.position.subtract(dragAxis));
             // Add drag behavior to handle events when the gizmo is dragged
-            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis });
+            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: new BABYLON.Vector3(0, 0, 1) });
             _this._dragBehavior.moveAttached = false;
             _this._rootMesh.addBehavior(_this._dragBehavior);
             _this._dragBehavior.onDragObservable.add(function (event) {
@@ -88187,7 +88239,7 @@ var BABYLON;
             arrowTail.position.z += 0.2;
             _this._rootMesh.lookAt(_this._rootMesh.position.subtract(dragAxis));
             // Add drag behavior to handle events when the gizmo is dragged
-            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis });
+            _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: new BABYLON.Vector3(0, 0, 1) });
             _this._dragBehavior.moveAttached = false;
             _this._rootMesh.addBehavior(_this._dragBehavior);
             _this._dragBehavior.onDragObservable.add(function (event) {
@@ -88452,6 +88504,223 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.scaleGizmo.js.map
 
+
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Bounding box gizmo
+     */
+    var BoundingBoxGizmo = /** @class */ (function (_super) {
+        __extends(BoundingBoxGizmo, _super);
+        /**
+         * Creates an BoundingBoxGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param color The color of the gizmo
+         */
+        function BoundingBoxGizmo(gizmoLayer, color) {
+            var _this = _super.call(this, gizmoLayer) || this;
+            _this._boundingDimensions = new BABYLON.Vector3(1, 1, 1);
+            _this._renderObserver = null;
+            // Do not update the gizmo's scale so it has a fixed size to the object its attached to
+            _this._updateScale = false;
+            // Create Material
+            var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            coloredMaterial.disableLighting = true;
+            coloredMaterial.emissiveColor = color;
+            // Build bounding box out of lines
+            _this._lineBoundingBox = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
+            _this._lineBoundingBox.rotationQuaternion = new BABYLON.Quaternion();
+            var lines = [];
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(_this._boundingDimensions.x, 0, 0)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, _this._boundingDimensions.y, 0)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 0, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(_this._boundingDimensions.x, 0, 0), new BABYLON.Vector3(_this._boundingDimensions.x, _this._boundingDimensions.y, 0)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(_this._boundingDimensions.x, 0, 0), new BABYLON.Vector3(_this._boundingDimensions.x, 0, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, _this._boundingDimensions.y, 0), new BABYLON.Vector3(_this._boundingDimensions.x, _this._boundingDimensions.y, 0)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, _this._boundingDimensions.y, 0), new BABYLON.Vector3(0, _this._boundingDimensions.y, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, 0, _this._boundingDimensions.z), new BABYLON.Vector3(_this._boundingDimensions.x, 0, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(0, 0, _this._boundingDimensions.z), new BABYLON.Vector3(0, _this._boundingDimensions.y, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(_this._boundingDimensions.x, _this._boundingDimensions.y, _this._boundingDimensions.z), new BABYLON.Vector3(0, _this._boundingDimensions.y, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(_this._boundingDimensions.x, _this._boundingDimensions.y, _this._boundingDimensions.z), new BABYLON.Vector3(_this._boundingDimensions.x, 0, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
+            lines.push(BABYLON.MeshBuilder.CreateLines("lines", { points: [new BABYLON.Vector3(_this._boundingDimensions.x, _this._boundingDimensions.y, _this._boundingDimensions.z), new BABYLON.Vector3(_this._boundingDimensions.x, _this._boundingDimensions.y, 0)] }, gizmoLayer.utilityLayerScene));
+            lines.forEach(function (l) {
+                l.color = color;
+                l.position.addInPlace(new BABYLON.Vector3(-_this._boundingDimensions.x / 2, -_this._boundingDimensions.y / 2, -_this._boundingDimensions.z / 2));
+                l.isPickable = false;
+                _this._lineBoundingBox.addChild(l);
+            });
+            _this._rootMesh.addChild(_this._lineBoundingBox);
+            // Create rotation spheres
+            _this._rotateSpheresParent = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
+            _this._rotateSpheresParent.rotationQuaternion = new BABYLON.Quaternion();
+            var _loop_1 = function (i_1) {
+                var sphere = BABYLON.MeshBuilder.CreateSphere("", { diameter: 0.1 }, gizmoLayer.utilityLayerScene);
+                sphere.rotationQuaternion = new BABYLON.Quaternion();
+                sphere.material = coloredMaterial;
+                // Drag behavior
+                _dragBehavior = new BABYLON.PointerDragBehavior({});
+                _dragBehavior.moveAttached = false;
+                sphere.addBehavior(_dragBehavior);
+                _dragBehavior.onDragObservable.add(function (event) {
+                    if (_this.attachedMesh) {
+                        var worldDragDirection = sphere.forward;
+                        // Project the world right on to the drag plane
+                        var toSub = event.dragPlaneNormal.scale(BABYLON.Vector3.Dot(event.dragPlaneNormal, worldDragDirection));
+                        var dragAxis = worldDragDirection.subtract(toSub).normalizeToNew();
+                        // project drag delta on to the resulting drag axis and rotate based on that
+                        var projectDist = BABYLON.Vector3.Dot(dragAxis, event.delta);
+                        // Rotate based on axis
+                        if (i_1 >= 8) {
+                            _this.attachedMesh.rotation.z -= projectDist;
+                        }
+                        else if (i_1 >= 4) {
+                            _this.attachedMesh.rotation.y -= projectDist;
+                        }
+                        else {
+                            _this.attachedMesh.rotation.x -= projectDist;
+                        }
+                    }
+                });
+                // Selection/deselection
+                _dragBehavior.onDragStartObservable.add(function () {
+                    _this._selectNode(sphere);
+                });
+                _dragBehavior.onDragEndObservable.add(function () {
+                    _this._selectNode(null);
+                });
+                this_1._rotateSpheresParent.addChild(sphere);
+            };
+            var this_1 = this, _dragBehavior;
+            for (var i_1 = 0; i_1 < 12; i_1++) {
+                _loop_1(i_1);
+            }
+            _this._rootMesh.addChild(_this._rotateSpheresParent);
+            // Create scale cubes
+            _this._scaleBoxesParent = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
+            _this._scaleBoxesParent.rotationQuaternion = new BABYLON.Quaternion();
+            for (var i = 0; i < 2; i++) {
+                for (var j = 0; j < 2; j++) {
+                    var _loop_2 = function () {
+                        var box = BABYLON.MeshBuilder.CreateBox("", { size: 0.1 }, gizmoLayer.utilityLayerScene);
+                        box.material = coloredMaterial;
+                        // Dragging logic
+                        var dragAxis = new BABYLON.Vector3(i == 0 ? -1 : 1, j == 0 ? -1 : 1, k == 0 ? -1 : 1);
+                        _dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis });
+                        _dragBehavior.moveAttached = false;
+                        box.addBehavior(_dragBehavior);
+                        _dragBehavior.onDragObservable.add(function (event) {
+                            if (_this.attachedMesh) {
+                                // Current boudning box dimensions
+                                var boundingInfo = _this.attachedMesh.getBoundingInfo().boundingBox;
+                                var boundBoxDimensions = boundingInfo.maximum.subtract(boundingInfo.minimum).multiplyInPlace(_this.attachedMesh.scaling);
+                                // Get the change in bounding box size/2 and add this to the mesh's position to offset from scaling with center pivot point
+                                var deltaScale = new BABYLON.Vector3(event.dragDistance, event.dragDistance, event.dragDistance);
+                                var scaleRatio = deltaScale.divide(_this.attachedMesh.scaling).scaleInPlace(0.5);
+                                var moveDirection = boundBoxDimensions.multiply(scaleRatio).multiplyInPlace(dragAxis);
+                                var worldMoveDirection = BABYLON.Vector3.TransformCoordinates(moveDirection, _this.attachedMesh.getWorldMatrix().getRotationMatrix());
+                                // Update scale and position
+                                _this.attachedMesh.scaling.addInPlace(deltaScale);
+                                _this.attachedMesh.position.addInPlace(worldMoveDirection);
+                            }
+                        });
+                        // Selection/deselection
+                        _dragBehavior.onDragStartObservable.add(function () {
+                            _this._selectNode(box);
+                        });
+                        _dragBehavior.onDragEndObservable.add(function () {
+                            _this._selectNode(null);
+                        });
+                        this_2._scaleBoxesParent.addChild(box);
+                    };
+                    var this_2 = this, _dragBehavior;
+                    for (var k = 0; k < 2; k++) {
+                        _loop_2();
+                    }
+                }
+            }
+            _this._rootMesh.addChild(_this._scaleBoxesParent);
+            // Update bounding box positions
+            _this._renderObserver = _this.gizmoLayer.originalScene.onBeforeRenderObservable.add(function () {
+                _this._updateBoundingBox();
+            });
+            _this._updateBoundingBox();
+            return _this;
+        }
+        BoundingBoxGizmo.prototype._selectNode = function (selectedMesh) {
+            this._rotateSpheresParent.getChildMeshes()
+                .concat(this._scaleBoxesParent.getChildMeshes()).forEach(function (m, i) {
+                m.isVisible = (!selectedMesh || m == selectedMesh);
+            });
+        };
+        BoundingBoxGizmo.prototype._updateBoundingBox = function () {
+            if (this.attachedMesh) {
+                // Update bounding dimensions/positions
+                var boundingInfo = this.attachedMesh.getBoundingInfo().boundingBox;
+                var boundBoxDimensions = boundingInfo.maximum.subtract(boundingInfo.minimum).multiplyInPlace(this.attachedMesh.scaling);
+                this._boundingDimensions.copyFrom(boundBoxDimensions);
+                this._lineBoundingBox.scaling.copyFrom(this._boundingDimensions);
+                if (!this.attachedMesh.rotationQuaternion) {
+                    this.attachedMesh.rotationQuaternion = new BABYLON.Quaternion();
+                }
+                this._lineBoundingBox.rotationQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+                this._rotateSpheresParent.rotationQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+                this._scaleBoxesParent.rotationQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+            }
+            // Update rotation sphere locations
+            var rotateSpheres = this._rotateSpheresParent.getChildMeshes();
+            for (var i = 0; i < 3; i++) {
+                for (var j = 0; j < 2; j++) {
+                    for (var k = 0; k < 2; k++) {
+                        var index = ((i * 4) + (j * 2)) + k;
+                        if (i == 0) {
+                            rotateSpheres[index].position.set(this._boundingDimensions.x / 2, this._boundingDimensions.y * j, this._boundingDimensions.z * k);
+                            rotateSpheres[index].position.addInPlace(new BABYLON.Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
+                            rotateSpheres[index].lookAt(BABYLON.Vector3.Cross(BABYLON.Vector3.Right(), rotateSpheres[index].position.normalizeToNew()).normalizeToNew().add(rotateSpheres[index].position));
+                        }
+                        if (i == 1) {
+                            rotateSpheres[index].position.set(this._boundingDimensions.x * j, this._boundingDimensions.y / 2, this._boundingDimensions.z * k);
+                            rotateSpheres[index].position.addInPlace(new BABYLON.Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
+                            rotateSpheres[index].lookAt(BABYLON.Vector3.Cross(BABYLON.Vector3.Up(), rotateSpheres[index].position.normalizeToNew()).normalizeToNew().add(rotateSpheres[index].position));
+                        }
+                        if (i == 2) {
+                            rotateSpheres[index].position.set(this._boundingDimensions.x * j, this._boundingDimensions.y * k, this._boundingDimensions.z / 2);
+                            rotateSpheres[index].position.addInPlace(new BABYLON.Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
+                            rotateSpheres[index].lookAt(BABYLON.Vector3.Cross(BABYLON.Vector3.Forward(), rotateSpheres[index].position.normalizeToNew()).normalizeToNew().add(rotateSpheres[index].position));
+                        }
+                    }
+                }
+            }
+            // Update scale box locations
+            var scaleBoxes = this._scaleBoxesParent.getChildMeshes();
+            for (var i = 0; i < 2; i++) {
+                for (var j = 0; j < 2; j++) {
+                    for (var k = 0; k < 2; k++) {
+                        var index = ((i * 4) + (j * 2)) + k;
+                        if (scaleBoxes[index]) {
+                            scaleBoxes[index].position.set(this._boundingDimensions.x * i, this._boundingDimensions.y * j, this._boundingDimensions.z * k);
+                            scaleBoxes[index].position.addInPlace(new BABYLON.Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
+                        }
+                    }
+                }
+            }
+        };
+        /**
+         * Disposes of the gizmo
+         */
+        BoundingBoxGizmo.prototype.dispose = function () {
+            this.gizmoLayer.originalScene.onBeforeRenderObservable.remove(this._renderObserver);
+            this._lineBoundingBox.dispose();
+            this._rotateSpheresParent.dispose();
+            this._scaleBoxesParent.dispose();
+            _super.prototype.dispose.call(this);
+        };
+        return BoundingBoxGizmo;
+    }(BABYLON.Gizmo));
+    BABYLON.BoundingBoxGizmo = BoundingBoxGizmo;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.boundingBoxGizmo.js.map
+
 var BABYLON;
 (function (BABYLON) {
     /**

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


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


+ 13 - 0
dist/preview release/proceduralTexturesLibrary/babylon.brickProceduralTexture.d.ts

@@ -11,5 +11,18 @@ declare module BABYLON {
         numberOfBricksWidth: number;
         jointColor: Color3;
         brickColor: Color3;
+        /**
+         * Serializes this brick procedural texture
+         * @returns a serialized brick procedural texture object
+         */
+        serialize(): any;
+        /**
+         * Creates a Brick Procedural Texture from parsed brick procedural texture data
+         * @param parsedTexture defines parsed texture data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing brick procedural texture information
+         * @returns a parsed Brick Procedural Texture
+         */
+        static Parse(parsedTexture: any, scene: Scene, rootUrl: string): BrickProceduralTexture;
     }
 }

+ 38 - 0
dist/preview release/proceduralTexturesLibrary/babylon.brickProceduralTexture.js

@@ -9,6 +9,12 @@ var __extends = (this && this.__extends) || (function () {
         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
     };
 })();
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
 var BABYLON;
 (function (BABYLON) {
     var BrickProceduralTexture = /** @class */ (function (_super) {
@@ -72,6 +78,38 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+         * Serializes this brick procedural texture
+         * @returns a serialized brick procedural texture object
+         */
+        BrickProceduralTexture.prototype.serialize = function () {
+            var serializationObject = BABYLON.SerializationHelper.Serialize(this, _super.prototype.serialize.call(this));
+            serializationObject.customType = "BABYLON.BrickProceduralTexture";
+            return serializationObject;
+        };
+        /**
+         * Creates a Brick Procedural Texture from parsed brick procedural texture data
+         * @param parsedTexture defines parsed texture data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing brick procedural texture information
+         * @returns a parsed Brick Procedural Texture
+         */
+        BrickProceduralTexture.Parse = function (parsedTexture, scene, rootUrl) {
+            var texture = BABYLON.SerializationHelper.Parse(function () { return new BrickProceduralTexture(parsedTexture.name, parsedTexture._size, scene, undefined, parsedTexture._generateMipMaps); }, parsedTexture, scene, rootUrl);
+            return texture;
+        };
+        __decorate([
+            BABYLON.serialize()
+        ], BrickProceduralTexture.prototype, "numberOfBricksHeight", null);
+        __decorate([
+            BABYLON.serialize()
+        ], BrickProceduralTexture.prototype, "numberOfBricksWidth", null);
+        __decorate([
+            BABYLON.serializeAsColor3()
+        ], BrickProceduralTexture.prototype, "jointColor", null);
+        __decorate([
+            BABYLON.serializeAsColor3()
+        ], BrickProceduralTexture.prototype, "brickColor", null);
         return BrickProceduralTexture;
     }(BABYLON.ProceduralTexture));
     BABYLON.BrickProceduralTexture = BrickProceduralTexture;

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


+ 13 - 0
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.d.ts

@@ -79,6 +79,19 @@ declare module BABYLON {
         numberOfBricksWidth: number;
         jointColor: Color3;
         brickColor: Color3;
+        /**
+         * Serializes this brick procedural texture
+         * @returns a serialized brick procedural texture object
+         */
+        serialize(): any;
+        /**
+         * Creates a Brick Procedural Texture from parsed brick procedural texture data
+         * @param parsedTexture defines parsed texture data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing brick procedural texture information
+         * @returns a parsed Brick Procedural Texture
+         */
+        static Parse(parsedTexture: any, scene: Scene, rootUrl: string): BrickProceduralTexture;
     }
 }
 

+ 33 - 0
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js

@@ -354,6 +354,7 @@ BABYLON.Effect.ShadersStore['roadProceduralTexturePixelShader'] = "precision hig
 
 
 
+
 var BABYLON;
 (function (BABYLON) {
     var BrickProceduralTexture = /** @class */ (function (_super) {
@@ -417,6 +418,38 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+         * Serializes this brick procedural texture
+         * @returns a serialized brick procedural texture object
+         */
+        BrickProceduralTexture.prototype.serialize = function () {
+            var serializationObject = BABYLON.SerializationHelper.Serialize(this, _super.prototype.serialize.call(this));
+            serializationObject.customType = "BABYLON.BrickProceduralTexture";
+            return serializationObject;
+        };
+        /**
+         * Creates a Brick Procedural Texture from parsed brick procedural texture data
+         * @param parsedTexture defines parsed texture data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing brick procedural texture information
+         * @returns a parsed Brick Procedural Texture
+         */
+        BrickProceduralTexture.Parse = function (parsedTexture, scene, rootUrl) {
+            var texture = BABYLON.SerializationHelper.Parse(function () { return new BrickProceduralTexture(parsedTexture.name, parsedTexture._size, scene, undefined, parsedTexture._generateMipMaps); }, parsedTexture, scene, rootUrl);
+            return texture;
+        };
+        __decorate([
+            BABYLON.serialize()
+        ], BrickProceduralTexture.prototype, "numberOfBricksHeight", null);
+        __decorate([
+            BABYLON.serialize()
+        ], BrickProceduralTexture.prototype, "numberOfBricksWidth", null);
+        __decorate([
+            BABYLON.serializeAsColor3()
+        ], BrickProceduralTexture.prototype, "jointColor", null);
+        __decorate([
+            BABYLON.serializeAsColor3()
+        ], BrickProceduralTexture.prototype, "brickColor", null);
         return BrickProceduralTexture;
     }(BABYLON.ProceduralTexture));
     BABYLON.BrickProceduralTexture = BrickProceduralTexture;

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


+ 13 - 0
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.module.d.ts

@@ -84,6 +84,19 @@ declare module BABYLON {
         numberOfBricksWidth: number;
         jointColor: Color3;
         brickColor: Color3;
+        /**
+         * Serializes this brick procedural texture
+         * @returns a serialized brick procedural texture object
+         */
+        serialize(): any;
+        /**
+         * Creates a Brick Procedural Texture from parsed brick procedural texture data
+         * @param parsedTexture defines parsed texture data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing brick procedural texture information
+         * @returns a parsed Brick Procedural Texture
+         */
+        static Parse(parsedTexture: any, scene: Scene, rootUrl: string): BrickProceduralTexture;
     }
 }
 

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


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