UNPKG

@deck.gl/core

Version:

deck.gl core library

80 lines (70 loc) 2.85 kB
// deck.gl // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors import Viewport from '../viewports/viewport'; import {getMeterZoom} from '@math.gl/web-mercator'; import {Matrix4, _SphericalCoordinates as SphericalCoordinates} from '@math.gl/core'; export type FirstPersonViewportOptions = { /** Name of the viewport */ id?: string; /** Left offset from the canvas edge, in pixels */ x?: number; /** Top offset from the canvas edge, in pixels */ y?: number; /** Viewport width in pixels */ width?: number; /** Viewport height in pixels */ height?: number; /** Longitude of the camera, in the geospatial case. */ longitude?: number; /** Latitude of the camera, in the geospatial case. */ latitude?: number; /** Meter offsets of the camera from the lng-lat-elevation anchor point. Default `[0, 0, 0]`. */ position?: [number, number, number]; /** Bearing (heading) of the camera in degrees. Default `0` (north). */ bearing?: number; /** Pitch (tilt) of the camera in degrees. Default `0` (horizontal). */ pitch?: number; /** Transform applied to the camera position and direction */ modelMatrix?: number[] | null; /** Custom projection matrix */ projectionMatrix?: number[]; /** The up direction, default positive z axis. */ up?: [number, number, number]; /** Field of view covered by camera, in degrees. Default `75`. */ fovy?: number; /** Distance of near clipping plane. Default `0.1`. */ near?: number; /** Distance of far clipping plane. Default `1000`. */ far?: number; /** Modifier of viewport scale. Corresponds to the number of pixels per meter. Default `1`. */ focalDistance?: number; }; export default class FirstPersonViewport extends Viewport { longitude?: number; latitude?: number; constructor(props: FirstPersonViewportOptions) { // TODO - push direction handling into Matrix4.lookAt const {longitude, latitude, modelMatrix, bearing = 0, pitch = 0, up = [0, 0, 1]} = props; // Always calculate direction from bearing and pitch const spherical = new SphericalCoordinates({ bearing, // Avoid "pixel project matrix not invertible" error pitch: pitch === -90 ? 0.0001 : 90 + pitch }); const dir = spherical.toVector3().normalize(); // Direction is relative to model coordinates, of course const center = modelMatrix ? new Matrix4(modelMatrix).transformAsVector(dir) : dir; // Just the direction. All the positioning is done in viewport.js const zoom = Number.isFinite(latitude) ? getMeterZoom({latitude: latitude as number}) : 0; const scale = Math.pow(2, zoom); const viewMatrix = new Matrix4().lookAt({eye: [0, 0, 0], center, up}).scale(scale); super({ ...props, zoom, viewMatrix }); this.latitude = latitude; this.longitude = longitude; } }