public attach()

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();
                    }));
    }