Skip to content

Commit

Permalink
Cameras: Modified cameras to work under onPointerObservable (#13293)
Browse files Browse the repository at this point in the history
* Modified inputs to use onPointerObservable

* Formatting

* factored out picking check

Former-commit-id: a2e085cc1a1ea08eb2395f1fbb52c436359baf86
  • Loading branch information
PolygonalSun authored Nov 28, 2022
1 parent bbdaea1 commit eb54382
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ export abstract class BaseCameraMouseWheelInput implements ICameraInput<Camera>
}
};

this._observer = this.camera.getScene()._onCameraInputObservable.add(this._wheel, PointerEventTypes.POINTERWHEEL);
this._observer = this.camera.getScene()._inputManager._addCameraPointerObserver(this._wheel, PointerEventTypes.POINTERWHEEL);
}

/**
* Detach the current controls from the specified dom element.
*/
public detachControl(): void {
if (this._observer) {
this.camera.getScene()._onCameraInputObservable.remove(this._observer);
this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);
this._observer = null;
this._wheel = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ export abstract class BaseCameraPointersInput implements ICameraInput<Camera> {

this._observer = this.camera
.getScene()
._onCameraInputObservable.add(
._inputManager._addCameraPointerObserver(
this._pointerInput,
PointerEventTypes.POINTERDOWN | PointerEventTypes.POINTERUP | PointerEventTypes.POINTERMOVE | PointerEventTypes.POINTERDOUBLETAP
);
Expand Down Expand Up @@ -251,7 +251,7 @@ export abstract class BaseCameraPointersInput implements ICameraInput<Camera> {
}

if (this._observer) {
this.camera.getScene()._onCameraInputObservable.remove(this._observer);
this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);
this._observer = null;

if (this._contextMenuBind) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export class ArcRotateCameraMouseWheelInput implements ICameraInput<ArcRotateCam
}
};

this._observer = this.camera.getScene()._onCameraInputObservable.add(this._wheel, PointerEventTypes.POINTERWHEEL);
this._observer = this.camera.getScene()._inputManager._addCameraPointerObserver(this._wheel, PointerEventTypes.POINTERWHEEL);

if (this.zoomToMouseLocation) {
this._inertialPanning.setAll(0);
Expand All @@ -140,7 +140,7 @@ export class ArcRotateCameraMouseWheelInput implements ICameraInput<ArcRotateCam
*/
public detachControl(): void {
if (this._observer) {
this.camera.getScene()._onCameraInputObservable.remove(this._observer);
this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);
this._observer = null;
this._wheel = null;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/dev/core/src/Cameras/Inputs/flyCameraMouseInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class FlyCameraMouseInput implements ICameraInput<FlyCamera> {
noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);
this._noPreventDefault = noPreventDefault;

this._observer = this.camera.getScene()._onCameraInputObservable.add((p: any) => {
this._observer = this.camera.getScene()._inputManager._addCameraPointerObserver((p: any) => {
this._pointerInput(p);
}, PointerEventTypes.POINTERDOWN | PointerEventTypes.POINTERUP | PointerEventTypes.POINTERMOVE);

Expand All @@ -101,7 +101,7 @@ export class FlyCameraMouseInput implements ICameraInput<FlyCamera> {
*/
public detachControl(): void {
if (this._observer) {
this.camera.getScene()._onCameraInputObservable.remove(this._observer);
this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);

this.camera.getScene().onBeforeRenderObservable.remove(this._rollObserver);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,15 @@ export class FollowCameraMouseWheelInput implements ICameraInput<FollowCamera> {
}
};

this._observer = this.camera.getScene()._onCameraInputObservable.add(this._wheel, PointerEventTypes.POINTERWHEEL);
this._observer = this.camera.getScene()._inputManager._addCameraPointerObserver(this._wheel, PointerEventTypes.POINTERWHEEL);
}

/**
* Detach the current controls from the specified dom element.
*/
public detachControl(): void {
if (this._observer) {
this.camera.getScene()._onCameraInputObservable.remove(this._observer);
this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);
this._observer = null;
this._wheel = null;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/dev/core/src/Cameras/Inputs/freeCameraMouseInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export class FreeCameraMouseInput implements ICameraInput<FreeCamera> {

this._observer = this.camera
.getScene()
._onCameraInputObservable.add(this._pointerInput, PointerEventTypes.POINTERDOWN | PointerEventTypes.POINTERUP | PointerEventTypes.POINTERMOVE);
._inputManager._addCameraPointerObserver(this._pointerInput, PointerEventTypes.POINTERDOWN | PointerEventTypes.POINTERUP | PointerEventTypes.POINTERMOVE);

if (element) {
this._contextMenuBind = this.onContextMenu.bind(this);
Expand All @@ -225,7 +225,7 @@ export class FreeCameraMouseInput implements ICameraInput<FreeCamera> {
*/
public detachControl(): void {
if (this._observer) {
this.camera.getScene()._onCameraInputObservable.remove(this._observer);
this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);

if (this._contextMenuBind) {
const engine = this.camera.getEngine();
Expand Down
4 changes: 2 additions & 2 deletions packages/dev/core/src/Cameras/Inputs/freeCameraTouchInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export class FreeCameraTouchInput implements ICameraInput<FreeCamera> {

this._observer = this.camera
.getScene()
._onCameraInputObservable.add(this._pointerInput, PointerEventTypes.POINTERDOWN | PointerEventTypes.POINTERUP | PointerEventTypes.POINTERMOVE);
._inputManager._addCameraPointerObserver(this._pointerInput, PointerEventTypes.POINTERDOWN | PointerEventTypes.POINTERUP | PointerEventTypes.POINTERMOVE);

if (this._onLostFocus) {
const engine = this.camera.getEngine();
Expand All @@ -156,7 +156,7 @@ export class FreeCameraTouchInput implements ICameraInput<FreeCamera> {
public detachControl(): void {
if (this._pointerInput) {
if (this._observer) {
this.camera.getScene()._onCameraInputObservable.remove(this._observer);
this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);
this._observer = null;
}

Expand Down
38 changes: 26 additions & 12 deletions packages/dev/core/src/Inputs/scene.inputManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Observable } from "../Misc/observable";
import type { EventState, Observable, Observer } from "../Misc/observable";
import { PointerInfoPre, PointerInfo, PointerEventTypes } from "../Events/pointerEvents";
import type { Nullable } from "../types";
import { AbstractActionManager } from "../Actions/abstractActionManager";
Expand Down Expand Up @@ -108,6 +108,7 @@ export class InputManager {
private _pointerCaptures: { [pointerId: number]: boolean } = {};
private _meshUnderPointerId: { [pointerId: number]: Nullable<AbstractMesh> } = {};
private _movePointerInfo: Nullable<PointerInfo> = null;
private _cameraObserverCount = 0;

// Keyboard
private _onKeyDown: (evt: IKeyboardEvent) => void;
Expand Down Expand Up @@ -235,7 +236,6 @@ export class InputManager {
this._movePointerInfo = pointerInfo;
}

scene._onCameraInputObservable.notifyObservers(pointerInfo, type);
if (scene.onPointerObservable.hasObservers()) {
scene.onPointerObservable.notifyObservers(pointerInfo, type);
}
Expand All @@ -252,6 +252,26 @@ export class InputManager {
}
}

/** @internal */
public _addCameraPointerObserver(observer: (p: PointerInfo, s: EventState) => void, mask?: number): Nullable<Observer<PointerInfo>> {
this._cameraObserverCount++;
return this._scene.onPointerObservable.add(observer, mask);
}

/** @internal */
public _removeCameraPointerObserver(observer: Observer<PointerInfo>): boolean {
this._cameraObserverCount--;
return this._scene.onPointerObservable.remove(observer);
}

private _checkForPicking(): boolean {
if (this._scene.onPointerObservable.observers.length > this._cameraObserverCount || this._scene.onPointerPick || this._scene.onPointerUp) {
return true;
}

return false;
}

private _checkPrePointerObservable(pickResult: Nullable<PickingInfo>, evt: IPointerEvent, type: number) {
const scene = this._scene;
const pi = new PointerInfoPre(type, evt, this._unTranslatedPointerX, this._unTranslatedPointerY);
Expand Down Expand Up @@ -407,7 +427,6 @@ export class InputManager {
pointerInfo = new PointerInfo(type, evt, null, this);
}

scene._onCameraInputObservable.notifyObservers(pointerInfo, type);
if (scene.onPointerObservable.hasObservers()) {
scene.onPointerObservable.notifyObservers(pointerInfo, type);
}
Expand Down Expand Up @@ -454,7 +473,7 @@ export class InputManager {
if (scene.onPointerPick) {
scene.onPointerPick(evt, pickResult);
}
if (clickInfo.singleClick && !clickInfo.ignore && scene.onPointerObservable.hasObservers()) {
if (clickInfo.singleClick && !clickInfo.ignore && scene.onPointerObservable.observers.length > this._cameraObserverCount) {
const type = PointerEventTypes.POINTERPICK;
const pi = new PointerInfo(type, evt, pickResult);
this._setRayOnPointerInfo(pickResult, evt);
Expand Down Expand Up @@ -501,7 +520,6 @@ export class InputManager {
if (type) {
const pi = new PointerInfo(type, evt, pickResult);
this._setRayOnPointerInfo(pickResult, evt);
scene._onCameraInputObservable.notifyObservers(pi, type);
if (scene.onPointerObservable.hasObservers() && scene.onPointerObservable.hasSpecificMask(type)) {
scene.onPointerObservable.notifyObservers(pi, type);
}
Expand All @@ -511,7 +529,6 @@ export class InputManager {
type = PointerEventTypes.POINTERUP;
const pi = new PointerInfo(type, evt, pickResult);
this._setRayOnPointerInfo(pickResult, evt);
scene._onCameraInputObservable.notifyObservers(pi, type);
scene.onPointerObservable.notifyObservers(pi, type);
}

Expand Down Expand Up @@ -557,7 +574,7 @@ export class InputManager {
this._initActionManager = (act: Nullable<AbstractActionManager>): Nullable<AbstractActionManager> => {
if (!this._meshPickProceed) {
const pickResult =
scene.skipPointerUpPicking || (scene._registeredActions === 0 && !(scene.onPointerObservable.hasObservers() || scene.onPointerPick || scene.onPointerUp))
scene.skipPointerUpPicking || (scene._registeredActions === 0 && !this._checkForPicking())
? null
: scene.pick(this._unTranslatedPointerX, this._unTranslatedPointerY, scene.pointerUpPredicate, false, scene.cameraToUseForPointers);
this._currentPickResult = pickResult;
Expand Down Expand Up @@ -797,7 +814,7 @@ export class InputManager {
// Meshes
this._pickedDownMesh = null;
let pickResult;
if (scene.skipPointerDownPicking || (scene._registeredActions === 0 && !(scene.onPointerObservable.hasObservers() || scene.onPointerPick || scene.onPointerDown))) {
if (scene.skipPointerDownPicking || (scene._registeredActions === 0 && !this._checkForPicking())) {
pickResult = new PickingInfo();
} else {
pickResult = scene.pick(this._unTranslatedPointerX, this._unTranslatedPointerY, scene.pointerDownPredicate, false, scene.cameraToUseForPointers);
Expand Down Expand Up @@ -873,10 +890,7 @@ export class InputManager {
}

// Meshes
if (
!this._meshPickProceed &&
((AbstractActionManager && AbstractActionManager.HasTriggers) || scene.onPointerObservable.hasObservers() || scene.onPointerPick || scene.onPointerUp)
) {
if (!this._meshPickProceed && ((AbstractActionManager && AbstractActionManager.HasTriggers) || this._checkForPicking())) {
this._initActionManager(null, clickInfo);
}
if (!pickResult) {
Expand Down
7 changes: 0 additions & 7 deletions packages/dev/core/src/scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -797,12 +797,6 @@ export class Scene extends AbstractScene implements IAnimatable, IClipPlanesHold
*/
public onPointerObservable = new Observable<PointerInfo>();

/**
* Observable to handle camera pointer inputs
* @internal
*/
public _onCameraInputObservable = new Observable<PointerInfo>();

/**
* Gets the pointer coordinates without any translation (ie. straight out of the pointer event)
*/
Expand Down Expand Up @@ -4737,7 +4731,6 @@ export class Scene extends AbstractScene implements IAnimatable, IClipPlanesHold
this.onTextureRemovedObservable.clear();
this.onPrePointerObservable.clear();
this.onPointerObservable.clear();
this._onCameraInputObservable.clear();
this.onPreKeyboardObservable.clear();
this.onKeyboardObservable.clear();
this.onActiveCameraChanged.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,19 @@ describe("FreeCameraMouseInput", () => {
const upPI2 = new PointerInfo(PointerEventTypes.POINTERUP, upEvt2 as IMouseEvent, new PickingInfo());

// With the first touch, the camera should rotate
scene?._onCameraInputObservable.notifyObservers(downPI1);
scene?._onCameraInputObservable.notifyObservers(movePI1);
scene?.onPointerObservable.notifyObservers(downPI1);
scene?.onPointerObservable.notifyObservers(movePI1);
expect(camera?.cameraRotation.x).not.toEqual(cameraRotation.x);
expect(camera?.cameraRotation.y).not.toEqual(cameraRotation.y);

// With the second touch, the camera should not rotate because the first touch is still active
cameraRotation = camera!.cameraRotation.clone();
scene?._onCameraInputObservable.notifyObservers(downPI2);
scene?._onCameraInputObservable.notifyObservers(movePI2);
scene?.onPointerObservable.notifyObservers(downPI2);
scene?.onPointerObservable.notifyObservers(movePI2);
expect(camera?.cameraRotation.x).toEqual(cameraRotation.x);
expect(camera?.cameraRotation.y).toEqual(cameraRotation.y);
scene?._onCameraInputObservable.notifyObservers(upPI2);
scene?._onCameraInputObservable.notifyObservers(upPI1);
scene?.onPointerObservable.notifyObservers(upPI2);
scene?.onPointerObservable.notifyObservers(upPI1);
});

it("can work with pointer lock", () => {
Expand Down Expand Up @@ -126,7 +126,7 @@ describe("FreeCameraMouseInput", () => {
engine!.isPointerLock = true;

// Try to move the camera with the first event, it should move
scene?._onCameraInputObservable.notifyObservers(movePI);
scene?.onPointerObservable.notifyObservers(movePI);
expect(camera?.cameraRotation.x).not.toEqual(cameraRotation.x);
expect(camera?.cameraRotation.y).not.toEqual(cameraRotation.y);

Expand All @@ -135,7 +135,7 @@ describe("FreeCameraMouseInput", () => {
engine!.isPointerLock = false;

// It should not move the camera
scene?._onCameraInputObservable.notifyObservers(movePI2);
scene?.onPointerObservable.notifyObservers(movePI2);
expect(camera?.cameraRotation.x).toEqual(cameraRotation.x);
expect(camera?.cameraRotation.y).toEqual(cameraRotation.y);
});
Expand Down

0 comments on commit eb54382

Please sign in to comment.