# EnvironmentControls

class in `3d-tiles-renderer/three`, extends `EventDispatcher`

```js
import { EnvironmentControls } from '3d-tiles-renderer/three';
```

Camera controls for exploring a 3D environment. Supports drag-to-pan, scroll-to-zoom,
right-click-to-rotate, and optional damping/inertia. Works with any Three.js scene.

Example: Drag to pan, right drag or shift drag to orbit, and scroll to zoom

```js
import { TilesRenderer, EnvironmentControls } from '3d-tiles-renderer/three';

// scene, camera and renderer are initialized here

const URL = 'https://raw.githubusercontent.com/NASA-AMMOS/3DTilesSampleData/master/msl-dingo-gap/0528_0260184_to_s64o256_colorize/0528_0260184_to_s64o256_colorize/0528_0260184_to_s64o256_colorize_tileset.json';
const tiles = new TilesRenderer( URL );
tiles.setCamera( camera );
tiles.group.rotation.x = Math.PI / 2;
scene.add( tiles.group );

camera.position.set( 20, 10, 20 );
camera.lookAt( 0, 0, 0 );

const controls = new EnvironmentControls( scene, camera, renderer.domElement );
controls.enableDamping = true;

renderer.setAnimationLoop( () => {

	controls.update();
	camera.updateMatrixWorld();
	tiles.setResolutionFromRenderer( camera, renderer );
	tiles.update();
	renderer.render( scene, camera );

} );
```

## Constructor

```js
new EnvironmentControls( scene?: Object3D, camera?: Camera, domElement?: HTMLElement )
```

- `scene`, `Object3D`, optional, default `null`: The scene to raycast against for surface interaction.
- `camera`, `Camera`, optional, default `null`: The camera to control.
- `domElement`, `HTMLElement`, optional, default `null`: The DOM element to attach pointer events to.

## Properties

### .enabled: boolean

default `true`

Whether the controls are active. When set to false, all input is ignored
and inertia is cleared.

### .cameraRadius: number

default `5`

Minimum camera distance above the surface in world units. Prevents clipping into terrain.

### .rotationSpeed: number

default `1`

Rotation sensitivity multiplier.

### .minAltitude: number

default `0`

Minimum camera angle above the horizon in radians.

### .maxAltitude: number

default `0.45 * Math.PI`

Maximum camera angle above the horizon in radians.

### .minDistance: number

default `10`

Minimum zoom distance in world units.

### .maxDistance: number

default `Infinity`

Maximum zoom distance in world units.

### .minZoom: number

default `0`

Minimum orthographic zoom level.

### .maxZoom: number

default `Infinity`

Maximum orthographic zoom level.

### .zoomSpeed: number

default `1`

Zoom sensitivity multiplier.

### .adjustHeight: boolean

default `true`

When true, the camera height is automatically adjusted to avoid clipping into the terrain.

### .enableDamping: boolean

default `false`

When true, camera movements decelerate gradually after input ends.

### .dampingFactor: number

default `0.15`

Rate of inertia decay per frame when damping is enabled. Lower values produce longer coasting.

### .enableDoubleTapZoom: boolean

default `true`

When true, double clicking or double tapping a point animates a zoom toward it.

### .doubleTapZoomScale: number

default `2`

Factor to zoom in toward the clicked point on a double tap.

### .doubleTapZoomDuration: number

default `0.5`

Duration of the double tap zoom animation in seconds.

### .fallbackPlane: Plane

default `new Plane( UP, 0 )`

Fallback plane used for drag/zoom when no scene geometry is hit.

### .useFallbackPlane: boolean

default `true`

When true, the fallback plane is used when raycasting misses scene geometry.

### .enableFlight: boolean

default `false`

When true, enables keyboard flight: W/A/S/D and arrow keys move forward/back/strafe, Q/E move
up/down, and Shift multiplies speed by `flightSpeedMultiplier`. Right-click or Shift+left-click
enters free-look mode, rotating the camera in place without requiring a surface hit. Only
supported for perspective cameras.

### .flightSpeed: number

default `10`

Base camera speed in world units per second during keyboard flight.

### .flightSpeedMultiplier: number

default `4`

Speed multiplier applied when the fast key is held during flight.

## Methods

### .setScene

```js
.setScene( scene: Object3D )
```

Sets the scene to raycast against for surface-based interaction.

- `scene`, `Object3D`

### .setCamera

```js
.setCamera( camera: Camera )
```

Sets the camera to control.

- `camera`, `Camera`

### .attach

```js
.attach( domElement: HTMLElement )
```

Attaches the controls to a DOM element, registering all pointer and keyboard event listeners.

- `domElement`, `HTMLElement`

### .detach

```js
.detach(  )
```

Detaches the controls from the DOM element, removing all event listeners.

### .getUpDirection

```js
.getUpDirection( point: Vector3, target: Vector3 )
```

Returns the local up direction at a world-space point. Override to provide terrain-aware
up vectors (e.g. ellipsoid normals). Default returns the controls' `up` vector.

- `point`, `Vector3`: World-space point to query.
- `target`, `Vector3`: Target vector to write the result into.

### .getCameraUpDirection

```js
.getCameraUpDirection( target: Vector3 )
```

Returns the local up direction at the camera's current position.

- `target`, `Vector3`: Target vector to write the result into.

### .getPivotPoint

```js
.getPivotPoint( target: Vector3 ): Vector3 | null
```

Returns the current drag or rotation pivot point in world space.

- `target`, `Vector3`: Target vector to write the result into.

Returns `Vector3 | null`: The target vector, or null if no pivot is active.

### .resetState

```js
.resetState(  )
```

Clears the current interaction state, cancelling any active drag, rotate, or zoom.

### .setState

```js
.setState( state?: number, fireEvent?: boolean )
```

Sets the current control state (e.g. `NONE`, `DRAG`, `ROTATE`, `ZOOM`).

- `state`, `number`, optional: One of the exported state constants. Defaults to current state.
- `fireEvent`, `boolean`, optional, default `true`: Whether to dispatch `'start'` and `'end'` events.

### .update

```js
.update( deltaTime?: number )
```

Applies pending input and inertia to the camera. Must be called each frame.

- `deltaTime`, `number`, optional: Time in seconds since the last frame. Defaults to the clock delta, capped at 64ms.

### .adjustCamera

```js
.adjustCamera( camera: Camera )
```

Adjusts the camera to satisfy altitude and distance constraints. Called automatically by `update`.
Override in subclasses to add custom camera adjustment behaviour (e.g. near/far plane updates).

- `camera`, `Camera`

### .dispose

```js
.dispose(  )
```

Disposes of event listeners and internal resources. Calls `detach` if currently attached.
