Skip to content
Snippets Groups Projects
Select Git revision
  • 917d540d53f7b357c2504ff298a6f5310a77e830
  • master default protected
  • rednatco-v2
  • rednatco
  • test
  • ntc-tube-uniform-color
  • ntc-tube-missing-atoms
  • restore-vertex-array-per-program
  • watlas2
  • dnatco_new
  • cleanup-old-nodejs
  • webmmb
  • fix_auth_seq_id
  • update_deps
  • ext_dev
  • ntc_balls
  • nci-2
  • plugin
  • bugfix-0.4.5
  • nci
  • servers
  • v0.5.0-dev.1
  • v0.4.5
  • v0.4.4
  • v0.4.3
  • v0.4.2
  • v0.4.1
  • v0.4.0
  • v0.3.12
  • v0.3.11
  • v0.3.10
  • v0.3.9
  • v0.3.8
  • v0.3.7
  • v0.3.6
  • v0.3.5
  • v0.3.4
  • v0.3.3
  • v0.3.2
  • v0.3.1
  • v0.3.0
41 results

web-api.ts

Blame
  • camera.ts 9.56 KiB
    /**
     * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
     *
     * @author David Sehnal <david.sehnal@gmail.com>
     * @author Alexander Rose <alexander.rose@weirdbyte.de>
     */
    
    import { Mat4, Vec3, Vec4, EPSILON } from '../mol-math/linear-algebra'
    import { Viewport, cameraProject, cameraUnproject } from './camera/util';
    import { Object3D } from '../mol-gl/object3d';
    import { BehaviorSubject } from 'rxjs';
    import { CameraTransitionManager } from './camera/transition';
    
    export { Camera }
    
    // TODO: slab controls that modify near/far planes?
    
    class Camera implements Object3D {
        readonly updatedViewProjection = new BehaviorSubject<Camera>(this);
    
        readonly view: Mat4 = Mat4.identity();
        readonly projection: Mat4 = Mat4.identity();
        readonly projectionView: Mat4 = Mat4.identity();
        readonly inverseProjectionView: Mat4 = Mat4.identity();
    
        readonly viewport: Viewport;
        readonly state: Readonly<Camera.Snapshot> = Camera.createDefaultSnapshot();
        readonly viewOffset: Camera.ViewOffset = {
            enabled: false,
            fullWidth: 1, fullHeight: 1,
            offsetX: 0, offsetY: 0,
            width: 1, height: 1
        }
    
        readonly transition: CameraTransitionManager = new CameraTransitionManager(this);
    
        get position() { return this.state.position; }
        set position(v: Vec3) { Vec3.copy(this.state.position, v); }
    
        get direction() { return this.state.direction; }
        set direction(v: Vec3) { Vec3.copy(this.state.direction, v); }
    
        get up() { return this.state.up; }
        set up(v: Vec3) { Vec3.copy(this.state.up, v); }
    
        get target() { return this.state.target; }
        set target(v: Vec3) { Vec3.copy(this.state.target, v); }
    
        private prevProjection = Mat4.identity();
        private prevView = Mat4.identity();
        private deltaDirection = Vec3.zero();
        private newPosition = Vec3.zero();
    
        updateMatrices() {
            const snapshot = this.state as Camera.Snapshot;
            const height = 2 * Math.tan(snapshot.fov / 2) * Vec3.distance(snapshot.position, snapshot.target);
            snapshot.zoom = this.viewport.height / height;
    
            switch (this.state.mode) {
                case 'orthographic': updateOrtho(this); break;
                case 'perspective': updatePers(this); break;
                default: throw new Error('unknown camera mode');
            }
    
            const changed = !Mat4.areEqual(this.projection, this.prevProjection, EPSILON) || !Mat4.areEqual(this.view, this.prevView, EPSILON);
    
            Mat4.mul(this.projectionView, this.projection, this.view)
            Mat4.invert(this.inverseProjectionView, this.projectionView)