Browse Source

initiate move when start drag is called

Trevor Baron 7 years ago
parent
commit
aedc6ca08c
1 changed files with 52 additions and 28 deletions
  1. 52 28
      src/Behaviors/Mesh/babylon.pointerDragBehavior.ts

+ 52 - 28
src/Behaviors/Mesh/babylon.pointerDragBehavior.ts

@@ -138,8 +138,6 @@ module BABYLON {
 
             // State of the drag
             this.lastDragPosition = new BABYLON.Vector3(0,0,0);
-            var delta = new BABYLON.Vector3(0,0,0);
-            var dragLength = 0;
 
             var pickPredicate = (m:AbstractMesh)=>{
                 return this._attachedNode == m || m.isDescendantOf(this._attachedNode)
@@ -153,39 +151,26 @@ module BABYLON {
                 if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERDOWN) {
                     
                     if(!this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.pickedPoint && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)){
-                        this.startDrag((<PointerEvent>pointerInfo.event).pointerId, pointerInfo.pickInfo.ray, pointerInfo.pickInfo.pickedPoint);
+                        this._startDrag((<PointerEvent>pointerInfo.event).pointerId, pointerInfo.pickInfo.ray, pointerInfo.pickInfo.pickedPoint);
                     }
                 }else if(pointerInfo.type == BABYLON.PointerEventTypes.POINTERUP){
                     if(this.currentDraggingPointerID == (<PointerEvent>pointerInfo.event).pointerId){
                         this.releaseDrag();
                     }
                 }else if(pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE){
-                    if(this.currentDraggingPointerID == (<PointerEvent>pointerInfo.event).pointerId && this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray){
-                        this._moving = true;
-                        var pickedPoint = this._pickWithRayOnDragPlane(pointerInfo.pickInfo.ray);
-                        
-                        if (pickedPoint) {
-                            if(this.updateDragPlane){
-                                this._updateDragPlanePosition(pointerInfo.pickInfo.ray, pickedPoint);
-                            }
-                            
-                            // depending on the drag mode option drag accordingly
-                            if(this._options.dragAxis){
-                                // Convert local drag axis to world
-                                Vector3.TransformCoordinatesToRef(this._options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._worldDragAxis);
+                    var pointerId = (<PointerEvent>pointerInfo.event).pointerId;
 
-                                // Project delta drag from the drag plane onto the drag axis
-                                pickedPoint.subtractToRef(this.lastDragPosition, this._tmpVector);
-                                dragLength = BABYLON.Vector3.Dot(this._tmpVector, this._worldDragAxis)
-                                this._worldDragAxis.scaleToRef(dragLength, delta);
-                            }else{
-                                dragLength = delta.length();
-                                pickedPoint.subtractToRef(this.lastDragPosition, delta);
-                            }
-                            this._targetPosition.addInPlace(delta);
-                            this.onDragObservable.notifyObservers({dragDistance: dragLength, delta: delta, dragPlanePoint: pickedPoint, dragPlaneNormal: this._dragPlane.forward, pointerId: this.currentDraggingPointerID});
-                            this.lastDragPosition.copyFrom(pickedPoint);
-                        }
+                    // Keep track of last pointer ray, this is used simulating the start of a drag in startDrag()
+                    if(!this._lastPointerRay[pointerId]){
+                        this._lastPointerRay[pointerId] = new BABYLON.Ray(new BABYLON.Vector3(), new BABYLON.Vector3());
+                    }
+                    if(pointerInfo.pickInfo && pointerInfo.pickInfo.ray){
+                        this._lastPointerRay[pointerId].origin.copyFrom(pointerInfo.pickInfo.ray.origin);
+                        this._lastPointerRay[pointerId].direction.copyFrom(pointerInfo.pickInfo.ray.direction);
+
+                        if(this.currentDraggingPointerID == pointerId && this.dragging){
+                            this._moveDrag(pointerInfo.pickInfo.ray);
+                         }
                     }
                 }
             });
@@ -214,6 +199,7 @@ module BABYLON {
         }
 
         private _startDragRay = new BABYLON.Ray(new BABYLON.Vector3(), new BABYLON.Vector3());
+        private _lastPointerRay:{[key: number]: Ray} = {};
         /**
          * Simulates the start of a pointer drag event on the behavior
          * @param pointerId pointerID of the pointer that should be simulated (Default: 1 for mouse pointer)
@@ -221,6 +207,14 @@ module BABYLON {
          * @param startPickedPoint picked point of the pointer to be simulated (Default: attached mesh position)
          */
         public startDrag(pointerId = 1, fromRay?:Ray, startPickedPoint?:Vector3){
+            this._startDrag(pointerId, fromRay, startPickedPoint);
+            if(this._lastPointerRay[pointerId]){
+                // if there was a last pointer ray drag the object there
+                this._moveDrag(this._lastPointerRay[pointerId]);
+            }
+        }
+
+        private _startDrag(pointerId = 1, fromRay?:Ray, startPickedPoint?:Vector3){
             if(!this._scene.activeCamera || this.dragging || !this._attachedNode){
                 return;
             }
@@ -257,6 +251,36 @@ module BABYLON {
             }
         }
 
+        private _dragDelta = new BABYLON.Vector3();
+        private _moveDrag(ray:Ray){
+            this._moving = true;
+            var pickedPoint = this._pickWithRayOnDragPlane(ray);
+            
+            if (pickedPoint) {
+                if(this.updateDragPlane){
+                    this._updateDragPlanePosition(ray, pickedPoint);
+                }
+                
+                var dragLength = 0;
+                // depending on the drag mode option drag accordingly
+                if(this._options.dragAxis){
+                    // Convert local drag axis to world
+                    Vector3.TransformCoordinatesToRef(this._options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._worldDragAxis);
+
+                    // Project delta drag from the drag plane onto the drag axis
+                    pickedPoint.subtractToRef(this.lastDragPosition, this._tmpVector);
+                    dragLength = BABYLON.Vector3.Dot(this._tmpVector, this._worldDragAxis)
+                    this._worldDragAxis.scaleToRef(dragLength, this._dragDelta);
+                }else{
+                    dragLength = this._dragDelta.length();
+                    pickedPoint.subtractToRef(this.lastDragPosition, this._dragDelta);
+                }
+                this._targetPosition.addInPlace(this._dragDelta);
+                this.onDragObservable.notifyObservers({dragDistance: dragLength, delta: this._dragDelta, dragPlanePoint: pickedPoint, dragPlaneNormal: this._dragPlane.forward, pointerId: this.currentDraggingPointerID});
+                this.lastDragPosition.copyFrom(pickedPoint);
+            }
+        }
+
         private _pickWithRayOnDragPlane(ray:Nullable<Ray>){
             if(!ray){
                 return null;