-
-
Notifications
You must be signed in to change notification settings - Fork 791
/
Copy pathglobe_projection.ts
128 lines (104 loc) · 4.92 KB
/
globe_projection.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import {type ProjectionDefinition, type ProjectionDefinitionSpecification, type ProjectionSpecification, type StylePropertySpecification, latest as styleSpec} from '@maplibre/maplibre-gl-style-spec';
import {DataConstantProperty, type PossiblyEvaluated, Properties, Transitionable, type Transitioning, type TransitionParameters} from '../../style/properties';
import {Evented} from '../../util/evented';
import {EvaluationParameters} from '../../style/evaluation_parameters';
import {MercatorProjection} from './mercator_projection';
import {VerticalPerspectiveProjection} from './vertical_perspective_projection';
import {type Projection, type ProjectionGPUContext, type TileMeshUsage} from './projection';
import {type PreparedShader} from '../../shaders/shaders';
import {type SubdivisionGranularitySetting} from '../../render/subdivision_granularity_settings';
import {type Context} from '../../gl/context';
import {type CanonicalTileID} from '../../source/tile_id';
import {type Mesh} from '../../render/mesh';
type ProjectionProps = {
type: DataConstantProperty<ProjectionDefinition>;
}
type ProjectionPossiblyEvaluated = {
type: ProjectionDefinitionSpecification;
}
const properties: Properties<ProjectionProps> = new Properties({
'type': new DataConstantProperty(styleSpec.projection.type as StylePropertySpecification)
});
export class GlobeProjection extends Evented implements Projection {
properties: PossiblyEvaluated<ProjectionProps, ProjectionPossiblyEvaluated>;
_transitionable: Transitionable<ProjectionProps>;
_transitioning: Transitioning<ProjectionProps>;
_mercatorProjection: MercatorProjection;
_verticalPerspectiveProjection: VerticalPerspectiveProjection;
constructor(projection?: ProjectionSpecification) {
super();
this._transitionable = new Transitionable(properties);
this.setProjection(projection);
this._transitioning = this._transitionable.untransitioned();
this.recalculate(new EvaluationParameters(0));
this._mercatorProjection = new MercatorProjection();
this._verticalPerspectiveProjection = new VerticalPerspectiveProjection();
}
public get transitionState(): number {
const currentProjectionSpecValue = this.properties.get('type');
if (typeof currentProjectionSpecValue === 'string' && currentProjectionSpecValue === 'mercator') {
return 0;
}
if (typeof currentProjectionSpecValue === 'string' && currentProjectionSpecValue === 'vertical-perspective') {
return 1;
}
// HM TODO: check this!
if ('transition' in (currentProjectionSpecValue as any)) {
return (currentProjectionSpecValue as any).transition;
};
return 1;
}
private get currentProjection(): Projection {
return this.useGlobeControls ? this._verticalPerspectiveProjection : this._mercatorProjection;
}
setProjection(projection?: ProjectionSpecification) {
this._transitionable.setValue('type', projection?.type || 'mercator');
}
updateTransitions(parameters: TransitionParameters) {
this._transitioning = this._transitionable.transitioned(parameters, this._transitioning);
}
hasTransition() {
return this._transitioning.hasTransition();
}
recalculate(parameters: EvaluationParameters) {
this.properties = this._transitioning.possiblyEvaluate(parameters);
}
get name(): 'mercator' | 'vertical-perspective' {
return this.currentProjection.name;
}
get useSubdivision(): boolean {
return this.currentProjection.useSubdivision;
}
get shaderVariantName(): string {
return this.currentProjection.shaderVariantName;
}
get shaderDefine(): string {
return this.currentProjection.shaderDefine;
}
get shaderPreludeCode(): PreparedShader {
return this.currentProjection.shaderPreludeCode;
}
get vertexShaderPreludeCode(): string {
return this.currentProjection.vertexShaderPreludeCode;
}
get subdivisionGranularity(): SubdivisionGranularitySetting {
return this.currentProjection.subdivisionGranularity;
}
get useGlobeControls(): boolean {
return this.transitionState > 0;
}
public destroy(): void {
this._mercatorProjection.destroy();
this._verticalPerspectiveProjection.destroy();
}
public isRenderingDirty(): boolean {
return this.hasTransition() || this.currentProjection.isRenderingDirty();
}
public updateGPUdependent(context: ProjectionGPUContext): void {
this._mercatorProjection.updateGPUdependent(context);
this._verticalPerspectiveProjection.updateGPUdependent(context);
}
public getMeshFromTileID(context: Context, _tileID: CanonicalTileID, _hasBorder: boolean, _allowPoles: boolean, _usage: TileMeshUsage): Mesh {
return this.currentProjection.getMeshFromTileID(context, _tileID, _hasBorder, _allowPoles, _usage);
}
}