|
@@ -1,76 +1,83 @@
|
|
module BABYLON {
|
|
module BABYLON {
|
|
|
|
+ /**
|
|
|
|
+ * The autoRotation behavior (BABYLON.AutoRotationBehavior) is designed to create a smooth rotation of an ArcRotateCamera when there is no user interaction.
|
|
|
|
+ * @see http://doc.babylonjs.com/how_to/camera_behaviors#autorotation-behavior
|
|
|
|
+ */
|
|
export class AutoRotationBehavior implements Behavior<ArcRotateCamera> {
|
|
export class AutoRotationBehavior implements Behavior<ArcRotateCamera> {
|
|
|
|
+ /**
|
|
|
|
+ * Gets the name of the behavior.
|
|
|
|
+ */
|
|
public get name(): string {
|
|
public get name(): string {
|
|
return "AutoRotation";
|
|
return "AutoRotation";
|
|
}
|
|
}
|
|
|
|
|
|
private _zoomStopsAnimation = false;
|
|
private _zoomStopsAnimation = false;
|
|
- private _idleRotationSpeed = 0.05;
|
|
|
|
- private _idleRotationWaitTime = 2000;
|
|
|
|
|
|
+ private _idleRotationSpeed = 0.05;
|
|
|
|
+ private _idleRotationWaitTime = 2000;
|
|
private _idleRotationSpinupTime = 2000;
|
|
private _idleRotationSpinupTime = 2000;
|
|
|
|
|
|
- /**
|
|
|
|
- * Sets the flag that indicates if user zooming should stop animation.
|
|
|
|
- */
|
|
|
|
- public set zoomStopsAnimation(flag: boolean) {
|
|
|
|
- this._zoomStopsAnimation = flag;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Gets the flag that indicates if user zooming should stop animation.
|
|
|
|
- */
|
|
|
|
- public get zoomStopsAnimation(): boolean {
|
|
|
|
- return this._zoomStopsAnimation;
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Sets the flag that indicates if user zooming should stop animation.
|
|
|
|
+ */
|
|
|
|
+ public set zoomStopsAnimation(flag: boolean) {
|
|
|
|
+ this._zoomStopsAnimation = flag;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Gets the flag that indicates if user zooming should stop animation.
|
|
|
|
+ */
|
|
|
|
+ public get zoomStopsAnimation(): boolean {
|
|
|
|
+ return this._zoomStopsAnimation;
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * Sets the default speed at which the camera rotates around the model.
|
|
|
|
- */
|
|
|
|
- public set idleRotationSpeed(speed: number) {
|
|
|
|
- this._idleRotationSpeed = speed;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Gets the default speed at which the camera rotates around the model.
|
|
|
|
- */
|
|
|
|
- public get idleRotationSpeed() {
|
|
|
|
- return this._idleRotationSpeed;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Sets the time (in milliseconds) to wait after user interaction before the camera starts rotating.
|
|
|
|
- */
|
|
|
|
- public set idleRotationWaitTime(time: number) {
|
|
|
|
- this._idleRotationWaitTime = time;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Gets the time (milliseconds) to wait after user interaction before the camera starts rotating.
|
|
|
|
- */
|
|
|
|
- public get idleRotationWaitTime() {
|
|
|
|
- return this._idleRotationWaitTime;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Sets the time (milliseconds) to take to spin up to the full idle rotation speed.
|
|
|
|
- */
|
|
|
|
- public set idleRotationSpinupTime(time: number) {
|
|
|
|
- this._idleRotationSpinupTime = time;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Gets the time (milliseconds) to take to spin up to the full idle rotation speed.
|
|
|
|
- */
|
|
|
|
- public get idleRotationSpinupTime() {
|
|
|
|
- return this._idleRotationSpinupTime;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Gets a value indicating if the camera is currently rotating because of this behavior
|
|
|
|
- */
|
|
|
|
- public get rotationInProgress(): boolean {
|
|
|
|
- return Math.abs(this._cameraRotationSpeed) > 0;
|
|
|
|
- }
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Sets the default speed at which the camera rotates around the model.
|
|
|
|
+ */
|
|
|
|
+ public set idleRotationSpeed(speed: number) {
|
|
|
|
+ this._idleRotationSpeed = speed;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Gets the default speed at which the camera rotates around the model.
|
|
|
|
+ */
|
|
|
|
+ public get idleRotationSpeed() {
|
|
|
|
+ return this._idleRotationSpeed;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Sets the time (in milliseconds) to wait after user interaction before the camera starts rotating.
|
|
|
|
+ */
|
|
|
|
+ public set idleRotationWaitTime(time: number) {
|
|
|
|
+ this._idleRotationWaitTime = time;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Gets the time (milliseconds) to wait after user interaction before the camera starts rotating.
|
|
|
|
+ */
|
|
|
|
+ public get idleRotationWaitTime() {
|
|
|
|
+ return this._idleRotationWaitTime;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Sets the time (milliseconds) to take to spin up to the full idle rotation speed.
|
|
|
|
+ */
|
|
|
|
+ public set idleRotationSpinupTime(time: number) {
|
|
|
|
+ this._idleRotationSpinupTime = time;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Gets the time (milliseconds) to take to spin up to the full idle rotation speed.
|
|
|
|
+ */
|
|
|
|
+ public get idleRotationSpinupTime() {
|
|
|
|
+ return this._idleRotationSpinupTime;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Gets a value indicating if the camera is currently rotating because of this behavior
|
|
|
|
+ */
|
|
|
|
+ public get rotationInProgress(): boolean {
|
|
|
|
+ return Math.abs(this._cameraRotationSpeed) > 0;
|
|
|
|
+ }
|
|
|
|
|
|
// Default behavior functions
|
|
// Default behavior functions
|
|
private _onPrePointerObservableObserver: Nullable<Observer<PointerInfoPre>>;
|
|
private _onPrePointerObservableObserver: Nullable<Observer<PointerInfoPre>>;
|
|
@@ -78,13 +85,20 @@ module BABYLON {
|
|
private _attachedCamera: Nullable<ArcRotateCamera>;
|
|
private _attachedCamera: Nullable<ArcRotateCamera>;
|
|
private _isPointerDown = false;
|
|
private _isPointerDown = false;
|
|
private _lastFrameTime: Nullable<number> = null;
|
|
private _lastFrameTime: Nullable<number> = null;
|
|
- private _lastInteractionTime = -Infinity;
|
|
|
|
- private _cameraRotationSpeed: number = 0;
|
|
|
|
-
|
|
|
|
- public init(): void {
|
|
|
|
- // Do notihng
|
|
|
|
- }
|
|
|
|
|
|
+ private _lastInteractionTime = -Infinity;
|
|
|
|
+ private _cameraRotationSpeed: number = 0;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Initializes the behavior.
|
|
|
|
+ */
|
|
|
|
+ public init(): void {
|
|
|
|
+ // Do notihng
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Attaches the behavior to its arc rotate camera.
|
|
|
|
+ * @param camera Defines the camera to attach the behavior to
|
|
|
|
+ */
|
|
public attach(camera: ArcRotateCamera): void {
|
|
public attach(camera: ArcRotateCamera): void {
|
|
this._attachedCamera = camera;
|
|
this._attachedCamera = camera;
|
|
let scene = this._attachedCamera.getScene();
|
|
let scene = this._attachedCamera.getScene();
|
|
@@ -112,78 +126,81 @@ module BABYLON {
|
|
this._applyUserInteraction();
|
|
this._applyUserInteraction();
|
|
|
|
|
|
let timeToRotation = now - this._lastInteractionTime - this._idleRotationWaitTime;
|
|
let timeToRotation = now - this._lastInteractionTime - this._idleRotationWaitTime;
|
|
- let scale = Math.max(Math.min(timeToRotation / (this._idleRotationSpinupTime), 1), 0);
|
|
|
|
|
|
+ let scale = Math.max(Math.min(timeToRotation / (this._idleRotationSpinupTime), 1), 0);
|
|
this._cameraRotationSpeed = this._idleRotationSpeed * scale;
|
|
this._cameraRotationSpeed = this._idleRotationSpeed * scale;
|
|
|
|
|
|
- // Step camera rotation by rotation speed
|
|
|
|
- if (this._attachedCamera) {
|
|
|
|
- this._attachedCamera.alpha -= this._cameraRotationSpeed * (dt / 1000);
|
|
|
|
- }
|
|
|
|
|
|
+ // Step camera rotation by rotation speed
|
|
|
|
+ if (this._attachedCamera) {
|
|
|
|
+ this._attachedCamera.alpha -= this._cameraRotationSpeed * (dt / 1000);
|
|
|
|
+ }
|
|
});
|
|
});
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Detaches the behavior from its current arc rotate camera.
|
|
|
|
+ */
|
|
public detach(): void {
|
|
public detach(): void {
|
|
- if (!this._attachedCamera) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ if (!this._attachedCamera) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
let scene = this._attachedCamera.getScene();
|
|
let scene = this._attachedCamera.getScene();
|
|
-
|
|
|
|
- if (this._onPrePointerObservableObserver) {
|
|
|
|
- scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
|
|
|
|
- this._attachedCamera = null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Returns true if user is scrolling.
|
|
|
|
- * @return true if user is scrolling.
|
|
|
|
- */
|
|
|
|
- private _userIsZooming(): boolean {
|
|
|
|
- if (!this._attachedCamera) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return this._attachedCamera.inertialRadiusOffset !== 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private _lastFrameRadius = 0;
|
|
|
|
- private _shouldAnimationStopForInteraction(): boolean {
|
|
|
|
- if (!this._attachedCamera) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var zoomHasHitLimit = false;
|
|
|
|
- if (this._lastFrameRadius === this._attachedCamera.radius && this._attachedCamera.inertialRadiusOffset !== 0) {
|
|
|
|
- zoomHasHitLimit = true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Update the record of previous radius - works as an approx. indicator of hitting radius limits
|
|
|
|
- this._lastFrameRadius = this._attachedCamera.radius;
|
|
|
|
- return this._zoomStopsAnimation ? zoomHasHitLimit : this._userIsZooming();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Applies any current user interaction to the camera. Takes into account maximum alpha rotation.
|
|
|
|
- */
|
|
|
|
|
|
+
|
|
|
|
+ if (this._onPrePointerObservableObserver) {
|
|
|
|
+ scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
|
|
|
|
+ this._attachedCamera = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Returns true if user is scrolling.
|
|
|
|
+ * @return true if user is scrolling.
|
|
|
|
+ */
|
|
|
|
+ private _userIsZooming(): boolean {
|
|
|
|
+ if (!this._attachedCamera) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return this._attachedCamera.inertialRadiusOffset !== 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private _lastFrameRadius = 0;
|
|
|
|
+ private _shouldAnimationStopForInteraction(): boolean {
|
|
|
|
+ if (!this._attachedCamera) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var zoomHasHitLimit = false;
|
|
|
|
+ if (this._lastFrameRadius === this._attachedCamera.radius && this._attachedCamera.inertialRadiusOffset !== 0) {
|
|
|
|
+ zoomHasHitLimit = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Update the record of previous radius - works as an approx. indicator of hitting radius limits
|
|
|
|
+ this._lastFrameRadius = this._attachedCamera.radius;
|
|
|
|
+ return this._zoomStopsAnimation ? zoomHasHitLimit : this._userIsZooming();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Applies any current user interaction to the camera. Takes into account maximum alpha rotation.
|
|
|
|
+ */
|
|
private _applyUserInteraction(): void {
|
|
private _applyUserInteraction(): void {
|
|
- if (this._userIsMoving() && !this._shouldAnimationStopForInteraction()) {
|
|
|
|
|
|
+ if (this._userIsMoving() && !this._shouldAnimationStopForInteraction()) {
|
|
this._lastInteractionTime = Tools.Now;
|
|
this._lastInteractionTime = Tools.Now;
|
|
- }
|
|
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
// Tools
|
|
// Tools
|
|
private _userIsMoving(): boolean {
|
|
private _userIsMoving(): boolean {
|
|
- if (!this._attachedCamera) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return this._attachedCamera.inertialAlphaOffset !== 0 ||
|
|
|
|
- this._attachedCamera.inertialBetaOffset !== 0 ||
|
|
|
|
- this._attachedCamera.inertialRadiusOffset !== 0 ||
|
|
|
|
- this._attachedCamera.inertialPanningX !== 0 ||
|
|
|
|
- this._attachedCamera.inertialPanningY !== 0 ||
|
|
|
|
- this._isPointerDown;
|
|
|
|
- }
|
|
|
|
|
|
+ if (!this._attachedCamera) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return this._attachedCamera.inertialAlphaOffset !== 0 ||
|
|
|
|
+ this._attachedCamera.inertialBetaOffset !== 0 ||
|
|
|
|
+ this._attachedCamera.inertialRadiusOffset !== 0 ||
|
|
|
|
+ this._attachedCamera.inertialPanningX !== 0 ||
|
|
|
|
+ this._attachedCamera.inertialPanningY !== 0 ||
|
|
|
|
+ this._isPointerDown;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|