import { Fog } from "@here/harp-datasource-protocol" ; import { HighPrecisionLineMaterial } from "@here/harp-materials" ; import { RawShaderMaterial } from "@here/harp-materials/lib/RawShaderMaterial" ; import { assert , MathUtils } from "@here/harp-utils" ; import * as THREE from "three" ; import { MapView } from "./MapView" ; /**
 * Manages the fog display in  MapView .
  export class MapViewFog { private m_enabled : boolean = true ; private m_fog : THREE . Fog = new THREE . Fog ( 0x000000 ) ; private m_fogIsDefined : boolean = false ; private m_cachedFog : Fog | undefined ; param m_scene - The scene used in  MapView that contains the map objects.
      constructor ( private m_scene ) { } param value set enabled ( enableFog ) { this . m_enabled = enableFog ; if ( enableFog && this . m_fogIsDefined && this . m_scene . fog === null ) { this . add ( ) ; } else if ( ! enableFog && this . m_scene . fog !== null ) { this . remove ( ) ; } } /**
     * Returns the current fog status, enabled or disabled.
     */ get enabled ( ) : boolean { return this . m_enabled ; } /**
     * Sets the fog depending on the  {@link @here/harp-datasource-protocol#Theme} * instance provided. This function is called when a
     * theme is loaded. Fog is added only if the theme contains a fog definition with a:
     * - `color` property, used to set the fog color.
     * - `startRatio` property, used to set the start distance of the fog as a ratio of the far
     * clipping plane distance.
     *
     *  param theme - A  {@link @here/harp-datasource-protocol#Theme} instance.
      reset ( fog ? ) { this . m_cachedFog = fog ; if ( fog !== undefined && fog . color !== undefined && fog . startRatio !== undefined ) { this . m_fogIsDefined = true ; this . m_fog . color . set ( fog . color ) ; if ( this . m_enabled && this . m_scene . fog === null ) { this . add ( ) ; } } else { this . m_fogIsDefined = false ; if ( this . m_scene . fog !== null ) { this . remove ( ) ; } } } param camera update ( mapView , viewDistance ? ) { if ( this . m_scene . fog !== null && this . m_cachedFog !== undefined && this . m_cachedFog && this . m_cachedFog . startRatio !== undefined && ( mapView . camera . far !== undefined || viewDistance !== undefined ) ) { const viewRange = viewDistance !== undefined ? viewDistance : mapView . camera . far ; const horizontalDensity = 1.0 ; const verticalDensity = 0.0 ; const startRatio = this . m_cachedFog . startRatio ; const endRatio = 1.0 ; assert ( startRatio <= endRatio ) ; const t = Math . abs ( Math . cos ( mapView . tilt ) ) ; const density = MathUtils . smoothStep ( horizontalDensity , verticalDensity , t ) ; this . m_fog . near = THREE . MathUtils . lerp ( viewRange * startRatio , viewRange , 1.0 - density ) ; this . m_fog . far = THREE . MathUtils . lerp ( viewRange * endRatio , viewRange , density ) ; this . m_fog . near = Math . min ( this . m_fog . near , mapView . camera . far ) ; this . m_fog . far = Math . min ( this . m_fog . far , mapView . camera . far ) ; } } /**
     * Handles fog addition.
     */ private add ( ) { this . m_scene . fog = this . m_fog ; this . setFogInRawShaderMaterials ( true ) ; } /**
     * Handles fog removal.
     */ private remove ( ) { this . m_scene . fog = null ; this . setFogInRawShaderMaterials ( false ) ; } see https private setFogInRawShaderMaterials ( enableFog ) { this . m_scene . traverse ( object => { if ( object instanceof THREE . Mesh ) { const material = object . material ; if ( material instanceof THREE . Material && ! ( material instanceof HighPrecisionLineMaterial ) && material . fog !== enableFog ) { material . fog = enableFog ; if ( material instanceof RawShaderMaterial ) { material . invalidateFog ( ) ; } } } } ) ; } }