|
@@ -50,11 +50,16 @@ module BABYLON {
|
|
public _dragPlaneParent:Nullable<Mesh>=null;
|
|
public _dragPlaneParent:Nullable<Mesh>=null;
|
|
|
|
|
|
/**
|
|
/**
|
|
- * If the drag behavior will react to drag events
|
|
|
|
|
|
+ * If the drag behavior will react to drag events (Default: true)
|
|
*/
|
|
*/
|
|
public enabled = true;
|
|
public enabled = true;
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
+ * If set, the drag plane/axis will be rotated based on the attached mesh's world rotation (Default: true)
|
|
|
|
+ */
|
|
|
|
+ public useObjectOrienationForDragging = true;
|
|
|
|
+
|
|
|
|
+ /**
|
|
* Creates a pointer drag behavior that can be attached to a mesh
|
|
* 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. If no options are specified the drag plane will always face the ray's origin (eg. camera)
|
|
* @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)
|
|
*/
|
|
*/
|
|
@@ -86,6 +91,8 @@ module BABYLON {
|
|
*/
|
|
*/
|
|
public init() {}
|
|
public init() {}
|
|
|
|
|
|
|
|
+ private _tmpVector = new Vector3(0,0,0);
|
|
|
|
+ private _worldDragAxis = new Vector3(0,0,0);
|
|
/**
|
|
/**
|
|
* Attaches the drag behavior the passed in mesh
|
|
* Attaches the drag behavior the passed in mesh
|
|
* @param ownerNode The mesh that will be dragged around once attached
|
|
* @param ownerNode The mesh that will be dragged around once attached
|
|
@@ -149,17 +156,19 @@ module BABYLON {
|
|
// depending on the drag mode option drag accordingly
|
|
// depending on the drag mode option drag accordingly
|
|
if(this.options.dragAxis){
|
|
if(this.options.dragAxis){
|
|
// Convert local drag axis to world
|
|
// Convert local drag axis to world
|
|
- var worldDragAxis = Vector3.TransformCoordinates(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix());
|
|
|
|
|
|
+ Vector3.TransformCoordinatesToRef(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._worldDragAxis);
|
|
|
|
|
|
// Project delta drag from the drag plane onto the drag axis
|
|
// Project delta drag from the drag plane onto the drag axis
|
|
- dragLength = BABYLON.Vector3.Dot(pickedPoint.subtract(this.lastDragPosition), worldDragAxis)
|
|
|
|
- worldDragAxis.scaleToRef(dragLength, delta);
|
|
|
|
|
|
+ pickedPoint.subtractToRef(this.lastDragPosition, this._tmpVector);
|
|
|
|
+ dragLength = BABYLON.Vector3.Dot(this._tmpVector, this._worldDragAxis)
|
|
|
|
+ this._worldDragAxis.scaleToRef(dragLength, delta);
|
|
}else{
|
|
}else{
|
|
dragLength = delta.length();
|
|
dragLength = delta.length();
|
|
pickedPoint.subtractToRef(this.lastDragPosition, delta);
|
|
pickedPoint.subtractToRef(this.lastDragPosition, delta);
|
|
}
|
|
}
|
|
if(this.moveAttached){
|
|
if(this.moveAttached){
|
|
- (<Mesh>this._attachedNode).position.addInPlace(delta);
|
|
|
|
|
|
+ (<Mesh>this._attachedNode).absolutePosition.addToRef(delta, this._tmpVector);
|
|
|
|
+ (<Mesh>this._attachedNode).setAbsolutePosition(this._tmpVector);
|
|
}
|
|
}
|
|
this.onDragObservable.notifyObservers({dragDistance: dragLength, delta: delta, dragPlanePoint: pickedPoint, dragPlaneNormal: this._dragPlane.forward, pointerId: this.currentDraggingPointerID});
|
|
this.onDragObservable.notifyObservers({dragDistance: dragLength, delta: delta, dragPlanePoint: pickedPoint, dragPlaneNormal: this._dragPlane.forward, pointerId: this.currentDraggingPointerID});
|
|
this.lastDragPosition.copyFrom(pickedPoint);
|
|
this.lastDragPosition.copyFrom(pickedPoint);
|
|
@@ -187,29 +196,42 @@ module BABYLON {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // Variables to avoid instantiation in the below method
|
|
|
|
+ private _pointA = new Vector3(0,0,0);
|
|
|
|
+ private _pointB = new Vector3(0,0,0);
|
|
|
|
+ private _pointC = new Vector3(0,0,0);
|
|
|
|
+ private _lineA = new Vector3(0,0,0);
|
|
|
|
+ private _lineB = new Vector3(0,0,0);
|
|
|
|
+ private _localAxis = new Vector3(0,0,0);
|
|
|
|
+ private _lookAt = new Vector3(0,0,0);
|
|
// Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera
|
|
// Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera
|
|
private _updateDragPlanePosition(ray:Ray){
|
|
private _updateDragPlanePosition(ray:Ray){
|
|
- var pointA = this._dragPlaneParent ? this._dragPlaneParent.absolutePosition : (<Mesh>this._attachedNode).absolutePosition;
|
|
|
|
|
|
+ this._pointA.copyFrom(this._dragPlaneParent ? this._dragPlaneParent.absolutePosition : (<Mesh>this._attachedNode).absolutePosition);
|
|
if(this.options.dragAxis){
|
|
if(this.options.dragAxis){
|
|
- var localAxis = Vector3.TransformCoordinates(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix());
|
|
|
|
|
|
+ this.useObjectOrienationForDragging ? Vector3.TransformCoordinatesToRef(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this.options.dragAxis);
|
|
|
|
|
|
// Calculate plane normal in direction of camera but perpendicular to drag axis
|
|
// Calculate plane normal in direction of camera but perpendicular to drag axis
|
|
- var pointB = pointA.add(localAxis); // towards drag axis
|
|
|
|
- var pointC = pointA.add(ray.origin.subtract(pointA).normalize()); // towards camera
|
|
|
|
|
|
+ this._pointA.addToRef(this._localAxis, this._pointB); // towards drag axis
|
|
|
|
+ ray.origin.subtractToRef(this._pointA, this._pointC)
|
|
|
|
+ this._pointA.addToRef(this._pointC.normalize(), this._pointC); // towards camera
|
|
// Get perpendicular line from direction to camera and drag axis
|
|
// Get perpendicular line from direction to camera and drag axis
|
|
- var lineA = pointB.subtract(pointA);
|
|
|
|
- var lineB = pointC.subtract(pointA);
|
|
|
|
- var perpLine = BABYLON.Vector3.Cross(lineA, lineB);
|
|
|
|
|
|
+ this._pointB.subtractToRef(this._pointA, this._lineA);
|
|
|
|
+ this._pointC.subtractToRef(this._pointA, this._lineB);
|
|
|
|
+ BABYLON.Vector3.CrossToRef(this._lineA, this._lineB, this._lookAt);
|
|
// Get perpendicular line from previous result and drag axis to adjust lineB to be perpendiculat to camera
|
|
// 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();
|
|
|
|
|
|
+ BABYLON.Vector3.CrossToRef(this._lineA, this._lookAt, this._lookAt);
|
|
|
|
+ this._lookAt.normalize();
|
|
|
|
|
|
- this._dragPlane.position.copyFrom(pointA);
|
|
|
|
- this._dragPlane.lookAt(pointA.subtract(norm));
|
|
|
|
|
|
+ this._dragPlane.position.copyFrom(this._pointA);
|
|
|
|
+ this._pointA.subtractToRef(this._lookAt, this._lookAt);
|
|
|
|
+ this._dragPlane.lookAt(this._lookAt);
|
|
}else if(this.options.dragPlaneNormal){
|
|
}else if(this.options.dragPlaneNormal){
|
|
- this._dragPlane.position.copyFrom(pointA);
|
|
|
|
- this._dragPlane.lookAt(pointA.subtract(this.options.dragPlaneNormal));
|
|
|
|
|
|
+ this.useObjectOrienationForDragging ? Vector3.TransformCoordinatesToRef(this.options.dragPlaneNormal, this._attachedNode.getWorldMatrix().getRotationMatrix(),this._localAxis) : this._localAxis.copyFrom(this.options.dragPlaneNormal);
|
|
|
|
+ this._dragPlane.position.copyFrom(this._pointA);
|
|
|
|
+ this._pointA.subtractToRef(this._localAxis, this._lookAt);
|
|
|
|
+ this._dragPlane.lookAt(this._lookAt);
|
|
}else{
|
|
}else{
|
|
- this._dragPlane.position.copyFrom(pointA);
|
|
|
|
|
|
+ this._dragPlane.position.copyFrom(this._pointA);
|
|
this._dragPlane.lookAt(ray.origin);
|
|
this._dragPlane.lookAt(ray.origin);
|
|
}
|
|
}
|
|
this._dragPlane.computeWorldMatrix(true);
|
|
this._dragPlane.computeWorldMatrix(true);
|