You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
262 lines
9.0 KiB
262 lines
9.0 KiB
4 years ago
|
import { ArcRotateCamera, CameraInputTypes, Nullable, PointerTouch, serialize } from "@babylonjs/core";
|
||
|
import { BaseCameraPointersInput } from "@babylonjs/core/Cameras/Inputs/BaseCameraPointersInput";
|
||
|
|
||
|
|
||
|
//修改为左键平移,右键旋转
|
||
|
|
||
|
export class MyArcRotateCameraPointersInput extends BaseCameraPointersInput {
|
||
|
/**
|
||
|
* Defines the camera the input is attached to.
|
||
|
*/
|
||
|
public camera: ArcRotateCamera;
|
||
|
|
||
|
/**
|
||
|
* Gets the class name of the current input.
|
||
|
* @returns the class name
|
||
|
*/
|
||
|
public getClassName(): string {
|
||
|
return "MyArcRotateCameraPointersInput";
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Defines the buttons associated with the input to handle camera move.
|
||
|
*/
|
||
|
@serialize()
|
||
|
public buttons = [0, 1, 2];
|
||
|
|
||
|
/**
|
||
|
* Defines the pointer angular sensibility along the X axis or how fast is
|
||
|
* the camera rotating.
|
||
|
*/
|
||
|
@serialize()
|
||
|
public angularSensibilityX = 1000.0;
|
||
|
|
||
|
/**
|
||
|
* Defines the pointer angular sensibility along the Y axis or how fast is
|
||
|
* the camera rotating.
|
||
|
*/
|
||
|
@serialize()
|
||
|
public angularSensibilityY = 1000.0;
|
||
|
|
||
|
/**
|
||
|
* Defines the pointer pinch precision or how fast is the camera zooming.
|
||
|
*/
|
||
|
@serialize()
|
||
|
public pinchPrecision = 12.0;
|
||
|
|
||
|
/**
|
||
|
* pinchDeltaPercentage will be used instead of pinchPrecision if different
|
||
|
* from 0.
|
||
|
* It defines the percentage of current camera.radius to use as delta when
|
||
|
* pinch zoom is used.
|
||
|
*/
|
||
|
@serialize()
|
||
|
public pinchDeltaPercentage = 0;
|
||
|
|
||
|
/**
|
||
|
* When useNaturalPinchZoom is true, multi touch zoom will zoom in such
|
||
|
* that any object in the plane at the camera's target point will scale
|
||
|
* perfectly with finger motion.
|
||
|
* Overrides pinchDeltaPercentage and pinchPrecision.
|
||
|
*/
|
||
|
@serialize()
|
||
|
public useNaturalPinchZoom: boolean = false;
|
||
|
|
||
|
/**
|
||
|
* Defines whether zoom (2 fingers pinch) is enabled through multitouch
|
||
|
*/
|
||
|
@serialize()
|
||
|
public pinchZoom: boolean = true;
|
||
|
|
||
|
/**
|
||
|
* Defines the pointer panning sensibility or how fast is the camera moving.
|
||
|
*/
|
||
|
@serialize()
|
||
|
public panningSensibility: number = 1000.0;
|
||
|
|
||
|
/**
|
||
|
* Defines whether panning (2 fingers swipe) is enabled through multitouch.
|
||
|
*/
|
||
|
@serialize()
|
||
|
public multiTouchPanning: boolean = true;
|
||
|
|
||
|
/**
|
||
|
* Defines whether panning is enabled for both pan (2 fingers swipe) and
|
||
|
* zoom (pinch) through multitouch.
|
||
|
*/
|
||
|
@serialize()
|
||
|
public multiTouchPanAndZoom: boolean = true;
|
||
|
|
||
|
/**
|
||
|
* Revers pinch action direction.
|
||
|
*/
|
||
|
public pinchInwards = true;
|
||
|
|
||
|
private _isPanClick: boolean = false;
|
||
|
private _twoFingerActivityCount: number = 0;
|
||
|
private _isPinching: boolean = false;
|
||
|
|
||
|
/**
|
||
|
* Move camera from multi touch panning positions.
|
||
|
*/
|
||
|
private _computeMultiTouchPanning(
|
||
|
previousMultiTouchPanPosition: Nullable<PointerTouch>,
|
||
|
multiTouchPanPosition: Nullable<PointerTouch>
|
||
|
): void {
|
||
|
if (this.panningSensibility !== 0 && previousMultiTouchPanPosition
|
||
|
&& multiTouchPanPosition) {
|
||
|
var moveDeltaX = multiTouchPanPosition.x - previousMultiTouchPanPosition.x;
|
||
|
var moveDeltaY = multiTouchPanPosition.y - previousMultiTouchPanPosition.y;
|
||
|
// this.camera.inertialPanningX += -moveDeltaX / this.panningSensibility;
|
||
|
// this.camera.inertialPanningY += moveDeltaY / this.panningSensibility;
|
||
|
// this.moveCamera(-moveDeltaX, moveDeltaY);
|
||
|
this.rotateCamera(moveDeltaX, moveDeltaX);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
moveCamera(x, y) {
|
||
|
this.camera.inertialPanningX += x / this.panningSensibility;
|
||
|
this.camera.inertialPanningY += y / this.panningSensibility;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Move camera from pinch zoom distances.
|
||
|
*/
|
||
|
private _computePinchZoom(
|
||
|
previousPinchSquaredDistance: number,
|
||
|
pinchSquaredDistance: number
|
||
|
): void {
|
||
|
if (this.useNaturalPinchZoom) {
|
||
|
this.camera.radius = this.camera.radius *
|
||
|
Math.sqrt(previousPinchSquaredDistance) / Math.sqrt(pinchSquaredDistance);
|
||
|
} else if (this.pinchDeltaPercentage) {
|
||
|
this.camera.inertialRadiusOffset +=
|
||
|
(pinchSquaredDistance - previousPinchSquaredDistance) * 0.001 *
|
||
|
this.camera.radius * this.pinchDeltaPercentage;
|
||
|
}
|
||
|
else {
|
||
|
this.camera.inertialRadiusOffset +=
|
||
|
(pinchSquaredDistance - previousPinchSquaredDistance) /
|
||
|
(this.pinchPrecision * (this.pinchInwards ? 1 : -1) *
|
||
|
(this.angularSensibilityX + this.angularSensibilityY) / 2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Called on pointer POINTERMOVE event if only a single touch is active.
|
||
|
*/
|
||
|
protected onTouch(point: Nullable<PointerTouch>,
|
||
|
offsetX: number,
|
||
|
offsetY: number): void {
|
||
|
if (this.panningSensibility !== 0 &&
|
||
|
((this._ctrlKey && this.camera._useCtrlForPanning) || this._isPanClick)) {
|
||
|
// this.camera.inertialPanningX += -offsetX / this.panningSensibility;
|
||
|
// this.camera.inertialPanningY += offsetY / this.panningSensibility;
|
||
|
|
||
|
this.rotateCamera(offsetX, offsetY);
|
||
|
} else {
|
||
|
this.moveCamera(-offsetX, offsetY);
|
||
|
// this.camera.inertialAlphaOffset -= offsetX / this.angularSensibilityX;
|
||
|
// this.camera.inertialBetaOffset -= offsetY / this.angularSensibilityY;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
rotateCamera(offsetX, offsetY) {
|
||
|
this.camera.inertialAlphaOffset -= offsetX / this.angularSensibilityX;
|
||
|
this.camera.inertialBetaOffset -= offsetY / this.angularSensibilityY;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Called on pointer POINTERDOUBLETAP event.
|
||
|
*/
|
||
|
protected onDoubleTap(type: string) {
|
||
|
if (this.camera.useInputToRestoreState) {
|
||
|
this.camera.restoreState();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Called on pointer POINTERMOVE event if multiple touches are active.
|
||
|
*/
|
||
|
protected onMultiTouch(pointA: Nullable<PointerTouch>,
|
||
|
pointB: Nullable<PointerTouch>,
|
||
|
previousPinchSquaredDistance: number,
|
||
|
pinchSquaredDistance: number,
|
||
|
previousMultiTouchPanPosition: Nullable<PointerTouch>,
|
||
|
multiTouchPanPosition: Nullable<PointerTouch>): void {
|
||
|
if (previousPinchSquaredDistance === 0 && previousMultiTouchPanPosition === null) {
|
||
|
// First time this method is called for new pinch.
|
||
|
// Next time this is called there will be a
|
||
|
// previousPinchSquaredDistance and pinchSquaredDistance to compare.
|
||
|
return;
|
||
|
}
|
||
|
if (pinchSquaredDistance === 0 && multiTouchPanPosition === null) {
|
||
|
// Last time this method is called at the end of a pinch.
|
||
|
return;
|
||
|
}
|
||
|
// Zoom and panning enabled together
|
||
|
if (this.multiTouchPanAndZoom) {
|
||
|
this._computePinchZoom(previousPinchSquaredDistance, pinchSquaredDistance);
|
||
|
this._computeMultiTouchPanning(previousMultiTouchPanPosition, multiTouchPanPosition);
|
||
|
|
||
|
// Zoom and panning enabled but only one at a time
|
||
|
} else if (this.multiTouchPanning && this.pinchZoom) {
|
||
|
this._twoFingerActivityCount++;
|
||
|
|
||
|
if (this._isPinching || (this._twoFingerActivityCount < 20
|
||
|
&& Math.abs(Math.sqrt(pinchSquaredDistance) - Math.sqrt(previousPinchSquaredDistance)) >
|
||
|
this.camera.pinchToPanMaxDistance)) {
|
||
|
|
||
|
// Since pinch has not been active long, assume we intend to zoom.
|
||
|
this._computePinchZoom(previousPinchSquaredDistance, pinchSquaredDistance);
|
||
|
|
||
|
// Since we are pinching, remain pinching on next iteration.
|
||
|
this._isPinching = true;
|
||
|
} else {
|
||
|
// Pause between pinch starting and moving implies not a zoom event. Pan instead.
|
||
|
this._computeMultiTouchPanning(previousMultiTouchPanPosition, multiTouchPanPosition);
|
||
|
}
|
||
|
|
||
|
// Panning enabled, zoom disabled
|
||
|
} else if (this.multiTouchPanning) {
|
||
|
this._computeMultiTouchPanning(previousMultiTouchPanPosition, multiTouchPanPosition);
|
||
|
|
||
|
// Zoom enabled, panning disabled
|
||
|
} else if (this.pinchZoom) {
|
||
|
this._computePinchZoom(previousPinchSquaredDistance, pinchSquaredDistance);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Called each time a new POINTERDOWN event occurs. Ie, for each button
|
||
|
* press.
|
||
|
*/
|
||
|
protected onButtonDown(evt: PointerEvent): void {
|
||
|
this._isPanClick = evt.button === this.camera._panningMouseButton;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Called each time a new POINTERUP event occurs. Ie, for each button
|
||
|
* release.
|
||
|
*/
|
||
|
protected onButtonUp(evt: PointerEvent): void {
|
||
|
this._twoFingerActivityCount = 0;
|
||
|
this._isPinching = false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Called when window becomes inactive.
|
||
|
*/
|
||
|
protected onLostFocus(): void {
|
||
|
|
||
|
// console.trace("失去焦点")
|
||
|
this._isPanClick = false;
|
||
|
this._twoFingerActivityCount = 0;
|
||
|
this._isPinching = false;
|
||
|
}
|
||
|
}
|
||
|
(<any>CameraInputTypes)["MyArcRotateCameraPointersInput"] =
|
||
|
MyArcRotateCameraPointersInput;
|