in src/viewer/CustomCameraControls.ts [37:154]
public attach(controls: ICustomCameraControls, viewer: IViewer): void {
if (this._controls) {
throw new MapillaryError('Custom camera controls already attached');
}
this._controls = controls;
const attach$ = new Subject<void>();
const active$ = attach$
.pipe(
switchMap(
() => {
return this._navigator.stateService.state$;
}),
map(
(state: State): boolean => {
return state === State.Custom;
}),
distinctUntilChanged());
const subs = this._subscriptions;
subs.push(active$
.pipe(
startWith(false),
pairwise(),
withLatestFrom(
this._navigator.stateService.reference$,
this._container.renderService.renderCamera$))
.subscribe(
([[deactivate, activate], ref, cam]) => {
if (activate) {
controls.onActivate(
viewer,
cam.perspective.matrixWorldInverse.toArray(),
cam.perspective.projectionMatrix.toArray(),
ref);
} else if (deactivate) {
controls.onDeactivate(viewer);
}
}));
subs.push(active$
.pipe(
switchMap(
active => {
return active ?
this._navigator.stateService.currentState$
.pipe(skip(1)) :
observableEmpty();
}))
.subscribe(
frame => {
controls.onAnimationFrame(viewer, frame.id);
}));
subs.push(active$
.pipe(
switchMap(
active => {
return active ?
this._navigator.stateService.reference$
.pipe(skip(1)) :
observableEmpty();
}))
.subscribe(ref => controls.onReference(viewer, ref)));
subs.push(active$
.pipe(
switchMap(
active => {
return active ?
this._container.renderService.size$
.pipe(skip(1)) :
observableEmpty();
}))
.subscribe(() => controls.onResize(viewer)));
subs.push(
observableCombineLatest(
[
// Include to ensure GL renderer has been initialized
this._container.glRenderer.webGLRenderer$,
this._container.renderService.renderCamera$,
this._navigator.stateService.reference$,
this._navigator.stateService.state$,
])
.pipe(first())
.subscribe(
(): void => {
const projectionMatrixCallback =
(projectionMatrix: number[]) => {
if (!this._controls ||
controls !== this._controls) {
return;
}
this._updateProjectionMatrix(projectionMatrix);
};
const viewMatrixCallback =
(viewMatrix: number[]) => {
if (!this._controls ||
controls !== this._controls) {
return;
}
this._updateViewMatrix(viewMatrix);
};
controls.onAttach(
viewer,
viewMatrixCallback,
projectionMatrixCallback);
attach$.next();
attach$.complete();
}));
}