@openglobus/og 0.12.3 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/dist/@openglobus/og.esm.js +2 -2
- package/dist/@openglobus/og.esm.js.map +1 -1
- package/dist/@openglobus/og.umd.js +2 -2
- package/dist/@openglobus/og.umd.js.map +1 -1
- package/package.json +7 -7
- package/src/og/Extent.js +3 -3
- package/src/og/Globe.js +277 -275
- package/src/og/ImageCanvas.js +3 -3
- package/src/og/LonLat.js +9 -9
- package/src/og/QueueArray.js +2 -2
- package/src/og/Rectangle.js +5 -5
- package/src/og/bv/Box.js +1 -1
- package/src/og/bv/Sphere.js +2 -2
- package/src/og/camera/Camera.js +1 -1
- package/src/og/camera/PlanetCamera.js +649 -646
- package/src/og/control/LayerSwitcher.js +1 -1
- package/src/og/control/MouseNavigation.js +22 -13
- package/src/og/control/MouseWheelZoomControl.js +2 -2
- package/src/og/control/ScaleControl.js +1 -1
- package/src/og/control/TouchNavigation.js +319 -319
- package/src/og/control/ZoomControl.js +132 -132
- package/src/og/control/visibleExtent/Segment.js +12 -12
- package/src/og/ellipsoid/Ellipsoid.js +577 -567
- package/src/og/entity/BillboardHandler.js +878 -1051
- package/src/og/entity/Entity.js +1 -1
- package/src/og/entity/EntityCollection.js +847 -857
- package/src/og/entity/GeoObjectHandler.js +2 -2
- package/src/og/entity/LabelHandler.js +888 -1040
- package/src/og/entity/LabelWorker.js +0 -6
- package/src/og/entity/PointCloud.js +495 -495
- package/src/og/entity/Polyline.js +2218 -2222
- package/src/og/entity/RayHandler.js +1 -1
- package/src/og/layer/CanvasTiles.js +6 -3
- package/src/og/layer/GeoImage.js +1 -1
- package/src/og/layer/KML.js +5 -5
- package/src/og/layer/Layer.js +804 -752
- package/src/og/layer/Vector.js +997 -1010
- package/src/og/layer/XYZ.js +359 -357
- package/src/og/math/Line2.js +4 -4
- package/src/og/math/Quat.js +2 -2
- package/src/og/math/Ray.js +2 -2
- package/src/og/math/Vec2.js +524 -524
- package/src/og/math/Vec3.js +900 -900
- package/src/og/math/Vec4.js +261 -261
- package/src/og/math.js +397 -398
- package/src/og/quadTree/EntityCollectionNode.js +389 -387
- package/src/og/renderer/Renderer.js +14 -20
- package/src/og/renderer/RendererEvents.js +1034 -1045
- package/src/og/scene/Planet.js +12 -9
- package/src/og/scene/RenderNode.js +347 -354
- package/src/og/segment/Segment.js +3 -1
- package/src/og/segment/SegmentLonLat.js +1 -4
- package/src/og/shaders/billboard.js +220 -204
- package/src/og/shaders/drawnode.js +603 -603
- package/src/og/shaders/label.js +595 -456
- package/src/og/shaders/polyline.js +365 -361
- package/src/og/terrain/MapboxTerrain.js +1 -1
- package/src/og/utils/FontAtlas.js +209 -200
- package/src/og/utils/GeoImageCreator.js +4 -5
- package/src/og/utils/TextureAtlas.js +4 -4
- package/src/og/utils/VectorTileCreator.js +414 -414
- package/src/og/utils/shared.js +1 -1
- package/src/og/webgl/Handler.js +28 -60
- package/src/og/webgl/Multisample.js +260 -260
- package/src/og/webgl/Program.js +411 -396
- package/types/bv/Box.d.ts +1 -1
- package/types/bv/Sphere.d.ts +1 -1
- package/types/camera/PlanetCamera.d.ts +3 -3
- package/types/control/LayerSwitcher.d.ts +1 -1
- package/types/ellipsoid/Ellipsoid.d.ts +9 -2
- package/types/entity/BillboardHandler.d.ts +0 -4
- package/types/entity/EntityCollection.d.ts +0 -8
- package/types/entity/LabelHandler.d.ts +0 -2
- package/types/entity/Polyline.d.ts +1 -1
- package/types/layer/KML.d.ts +11 -11
- package/types/layer/Layer.d.ts +5 -0
- package/types/layer/Vector.d.ts +1 -8
- package/types/math/Line2.d.ts +4 -4
- package/types/math/Ray.d.ts +2 -2
- package/types/math/Vec2.d.ts +1 -1
- package/types/math/Vec3.d.ts +1 -1
- package/types/math/Vec4.d.ts +2 -2
- package/types/math.d.ts +1 -1
- package/types/renderer/Renderer.d.ts +1 -1
- package/types/renderer/RendererEvents.d.ts +1 -1
- package/types/shaders/label.d.ts +1 -1
- package/types/utils/FontAtlas.d.ts +3 -2
- package/types/utils/TextureAtlas.d.ts +3 -3
- package/types/utils/VectorTileCreator.d.ts +4 -4
- package/types/utils/shared.d.ts +1 -1
- package/types/webgl/Handler.d.ts +6 -31
- package/types/webgl/Program.d.ts +2 -0
|
@@ -1,651 +1,654 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module og/camera/PlanetCamera
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
"use strict";
|
|
6
|
-
|
|
7
|
-
import * as math from "../math.js";
|
|
8
|
-
import * as mercator from "../mercator.js";
|
|
9
|
-
import { Camera } from "./Camera.js";
|
|
10
|
-
import { Vec3 } from "../math/Vec3.js";
|
|
11
|
-
import { Key } from "../Lock.js";
|
|
12
|
-
import { LonLat } from "../LonLat.js";
|
|
13
|
-
import { Ray } from "../math/Ray.js";
|
|
14
|
-
import { Quat } from "../math/Quat.js";
|
|
15
|
-
import { Mat4 } from "../math/Mat4.js";
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Planet camera.
|
|
19
|
-
* @class
|
|
20
|
-
* @extends {Camera}
|
|
21
|
-
* @param {RenderNode} planet - Planet render node.
|
|
22
|
-
* @param {Object} [options] - Planet camera options:
|
|
23
|
-
* @param {Object} [options.name] - Camera name.
|
|
24
|
-
* @param {number} [options.viewAngle=37] - Camera angle of view. Default is 35.0
|
|
25
|
-
* @param {number} [options.near] - Camera near plane distance. Default is 1.0
|
|
26
|
-
* @param {number} [options.far] - Camera far plane distance. Deafult is og.math.MAX
|
|
27
|
-
* @param {number} [options.minAltitude] - Minimal altitude for the camera. Deafult is
|
|
28
|
-
* @param {number} [options.maxAltitude] - Maximal altitude for the camera. Deafult is 20000000
|
|
29
|
-
* @param {Vec3} [options.eye] - Camera eye position. Default (0,0,0)
|
|
30
|
-
* @param {Vec3} [options.look] - Camera look position. Default (0,0,0)
|
|
31
|
-
* @param {Vec3} [options.up] - Camera eye position. Default (0,1,0)
|
|
32
|
-
*/
|
|
33
|
-
class PlanetCamera extends Camera {
|
|
34
|
-
/**
|
|
35
|
-
* @param {RenderNode} planet - Planet render node.
|
|
36
|
-
* @param {Object} [options] - Planet camera options:
|
|
37
|
-
*/
|
|
38
|
-
constructor(planet, options) {
|
|
39
|
-
super(planet.renderer, {
|
|
40
|
-
frustums: [
|
|
41
|
-
[1, 100 + 0.075],
|
|
42
|
-
[100, 1000 + 0.075],
|
|
43
|
-
[1000, 1e6 + 10000],
|
|
44
|
-
[1e6, 1e9]
|
|
45
|
-
], //[[1, 1e3 + 100], [1e3, 1e6 + 10000], [1e6, 1e9]]*/
|
|
1
|
+
/**
|
|
2
|
+
* @module og/camera/PlanetCamera
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
import * as math from "../math.js";
|
|
8
|
+
import * as mercator from "../mercator.js";
|
|
9
|
+
import { Camera } from "./Camera.js";
|
|
10
|
+
import { Vec3 } from "../math/Vec3.js";
|
|
11
|
+
import { Key } from "../Lock.js";
|
|
12
|
+
import { LonLat } from "../LonLat.js";
|
|
13
|
+
import { Ray } from "../math/Ray.js";
|
|
14
|
+
import { Quat } from "../math/Quat.js";
|
|
15
|
+
import { Mat4 } from "../math/Mat4.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Planet camera.
|
|
19
|
+
* @class
|
|
20
|
+
* @extends {Camera}
|
|
21
|
+
* @param {RenderNode} planet - Planet render node.
|
|
22
|
+
* @param {Object} [options] - Planet camera options:
|
|
23
|
+
* @param {Object} [options.name] - Camera name.
|
|
24
|
+
* @param {number} [options.viewAngle=37] - Camera angle of view. Default is 35.0
|
|
25
|
+
* @param {number} [options.near] - Camera near plane distance. Default is 1.0
|
|
26
|
+
* @param {number} [options.far] - Camera far plane distance. Deafult is og.math.MAX
|
|
27
|
+
* @param {number} [options.minAltitude] - Minimal altitude for the camera. Deafult is 5
|
|
28
|
+
* @param {number} [options.maxAltitude] - Maximal altitude for the camera. Deafult is 20000000
|
|
29
|
+
* @param {Vec3} [options.eye] - Camera eye position. Default (0,0,0)
|
|
30
|
+
* @param {Vec3} [options.look] - Camera look position. Default (0,0,0)
|
|
31
|
+
* @param {Vec3} [options.up] - Camera eye position. Default (0,1,0)
|
|
32
|
+
*/
|
|
33
|
+
class PlanetCamera extends Camera {
|
|
34
|
+
/**
|
|
35
|
+
* @param {RenderNode} planet - Planet render node.
|
|
36
|
+
* @param {Object} [options] - Planet camera options:
|
|
37
|
+
*/
|
|
38
|
+
constructor(planet, options) {
|
|
39
|
+
super(planet.renderer, {
|
|
40
|
+
frustums: [
|
|
41
|
+
[1, 100 + 0.075],
|
|
42
|
+
[100, 1000 + 0.075],
|
|
43
|
+
[1000, 1e6 + 10000],
|
|
44
|
+
[1e6, 1e9]
|
|
45
|
+
], //[[1, 1e3 + 100], [1e3, 1e6 + 10000], [1e6, 1e9]]*/
|
|
46
46
|
...options
|
|
47
|
-
}
|
|
48
|
-
);
|
|
49
|
-
/**
|
|
50
|
-
* Assigned camera's planet.
|
|
51
|
-
* @public
|
|
52
|
-
* @type {Planet}
|
|
53
|
-
*/
|
|
54
|
-
this.planet = planet;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Minimal alltitude that camera can reach over the terrain.
|
|
58
|
-
* @public
|
|
59
|
-
* @type {number}
|
|
60
|
-
*/
|
|
61
|
-
this.minAltitude = options.minAltitude ||
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Maximal alltitude that camera can reach over the globe.
|
|
65
|
-
* @public
|
|
66
|
-
* @type {number}
|
|
67
|
-
*/
|
|
68
|
-
this.maxAltitude = options.maxAltitude || 20000000;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Current geographical degree position.
|
|
72
|
-
* @protected
|
|
73
|
-
* @type {LonLat}
|
|
74
|
-
*/
|
|
75
|
-
this._lonLat = this.planet.ellipsoid.cartesianToLonLat(this.eye);
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Current geographical mercator position.
|
|
79
|
-
* @protected
|
|
80
|
-
* @type {LonLat}
|
|
81
|
-
*/
|
|
82
|
-
this._lonLatMerc = this._lonLat.forwardMercator();
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Current altitude.
|
|
86
|
-
* @protected
|
|
87
|
-
* @type {number}
|
|
88
|
-
*/
|
|
89
|
-
this._terrainAltitude = this._lonLat.height;
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Cartesian coordinates on the terrain.
|
|
93
|
-
* @protected
|
|
94
|
-
* @type {Vec3}
|
|
95
|
-
*/
|
|
96
|
-
this._terrainPoint = new Vec3();
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Quad node that camera flies over.
|
|
100
|
-
* @protected
|
|
101
|
-
* @type {quadTree.Node}
|
|
102
|
-
*/
|
|
103
|
-
this._insideSegment = null;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Coordinates that depends on what segment class we are fling over.
|
|
107
|
-
* It can be WGS84 or Mercator coordinates. Gets in og.quadTree.Node
|
|
108
|
-
* @protected
|
|
109
|
-
* @type {LonLat}
|
|
110
|
-
*/
|
|
111
|
-
this._insideSegmentPosition = new LonLat();
|
|
112
|
-
|
|
113
|
-
this.slope = 0;
|
|
114
|
-
|
|
115
|
-
this._keyLock = new Key();
|
|
116
|
-
|
|
117
|
-
// Camera's flying frames
|
|
118
|
-
this._framesArr = [];
|
|
119
|
-
this._framesCounter = 0;
|
|
120
|
-
this._numFrames = 50;
|
|
121
|
-
this._completeCallback = null;
|
|
122
|
-
this._flying = false;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Updates camera view space.
|
|
127
|
-
* @public
|
|
128
|
-
* @virtual
|
|
129
|
-
*/
|
|
130
|
-
update() {
|
|
131
|
-
this.events.stopPropagation();
|
|
132
|
-
|
|
133
|
-
let maxAlt = this.maxAltitude + this.planet.ellipsoid._a;
|
|
134
|
-
|
|
135
|
-
if (this.eye.length() > maxAlt) {
|
|
136
|
-
this.eye.copy(this.eye.normal().scale(maxAlt));
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
super.update();
|
|
140
|
-
this.updateGeodeticPosition();
|
|
141
|
-
this.eyeNorm = this.eye.normal();
|
|
142
|
-
this.slope = this._b.dot(this.eyeNorm);
|
|
143
|
-
this.events.dispatch(this.events.viewchange, this);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
updateGeodeticPosition() {
|
|
147
|
-
this._lonLat = this.planet.ellipsoid.cartesianToLonLat(this.eye);
|
|
148
|
-
if (Math.abs(this._lonLat.lat) <= mercator.MAX_LAT) {
|
|
149
|
-
this._lonLatMerc = this._lonLat.forwardMercator();
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Sets altitude over the terrain.
|
|
155
|
-
* @public
|
|
156
|
-
* @param {number} alt - Altitude over the terrain.
|
|
157
|
-
*/
|
|
158
|
-
setAltitude(alt) {
|
|
159
|
-
var n = this.eye.normal();
|
|
160
|
-
var t = this._terrainPoint;
|
|
161
|
-
this.eye.x = n.x * alt + t.x;
|
|
162
|
-
this.eye.y = n.y * alt + t.y;
|
|
163
|
-
this.eye.z = n.z * alt + t.z;
|
|
164
|
-
this._terrainAltitude = alt;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Gets altitude over the terrain.
|
|
169
|
-
* @public
|
|
170
|
-
*/
|
|
171
|
-
getAltitude() {
|
|
172
|
-
return this._terrainAltitude;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Places camera to view to the geographical point.
|
|
177
|
-
* @public
|
|
178
|
-
* @param {LonLat} lonlat - New camera and camera view position.
|
|
179
|
-
* @param {LonLat} [lookLonLat] - Look up coordinates.
|
|
180
|
-
* @param {Vec3} [up] - Camera UP vector. Default (0,1,0)
|
|
181
|
-
*/
|
|
182
|
-
setLonLat(lonlat, lookLonLat, up) {
|
|
183
|
-
this.stopFlying();
|
|
184
|
-
this._lonLat.set(lonlat.lon, lonlat.lat, lonlat.height || this._lonLat.height);
|
|
185
|
-
var el = this.planet.ellipsoid;
|
|
186
|
-
var newEye = el.lonLatToCartesian(this._lonLat);
|
|
187
|
-
var newLook = lookLonLat ? el.lonLatToCartesian(lookLonLat) : Vec3.ZERO;
|
|
188
|
-
this.set(newEye, newLook, up || Vec3.UP);
|
|
189
|
-
this.update();
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Returns camera geographical position.
|
|
194
|
-
* @public
|
|
195
|
-
* @returns {LonLat}
|
|
196
|
-
*/
|
|
197
|
-
getLonLat() {
|
|
198
|
-
return this._lonLat;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Returns camera height.
|
|
203
|
-
* @public
|
|
204
|
-
* @returns {number}
|
|
205
|
-
*/
|
|
206
|
-
getHeight() {
|
|
207
|
-
return this._lonLat.height;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Gets position by viewable extent.
|
|
212
|
-
* @public
|
|
213
|
-
* @param {Extent} extent - Viewable extent.
|
|
214
|
-
* @param {Number} height - Camera height
|
|
215
|
-
* @returns {Vec3}
|
|
216
|
-
*/
|
|
217
|
-
getExtentPosition(extent, height) {
|
|
218
|
-
var north = extent.getNorth();
|
|
219
|
-
var south = extent.getSouth();
|
|
220
|
-
var east = extent.getEast();
|
|
221
|
-
var west = extent.getWest();
|
|
222
|
-
|
|
223
|
-
if (west > east) {
|
|
224
|
-
east += 360;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
var e = this.planet.ellipsoid;
|
|
228
|
-
|
|
229
|
-
var cart = new LonLat(east, north);
|
|
230
|
-
var northEast = e.lonLatToCartesian(cart);
|
|
231
|
-
cart.lat = south;
|
|
232
|
-
var southEast = e.lonLatToCartesian(cart);
|
|
233
|
-
cart.lon = west;
|
|
234
|
-
var southWest = e.lonLatToCartesian(cart);
|
|
235
|
-
cart.lat = north;
|
|
236
|
-
var northWest = e.lonLatToCartesian(cart);
|
|
237
|
-
|
|
238
|
-
var center = Vec3.sub(northEast, southWest).scale(0.5).addA(southWest);
|
|
239
|
-
|
|
240
|
-
var mag = center.length();
|
|
241
|
-
if (mag < 0.000001) {
|
|
242
|
-
cart.lon = (east + west) * 0.5;
|
|
243
|
-
cart.lat = (north + south) * 0.5;
|
|
244
|
-
center = e.lonLatToCartesian(cart);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
northWest.subA(center);
|
|
248
|
-
southEast.subA(center);
|
|
249
|
-
northEast.subA(center);
|
|
250
|
-
southWest.subA(center);
|
|
251
|
-
|
|
252
|
-
var direction = center.normal(); // ellipsoid.getSurfaceNormal(center).negate().normalize();
|
|
253
|
-
var right = direction.cross(Vec3.UP).normalize();
|
|
254
|
-
var up = right.cross(direction).normalize();
|
|
255
|
-
|
|
256
|
-
var _h = Math.max(
|
|
257
|
-
Math.abs(up.dot(northWest)),
|
|
258
|
-
Math.abs(up.dot(southEast)),
|
|
259
|
-
Math.abs(up.dot(northEast)),
|
|
260
|
-
Math.abs(up.dot(southWest))
|
|
261
|
-
);
|
|
262
|
-
|
|
263
|
-
var _w = Math.max(
|
|
264
|
-
Math.abs(right.dot(northWest)),
|
|
265
|
-
Math.abs(right.dot(southEast)),
|
|
266
|
-
Math.abs(right.dot(northEast)),
|
|
267
|
-
Math.abs(right.dot(southWest))
|
|
268
|
-
);
|
|
269
|
-
|
|
270
|
-
var tanPhi = Math.tan(this._viewAngle * math.RADIANS * 0.5);
|
|
271
|
-
var tanTheta = this._aspect * tanPhi;
|
|
272
|
-
var d = Math.max(_w / tanTheta, _h / tanPhi);
|
|
273
|
-
|
|
274
|
-
center.normalize();
|
|
275
|
-
center.scale(mag + d + (height || 0));
|
|
276
|
-
|
|
277
|
-
return center;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* View current extent.
|
|
282
|
-
* @public
|
|
283
|
-
* @param {Extent} extent - Current extent.
|
|
284
|
-
*/
|
|
285
|
-
viewExtent(extent, height) {
|
|
286
|
-
this.stopFlying();
|
|
287
|
-
this.set(this.getExtentPosition(extent, height), Vec3.ZERO, Vec3.UP);
|
|
288
|
-
this.update();
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Flies to the current extent.
|
|
293
|
-
* @public
|
|
294
|
-
* @param {Extent} extent - Current extent.
|
|
295
|
-
* @param {Vec3} [up] - Camera UP in the end of flying. Default - (0,1,0)
|
|
296
|
-
* @param {Number} [ampl] - Altitude amplitude factor.
|
|
297
|
-
* @param {cameraCallback} [completeCallback] - Callback that calls after flying when flying is finished.
|
|
298
|
-
* @param {cameraCallback} [startCallback] - Callback that calls befor the flying begins.
|
|
299
|
-
* @param [frameCallback]
|
|
300
|
-
*/
|
|
301
|
-
flyExtent(extent, height, up, ampl, completeCallback, startCallback, frameCallback) {
|
|
302
|
-
this.flyCartesian(
|
|
303
|
-
this.getExtentPosition(extent, height),
|
|
304
|
-
Vec3.ZERO,
|
|
305
|
-
up,
|
|
306
|
-
ampl,
|
|
307
|
-
completeCallback,
|
|
308
|
-
startCallback,
|
|
309
|
-
frameCallback
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
viewDistance(cartesian, distance = 10000.0) {
|
|
314
|
-
let p0 = this.eye.add(this.getForward().scaleTo(distance));
|
|
315
|
-
let _rot = Quat.getRotationBetweenVectors(p0.normal(), cartesian.normal());
|
|
316
|
-
if (_rot.isZero()) {
|
|
317
|
-
let newPos = cartesian.add(this.getBackward().scaleTo(distance));
|
|
318
|
-
this.set(newPos, cartesian);
|
|
319
|
-
} else {
|
|
320
|
-
let newPos = cartesian.add(_rot.mulVec3(this.getBackward()).scale(distance)),
|
|
321
|
-
newUp = _rot.mulVec3(this.getUp());
|
|
322
|
-
this.set(newPos, cartesian, newUp);
|
|
323
|
-
}
|
|
324
|
-
this.update();
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
flyDistance(
|
|
328
|
-
cartesian,
|
|
329
|
-
distance = 10000.0,
|
|
330
|
-
ampl = 0.0,
|
|
331
|
-
completeCallback,
|
|
332
|
-
startCallback,
|
|
333
|
-
frameCallback
|
|
334
|
-
) {
|
|
335
|
-
let p0 = this.eye.add(this.getForward().scaleTo(distance));
|
|
336
|
-
let _rot = Quat.getRotationBetweenVectors(p0.normal(), cartesian.normal());
|
|
337
|
-
if (_rot.isZero()) {
|
|
338
|
-
let newPos = cartesian.add(this.getBackward().scaleTo(distance));
|
|
339
|
-
this.set(newPos, cartesian);
|
|
340
|
-
} else {
|
|
341
|
-
let newPos = cartesian.add(_rot.mulVec3(this.getBackward()).scale(distance)),
|
|
342
|
-
newUp = _rot.mulVec3(this.getUp());
|
|
343
|
-
this.flyCartesian(
|
|
344
|
-
newPos,
|
|
345
|
-
cartesian,
|
|
346
|
-
newUp,
|
|
347
|
-
ampl,
|
|
348
|
-
completeCallback,
|
|
349
|
-
startCallback,
|
|
350
|
-
frameCallback
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Flies to the cartesian coordinates.
|
|
357
|
-
* @public
|
|
358
|
-
* @param {Vec3} cartesian - Finish cartesian coordinates.
|
|
359
|
-
* @param {Vec3} [look] - Camera LOOK in the end of flying. Default - (0,0,0)
|
|
360
|
-
* @param {Vec3} [up] - Camera UP vector in the end of flying. Default - (0,1,0)
|
|
361
|
-
* @param {Number} [ampl=1.0] - Altitude amplitude factor.
|
|
362
|
-
* @param {cameraCallback} [completeCallback] - Callback that calls after flying when flying is finished.
|
|
363
|
-
* @param {cameraCallback} [startCallback] - Callback that calls befor the flying begins.
|
|
364
|
-
* @param [frameCallback]
|
|
365
|
-
*/
|
|
366
|
-
flyCartesian(cartesian, look, up, ampl = 1.0, completeCallback, startCallback, frameCallback) {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
var
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
var
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
var
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
var
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
var
|
|
402
|
-
|
|
403
|
-
var
|
|
404
|
-
|
|
405
|
-
var
|
|
406
|
-
var
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
var
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
var
|
|
434
|
-
var
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
*
|
|
456
|
-
* @
|
|
457
|
-
* @param {
|
|
458
|
-
* @param {
|
|
459
|
-
* @param {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
this.
|
|
483
|
-
this.
|
|
484
|
-
|
|
485
|
-
this.
|
|
486
|
-
this.
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
*
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
*
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
var
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
let
|
|
550
|
-
|
|
551
|
-
let
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
/**
|
|
50
|
+
* Assigned camera's planet.
|
|
51
|
+
* @public
|
|
52
|
+
* @type {Planet}
|
|
53
|
+
*/
|
|
54
|
+
this.planet = planet;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Minimal alltitude that camera can reach over the terrain.
|
|
58
|
+
* @public
|
|
59
|
+
* @type {number}
|
|
60
|
+
*/
|
|
61
|
+
this.minAltitude = options.minAltitude || 5;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Maximal alltitude that camera can reach over the globe.
|
|
65
|
+
* @public
|
|
66
|
+
* @type {number}
|
|
67
|
+
*/
|
|
68
|
+
this.maxAltitude = options.maxAltitude || 20000000;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Current geographical degree position.
|
|
72
|
+
* @protected
|
|
73
|
+
* @type {LonLat}
|
|
74
|
+
*/
|
|
75
|
+
this._lonLat = this.planet.ellipsoid.cartesianToLonLat(this.eye);
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Current geographical mercator position.
|
|
79
|
+
* @protected
|
|
80
|
+
* @type {LonLat}
|
|
81
|
+
*/
|
|
82
|
+
this._lonLatMerc = this._lonLat.forwardMercator();
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Current altitude.
|
|
86
|
+
* @protected
|
|
87
|
+
* @type {number}
|
|
88
|
+
*/
|
|
89
|
+
this._terrainAltitude = this._lonLat.height;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Cartesian coordinates on the terrain.
|
|
93
|
+
* @protected
|
|
94
|
+
* @type {Vec3}
|
|
95
|
+
*/
|
|
96
|
+
this._terrainPoint = new Vec3();
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Quad node that camera flies over.
|
|
100
|
+
* @protected
|
|
101
|
+
* @type {quadTree.Node}
|
|
102
|
+
*/
|
|
103
|
+
this._insideSegment = null;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Coordinates that depends on what segment class we are fling over.
|
|
107
|
+
* It can be WGS84 or Mercator coordinates. Gets in og.quadTree.Node
|
|
108
|
+
* @protected
|
|
109
|
+
* @type {LonLat}
|
|
110
|
+
*/
|
|
111
|
+
this._insideSegmentPosition = new LonLat();
|
|
112
|
+
|
|
113
|
+
this.slope = 0;
|
|
114
|
+
|
|
115
|
+
this._keyLock = new Key();
|
|
116
|
+
|
|
117
|
+
// Camera's flying frames
|
|
118
|
+
this._framesArr = [];
|
|
119
|
+
this._framesCounter = 0;
|
|
120
|
+
this._numFrames = 50;
|
|
121
|
+
this._completeCallback = null;
|
|
122
|
+
this._flying = false;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Updates camera view space.
|
|
127
|
+
* @public
|
|
128
|
+
* @virtual
|
|
129
|
+
*/
|
|
130
|
+
update() {
|
|
131
|
+
this.events.stopPropagation();
|
|
132
|
+
|
|
133
|
+
let maxAlt = this.maxAltitude + this.planet.ellipsoid._a;
|
|
134
|
+
|
|
135
|
+
if (this.eye.length() > maxAlt) {
|
|
136
|
+
this.eye.copy(this.eye.normal().scale(maxAlt));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
super.update();
|
|
140
|
+
this.updateGeodeticPosition();
|
|
141
|
+
this.eyeNorm = this.eye.normal();
|
|
142
|
+
this.slope = this._b.dot(this.eyeNorm);
|
|
143
|
+
this.events.dispatch(this.events.viewchange, this);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
updateGeodeticPosition() {
|
|
147
|
+
this._lonLat = this.planet.ellipsoid.cartesianToLonLat(this.eye);
|
|
148
|
+
if (Math.abs(this._lonLat.lat) <= mercator.MAX_LAT) {
|
|
149
|
+
this._lonLatMerc = this._lonLat.forwardMercator();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Sets altitude over the terrain.
|
|
155
|
+
* @public
|
|
156
|
+
* @param {number} alt - Altitude over the terrain.
|
|
157
|
+
*/
|
|
158
|
+
setAltitude(alt) {
|
|
159
|
+
var n = this.eye.normal();
|
|
160
|
+
var t = this._terrainPoint;
|
|
161
|
+
this.eye.x = n.x * alt + t.x;
|
|
162
|
+
this.eye.y = n.y * alt + t.y;
|
|
163
|
+
this.eye.z = n.z * alt + t.z;
|
|
164
|
+
this._terrainAltitude = alt;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Gets altitude over the terrain.
|
|
169
|
+
* @public
|
|
170
|
+
*/
|
|
171
|
+
getAltitude() {
|
|
172
|
+
return this._terrainAltitude;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Places camera to view to the geographical point.
|
|
177
|
+
* @public
|
|
178
|
+
* @param {LonLat} lonlat - New camera and camera view position.
|
|
179
|
+
* @param {LonLat} [lookLonLat] - Look up coordinates.
|
|
180
|
+
* @param {Vec3} [up] - Camera UP vector. Default (0,1,0)
|
|
181
|
+
*/
|
|
182
|
+
setLonLat(lonlat, lookLonLat, up) {
|
|
183
|
+
this.stopFlying();
|
|
184
|
+
this._lonLat.set(lonlat.lon, lonlat.lat, lonlat.height || this._lonLat.height);
|
|
185
|
+
var el = this.planet.ellipsoid;
|
|
186
|
+
var newEye = el.lonLatToCartesian(this._lonLat);
|
|
187
|
+
var newLook = lookLonLat ? el.lonLatToCartesian(lookLonLat) : Vec3.ZERO;
|
|
188
|
+
this.set(newEye, newLook, up || Vec3.UP);
|
|
189
|
+
this.update();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Returns camera geographical position.
|
|
194
|
+
* @public
|
|
195
|
+
* @returns {LonLat}
|
|
196
|
+
*/
|
|
197
|
+
getLonLat() {
|
|
198
|
+
return this._lonLat;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Returns camera height.
|
|
203
|
+
* @public
|
|
204
|
+
* @returns {number}
|
|
205
|
+
*/
|
|
206
|
+
getHeight() {
|
|
207
|
+
return this._lonLat.height;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Gets position by viewable extent.
|
|
212
|
+
* @public
|
|
213
|
+
* @param {Extent} extent - Viewable extent.
|
|
214
|
+
* @param {Number} height - Camera height
|
|
215
|
+
* @returns {Vec3}
|
|
216
|
+
*/
|
|
217
|
+
getExtentPosition(extent, height) {
|
|
218
|
+
var north = extent.getNorth();
|
|
219
|
+
var south = extent.getSouth();
|
|
220
|
+
var east = extent.getEast();
|
|
221
|
+
var west = extent.getWest();
|
|
222
|
+
|
|
223
|
+
if (west > east) {
|
|
224
|
+
east += 360;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
var e = this.planet.ellipsoid;
|
|
228
|
+
|
|
229
|
+
var cart = new LonLat(east, north);
|
|
230
|
+
var northEast = e.lonLatToCartesian(cart);
|
|
231
|
+
cart.lat = south;
|
|
232
|
+
var southEast = e.lonLatToCartesian(cart);
|
|
233
|
+
cart.lon = west;
|
|
234
|
+
var southWest = e.lonLatToCartesian(cart);
|
|
235
|
+
cart.lat = north;
|
|
236
|
+
var northWest = e.lonLatToCartesian(cart);
|
|
237
|
+
|
|
238
|
+
var center = Vec3.sub(northEast, southWest).scale(0.5).addA(southWest);
|
|
239
|
+
|
|
240
|
+
var mag = center.length();
|
|
241
|
+
if (mag < 0.000001) {
|
|
242
|
+
cart.lon = (east + west) * 0.5;
|
|
243
|
+
cart.lat = (north + south) * 0.5;
|
|
244
|
+
center = e.lonLatToCartesian(cart);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
northWest.subA(center);
|
|
248
|
+
southEast.subA(center);
|
|
249
|
+
northEast.subA(center);
|
|
250
|
+
southWest.subA(center);
|
|
251
|
+
|
|
252
|
+
var direction = center.normal(); // ellipsoid.getSurfaceNormal(center).negate().normalize();
|
|
253
|
+
var right = direction.cross(Vec3.UP).normalize();
|
|
254
|
+
var up = right.cross(direction).normalize();
|
|
255
|
+
|
|
256
|
+
var _h = Math.max(
|
|
257
|
+
Math.abs(up.dot(northWest)),
|
|
258
|
+
Math.abs(up.dot(southEast)),
|
|
259
|
+
Math.abs(up.dot(northEast)),
|
|
260
|
+
Math.abs(up.dot(southWest))
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
var _w = Math.max(
|
|
264
|
+
Math.abs(right.dot(northWest)),
|
|
265
|
+
Math.abs(right.dot(southEast)),
|
|
266
|
+
Math.abs(right.dot(northEast)),
|
|
267
|
+
Math.abs(right.dot(southWest))
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
var tanPhi = Math.tan(this._viewAngle * math.RADIANS * 0.5);
|
|
271
|
+
var tanTheta = this._aspect * tanPhi;
|
|
272
|
+
var d = Math.max(_w / tanTheta, _h / tanPhi);
|
|
273
|
+
|
|
274
|
+
center.normalize();
|
|
275
|
+
center.scale(mag + d + (height || 0));
|
|
276
|
+
|
|
277
|
+
return center;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* View current extent.
|
|
282
|
+
* @public
|
|
283
|
+
* @param {Extent} extent - Current extent.
|
|
284
|
+
*/
|
|
285
|
+
viewExtent(extent, height) {
|
|
286
|
+
this.stopFlying();
|
|
287
|
+
this.set(this.getExtentPosition(extent, height), Vec3.ZERO, Vec3.UP);
|
|
288
|
+
this.update();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Flies to the current extent.
|
|
293
|
+
* @public
|
|
294
|
+
* @param {Extent} extent - Current extent.
|
|
295
|
+
* @param {Vec3} [up] - Camera UP in the end of flying. Default - (0,1,0)
|
|
296
|
+
* @param {Number} [ampl] - Altitude amplitude factor.
|
|
297
|
+
* @param {cameraCallback} [completeCallback] - Callback that calls after flying when flying is finished.
|
|
298
|
+
* @param {cameraCallback} [startCallback] - Callback that calls befor the flying begins.
|
|
299
|
+
* @param [frameCallback]
|
|
300
|
+
*/
|
|
301
|
+
flyExtent(extent, height, up, ampl, completeCallback, startCallback, frameCallback) {
|
|
302
|
+
this.flyCartesian(
|
|
303
|
+
this.getExtentPosition(extent, height),
|
|
304
|
+
Vec3.ZERO,
|
|
305
|
+
up,
|
|
306
|
+
ampl,
|
|
307
|
+
completeCallback,
|
|
308
|
+
startCallback,
|
|
309
|
+
frameCallback
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
viewDistance(cartesian, distance = 10000.0) {
|
|
314
|
+
let p0 = this.eye.add(this.getForward().scaleTo(distance));
|
|
315
|
+
let _rot = Quat.getRotationBetweenVectors(p0.normal(), cartesian.normal());
|
|
316
|
+
if (_rot.isZero()) {
|
|
317
|
+
let newPos = cartesian.add(this.getBackward().scaleTo(distance));
|
|
318
|
+
this.set(newPos, cartesian);
|
|
319
|
+
} else {
|
|
320
|
+
let newPos = cartesian.add(_rot.mulVec3(this.getBackward()).scale(distance)),
|
|
321
|
+
newUp = _rot.mulVec3(this.getUp());
|
|
322
|
+
this.set(newPos, cartesian, newUp);
|
|
323
|
+
}
|
|
324
|
+
this.update();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
flyDistance(
|
|
328
|
+
cartesian,
|
|
329
|
+
distance = 10000.0,
|
|
330
|
+
ampl = 0.0,
|
|
331
|
+
completeCallback,
|
|
332
|
+
startCallback,
|
|
333
|
+
frameCallback
|
|
334
|
+
) {
|
|
335
|
+
let p0 = this.eye.add(this.getForward().scaleTo(distance));
|
|
336
|
+
let _rot = Quat.getRotationBetweenVectors(p0.normal(), cartesian.normal());
|
|
337
|
+
if (_rot.isZero()) {
|
|
338
|
+
let newPos = cartesian.add(this.getBackward().scaleTo(distance));
|
|
339
|
+
this.set(newPos, cartesian);
|
|
340
|
+
} else {
|
|
341
|
+
let newPos = cartesian.add(_rot.mulVec3(this.getBackward()).scale(distance)),
|
|
342
|
+
newUp = _rot.mulVec3(this.getUp());
|
|
343
|
+
this.flyCartesian(
|
|
344
|
+
newPos,
|
|
345
|
+
cartesian,
|
|
346
|
+
newUp,
|
|
347
|
+
ampl,
|
|
348
|
+
completeCallback,
|
|
349
|
+
startCallback,
|
|
350
|
+
frameCallback
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Flies to the cartesian coordinates.
|
|
357
|
+
* @public
|
|
358
|
+
* @param {Vec3} cartesian - Finish cartesian coordinates.
|
|
359
|
+
* @param {Vec3} [look] - Camera LOOK in the end of flying. Default - (0,0,0)
|
|
360
|
+
* @param {Vec3} [up] - Camera UP vector in the end of flying. Default - (0,1,0)
|
|
361
|
+
* @param {Number} [ampl=1.0] - Altitude amplitude factor.
|
|
362
|
+
* @param {cameraCallback} [completeCallback] - Callback that calls after flying when flying is finished.
|
|
363
|
+
* @param {cameraCallback} [startCallback] - Callback that calls befor the flying begins.
|
|
364
|
+
* @param [frameCallback]
|
|
365
|
+
*/
|
|
366
|
+
flyCartesian(cartesian, look = Vec3.ZERO, up = Vec3.UP, ampl = 1.0, completeCallback = () => { }, startCallback = () => { }, frameCallback = () => { }) {
|
|
367
|
+
|
|
368
|
+
this.stopFlying();
|
|
369
|
+
|
|
370
|
+
look = look || Vec3.ZERO;
|
|
371
|
+
up = up || Vec3.UP;
|
|
372
|
+
|
|
373
|
+
this._completeCallback = completeCallback;
|
|
374
|
+
|
|
375
|
+
this._frameCallback = frameCallback;
|
|
376
|
+
|
|
377
|
+
if (startCallback) {
|
|
378
|
+
startCallback.call(this);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if (look instanceof LonLat) {
|
|
382
|
+
look = this.planet.ellipsoid.lonLatToCartesian(look);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
var ground_a = this.planet.ellipsoid.lonLatToCartesian(
|
|
386
|
+
new LonLat(this._lonLat.lon, this._lonLat.lat)
|
|
387
|
+
);
|
|
388
|
+
var v_a = this._u,
|
|
389
|
+
n_a = this._b;
|
|
390
|
+
|
|
391
|
+
var lonlat_b = this.planet.ellipsoid.cartesianToLonLat(cartesian);
|
|
392
|
+
var up_b = up;
|
|
393
|
+
var ground_b = this.planet.ellipsoid.lonLatToCartesian(
|
|
394
|
+
new LonLat(lonlat_b.lon, lonlat_b.lat, 0)
|
|
395
|
+
);
|
|
396
|
+
var eye_b = cartesian;
|
|
397
|
+
var n_b = Vec3.sub(eye_b, look);
|
|
398
|
+
var u_b = up_b.cross(n_b);
|
|
399
|
+
n_b.normalize();
|
|
400
|
+
u_b.normalize();
|
|
401
|
+
var v_b = n_b.cross(u_b);
|
|
402
|
+
|
|
403
|
+
var an = ground_a.normal();
|
|
404
|
+
var bn = ground_b.normal();
|
|
405
|
+
var anbn = 1.0 - an.dot(bn);
|
|
406
|
+
var hM_a = ampl * math.SQRT_HALF * Math.sqrt(anbn > 0.0 ? anbn : 0.0);
|
|
407
|
+
|
|
408
|
+
var maxHeight = 6639613;
|
|
409
|
+
var currMaxHeight = Math.max(this._lonLat.height, lonlat_b.height);
|
|
410
|
+
if (currMaxHeight > maxHeight) {
|
|
411
|
+
maxHeight = currMaxHeight;
|
|
412
|
+
}
|
|
413
|
+
var max_h = currMaxHeight + 2.5 * hM_a * (maxHeight - currMaxHeight);
|
|
414
|
+
var zero = Vec3.ZERO;
|
|
415
|
+
|
|
416
|
+
// camera path and orientations calculation
|
|
417
|
+
for (var i = 0; i <= this._numFrames; i++) {
|
|
418
|
+
var d = 1 - i / this._numFrames;
|
|
419
|
+
d = d * d * (3 - 2 * d);
|
|
420
|
+
d *= d;
|
|
421
|
+
|
|
422
|
+
// Error here
|
|
423
|
+
var g_i = ground_a.smerp(ground_b, d).normalize();
|
|
424
|
+
var ground_i = this.planet.getRayIntersectionEllipsoid(new Ray(zero, g_i));
|
|
425
|
+
var t = 1 - d;
|
|
426
|
+
var height_i =
|
|
427
|
+
this._lonLat.height * d * d * d +
|
|
428
|
+
max_h * 3 * d * d * t +
|
|
429
|
+
max_h * 3 * d * t * t +
|
|
430
|
+
lonlat_b.height * t * t * t;
|
|
431
|
+
|
|
432
|
+
var eye_i = ground_i.addA(g_i.scale(height_i));
|
|
433
|
+
var up_i = v_a.smerp(v_b, d);
|
|
434
|
+
var look_i = Vec3.add(eye_i, n_a.smerp(n_b, d).negateTo());
|
|
435
|
+
|
|
436
|
+
var n = new Vec3(eye_i.x - look_i.x, eye_i.y - look_i.y, eye_i.z - look_i.z);
|
|
437
|
+
var u = up_i.cross(n);
|
|
438
|
+
n.normalize();
|
|
439
|
+
u.normalize();
|
|
440
|
+
|
|
441
|
+
var v = n.cross(u);
|
|
442
|
+
this._framesArr[i] = {
|
|
443
|
+
eye: eye_i,
|
|
444
|
+
n: n,
|
|
445
|
+
u: u,
|
|
446
|
+
v: v
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
this._framesCounter = this._numFrames;
|
|
451
|
+
this._flying = true;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Flies to the geo coordiantes.
|
|
456
|
+
* @public
|
|
457
|
+
* @param {LonLat} lonlat - Finish coordinates.
|
|
458
|
+
* @param {Vec3} [look] - Camera LOOK in the end of flying. Default - (0,0,0)
|
|
459
|
+
* @param {Vec3} [up] - Camera UP vector in the end of flying. Default - (0,1,0)
|
|
460
|
+
* @param {Number} [ampl] - Altitude amplitude factor.
|
|
461
|
+
* @param {cameraCallback} [completeCallback] - Callback that calls after flying when flying is finished.
|
|
462
|
+
* @param {cameraCallback} [startCallback] - Callback that calls befor the flying begins.
|
|
463
|
+
*/
|
|
464
|
+
flyLonLat(lonlat, look, up, ampl, completeCallback, startCallback) {
|
|
465
|
+
var _lonlat = new LonLat(lonlat.lon, lonlat.lat, lonlat.height || this._lonLat.height);
|
|
466
|
+
this.flyCartesian(
|
|
467
|
+
this.planet.ellipsoid.lonLatToCartesian(_lonlat),
|
|
468
|
+
look,
|
|
469
|
+
up,
|
|
470
|
+
ampl,
|
|
471
|
+
completeCallback,
|
|
472
|
+
startCallback
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Breaks the flight.
|
|
478
|
+
* @public
|
|
479
|
+
*/
|
|
480
|
+
stopFlying() {
|
|
481
|
+
this.planet.layerLock.free(this._keyLock);
|
|
482
|
+
this.planet.terrainLock.free(this._keyLock);
|
|
483
|
+
this.planet._normalMapCreator.free(this._keyLock);
|
|
484
|
+
|
|
485
|
+
this._flying = false;
|
|
486
|
+
this._framesArr.length = 0;
|
|
487
|
+
this._framesArr = [];
|
|
488
|
+
this._framesCounter = -1;
|
|
489
|
+
this._frameCallback = null;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Returns camera is flying.
|
|
494
|
+
* @public
|
|
495
|
+
* @returns {boolean}
|
|
496
|
+
*/
|
|
497
|
+
isFlying() {
|
|
498
|
+
return this._flying;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Rotates around planet to the left.
|
|
503
|
+
* @public
|
|
504
|
+
* @param {number} angle - Rotation angle.
|
|
505
|
+
* @param {boolean} [spin] - If its true rotates around globe spin.
|
|
506
|
+
*/
|
|
507
|
+
rotateLeft(angle, spin) {
|
|
508
|
+
this.rotateHorizontal(angle * math.RADIANS, spin ^ true, Vec3.ZERO);
|
|
509
|
+
this.update();
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Rotates around planet to the right.
|
|
514
|
+
* @public
|
|
515
|
+
* @param {number} angle - Rotation angle.
|
|
516
|
+
* @param {boolean} [spin] - If its true rotates around globe spin.
|
|
517
|
+
*/
|
|
518
|
+
rotateRight(angle, spin) {
|
|
519
|
+
this.rotateHorizontal(-angle * math.RADIANS, spin ^ true, Vec3.ZERO);
|
|
520
|
+
this.update();
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Rotates around planet to the north pole.
|
|
525
|
+
* @public
|
|
526
|
+
* @param {number} angle - Rotation angle.
|
|
527
|
+
*/
|
|
528
|
+
rotateUp(angle) {
|
|
529
|
+
this.rotateVertical(angle * math.RADIANS, Vec3.ZERO);
|
|
530
|
+
this.update();
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Rotates around planet to the south pole.
|
|
535
|
+
* @public
|
|
536
|
+
* @param {number} angle - Rotation angle.
|
|
537
|
+
*/
|
|
538
|
+
rotateDown(angle) {
|
|
539
|
+
this.rotateVertical(-angle * math.RADIANS, Vec3.ZERO);
|
|
540
|
+
this.update();
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
rotateVertical(angle, center, minSlope = 0) {
|
|
544
|
+
var rot = new Mat4().setRotation(this._r, angle);
|
|
545
|
+
var tr = new Mat4().setIdentity().translate(center);
|
|
546
|
+
var ntr = new Mat4().setIdentity().translate(center.negateTo());
|
|
547
|
+
var trm = tr.mul(rot).mul(ntr);
|
|
548
|
+
|
|
549
|
+
let eye = trm.mulVec3(this.eye);
|
|
550
|
+
let u = rot.mulVec3(this._u).normalize();
|
|
551
|
+
let r = rot.mulVec3(this._r).normalize();
|
|
552
|
+
let b = rot.mulVec3(this._b).normalize();
|
|
553
|
+
|
|
554
|
+
let eyeNorm = eye.normal();
|
|
552
555
|
let slope = b.dot(eyeNorm);
|
|
553
|
-
|
|
554
|
-
if (minSlope) {
|
|
555
|
-
let dSlope = slope - this.slope;
|
|
556
|
-
|
|
557
|
-
if (slope < minSlope && dSlope < 0) return;
|
|
558
|
-
|
|
559
|
-
if (
|
|
560
|
-
(slope > 0.1 && u.dot(eyeNorm) > 0) ||
|
|
561
|
-
this.slope <= 0.1 ||
|
|
562
|
-
this._u.dot(this.eye.normal()) <= 0.0
|
|
563
|
-
) {
|
|
564
|
-
this.eye = eye;
|
|
565
|
-
this._u = u;
|
|
566
|
-
this._r = r;
|
|
567
|
-
this._b = b;
|
|
568
|
-
}
|
|
569
|
-
} else {
|
|
570
|
-
this.eye = eye;
|
|
571
|
-
this._u = u;
|
|
572
|
-
this._r = r;
|
|
573
|
-
this._b = b;
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
/**
|
|
578
|
-
* Prepare camera to the frame. Used in render node frame function.
|
|
579
|
-
* @public
|
|
580
|
-
*/
|
|
581
|
-
checkFly() {
|
|
582
|
-
if (this._flying) {
|
|
583
|
-
var c = this._numFrames - this._framesCounter;
|
|
584
|
-
|
|
585
|
-
this.planet.layerLock.lock(this._keyLock);
|
|
586
|
-
this.planet.terrainLock.lock(this._keyLock);
|
|
587
|
-
this.planet._normalMapCreator.lock(this._keyLock);
|
|
588
|
-
|
|
589
|
-
this.eye = this._framesArr[c].eye;
|
|
590
|
-
this._r = this._framesArr[c].u;
|
|
591
|
-
this._u = this._framesArr[c].v;
|
|
592
|
-
this._b = this._framesArr[c].n;
|
|
593
|
-
|
|
594
|
-
if (this._frameCallback) {
|
|
595
|
-
this._frameCallback();
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
this.update();
|
|
599
|
-
|
|
600
|
-
this._framesCounter--;
|
|
601
|
-
|
|
602
|
-
if (this._framesCounter < 0) {
|
|
603
|
-
this.stopFlying();
|
|
604
|
-
if (this._completeCallback) {
|
|
605
|
-
this._completeCallback();
|
|
606
|
-
this._completeCallback = null;
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
checkTerrainCollision() {
|
|
613
|
-
this._terrainAltitude = this._lonLat.height;
|
|
614
|
-
if (this._insideSegment && this._insideSegment.planet) {
|
|
615
|
-
this._terrainAltitude = this._insideSegment.getTerrainPoint(
|
|
616
|
-
this.eye,
|
|
617
|
-
this._insideSegmentPosition,
|
|
618
|
-
this._terrainPoint
|
|
619
|
-
);
|
|
620
|
-
if (this._terrainAltitude < this.minAltitude) {
|
|
621
|
-
this.setAltitude(this.minAltitude);
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
getSurfaceVisibleDistance(d) {
|
|
627
|
-
let R = this.planet.ellipsoid._a;
|
|
628
|
-
return R * Math.acos(R / (R + this._lonLat.height + d));
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
getHeading() {
|
|
632
|
-
let u = this.eye.normal();
|
|
633
|
-
let f = Vec3.proj_b_to_plane(
|
|
634
|
-
this.slope >= 0.97 ? this.getUp() : this.getForward(),
|
|
635
|
-
u
|
|
636
|
-
).normalize(),
|
|
637
|
-
n = Vec3.proj_b_to_plane(Vec3.UP, u).normalize();
|
|
638
|
-
let res = Math.sign(u.dot(f.cross(n))) * Math.acos(f.dot(n)) * math.DEGREES;
|
|
639
|
-
if (res < 0.0) {
|
|
640
|
-
return 360.0 + res;
|
|
641
|
-
}
|
|
642
|
-
return res;
|
|
556
|
+
|
|
557
|
+
if (minSlope) {
|
|
558
|
+
let dSlope = slope - this.slope;
|
|
559
|
+
|
|
560
|
+
if (slope < minSlope && dSlope < 0) return;
|
|
561
|
+
|
|
562
|
+
if (
|
|
563
|
+
(slope > 0.1 && u.dot(eyeNorm) > 0) ||
|
|
564
|
+
this.slope <= 0.1 ||
|
|
565
|
+
this._u.dot(this.eye.normal()) <= 0.0
|
|
566
|
+
) {
|
|
567
|
+
this.eye = eye;
|
|
568
|
+
this._u = u;
|
|
569
|
+
this._r = r;
|
|
570
|
+
this._b = b;
|
|
571
|
+
}
|
|
572
|
+
} else {
|
|
573
|
+
this.eye = eye;
|
|
574
|
+
this._u = u;
|
|
575
|
+
this._r = r;
|
|
576
|
+
this._b = b;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Prepare camera to the frame. Used in render node frame function.
|
|
582
|
+
* @public
|
|
583
|
+
*/
|
|
584
|
+
checkFly() {
|
|
585
|
+
if (this._flying) {
|
|
586
|
+
var c = this._numFrames - this._framesCounter;
|
|
587
|
+
|
|
588
|
+
this.planet.layerLock.lock(this._keyLock);
|
|
589
|
+
this.planet.terrainLock.lock(this._keyLock);
|
|
590
|
+
this.planet._normalMapCreator.lock(this._keyLock);
|
|
591
|
+
|
|
592
|
+
this.eye = this._framesArr[c].eye;
|
|
593
|
+
this._r = this._framesArr[c].u;
|
|
594
|
+
this._u = this._framesArr[c].v;
|
|
595
|
+
this._b = this._framesArr[c].n;
|
|
596
|
+
|
|
597
|
+
if (this._frameCallback) {
|
|
598
|
+
this._frameCallback();
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
this.update();
|
|
602
|
+
|
|
603
|
+
this._framesCounter--;
|
|
604
|
+
|
|
605
|
+
if (this._framesCounter < 0) {
|
|
606
|
+
this.stopFlying();
|
|
607
|
+
if (this._completeCallback) {
|
|
608
|
+
this._completeCallback();
|
|
609
|
+
this._completeCallback = null;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
checkTerrainCollision() {
|
|
616
|
+
this._terrainAltitude = this._lonLat.height;
|
|
617
|
+
if (this._insideSegment && this._insideSegment.planet) {
|
|
618
|
+
this._terrainAltitude = this._insideSegment.getTerrainPoint(
|
|
619
|
+
this.eye,
|
|
620
|
+
this._insideSegmentPosition,
|
|
621
|
+
this._terrainPoint
|
|
622
|
+
);
|
|
623
|
+
if (this._terrainAltitude < this.minAltitude) {
|
|
624
|
+
this.setAltitude(this.minAltitude);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
getSurfaceVisibleDistance(d) {
|
|
630
|
+
let R = this.planet.ellipsoid._a;
|
|
631
|
+
return R * Math.acos(R / (R + this._lonLat.height + d));
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
getHeading() {
|
|
635
|
+
let u = this.eye.normal();
|
|
636
|
+
let f = Vec3.proj_b_to_plane(
|
|
637
|
+
this.slope >= 0.97 ? this.getUp() : this.getForward(),
|
|
638
|
+
u
|
|
639
|
+
).normalize(),
|
|
640
|
+
n = Vec3.proj_b_to_plane(Vec3.UP, u).normalize();
|
|
641
|
+
let res = Math.sign(u.dot(f.cross(n))) * Math.acos(f.dot(n)) * math.DEGREES;
|
|
642
|
+
if (res < 0.0) {
|
|
643
|
+
return 360.0 + res;
|
|
644
|
+
}
|
|
645
|
+
return res;
|
|
643
646
|
}
|
|
644
647
|
|
|
645
648
|
isVisible(poi) {
|
|
646
|
-
let e = this.eye.length();
|
|
647
|
-
return this.eye.distance(poi) < Math.sqrt(e * e - this.planet.ellipsoid._a2);
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
export { PlanetCamera };
|
|
649
|
+
let e = this.eye.length();
|
|
650
|
+
return this.eye.distance(poi) < Math.sqrt(e * e - this.planet.ellipsoid._a2);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
export { PlanetCamera };
|