Alternative FirstPersonController
by felixp
HTML
<script src="https://unpkg.com/deck.gl@latest/dist.min.js"></script>
<script src="https://unpkg.com/@loaders.gl/[email protected]/dist/dist.min.js"></script>
CSS
body {
margin: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
}
JavaScript
/*
* https://deck.gl/docs/api-reference/core/first-person-view
*/
const {DeckGL, Controller, FirstPersonView, PointCloudLayer, COORDINATE_SYSTEM, LinearInterpolator} = deck;
const {PLYLoader} = loaders;
import { Vector3, _SphericalCoordinates as SphericalCoordinates, clamp } from 'https://esm.sh/@math.gl/[email protected]';
// Modified FirstPersonController implementation
class FirstPersonController extends Controller {
ControllerState = FirstPersonState;
transition = {
transitionDuration: 300,
transitionInterpolator: new LinearInterpolator(['position', 'pitch', 'bearing'])
};
}
function mod(value, divisor) {
const modulus = value % divisor;
return modulus < 0 ? divisor + modulus : modulus;
}
// Apply any constraints (mathematical or defined by _viewportProps) to map state
function applyConstraints(props) {
// Ensure pitch and zoom are within specified range
const { pitch, maxPitch, minPitch, longitude, bearing } = props;
props.pitch = clamp(pitch, minPitch, maxPitch);
// Normalize degrees
if (longitude !== null && (longitude < -180 || longitude > 180)) {
props.longitude = mod(longitude + 180, 360) - 180;
}
if (bearing < -180 || bearing > 180) {
props.bearing = mod(bearing + 180, 360) - 180;
}
return props;
}
const MOVEMENT_SPEED = 25;
const PAN_SPEED = 500;
// Adapted from FirstPersonState used in deck.gl FirstPersonController
class FirstPersonState {
getViewportProps() {
return this._viewportProps;
}
getState() {
return this._state;
}
constructor(options) {
const {
/* Viewport arguments */
width, // Width of viewport
height, // Height of viewport
// Position and orientation
position = [0, 0, 0], // typically in meters from anchor point
bearing = 0, // Rotation around y axis
pitch = 0, // Rotation around x axis
// Geospatial anchor
longitude = null,
latitude = null,
maxPitch = 90,
minPitch = -90,
// Model...