|
@@ -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;
|