@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.
Files changed (93) hide show
  1. package/README.md +0 -2
  2. package/dist/@openglobus/og.esm.js +2 -2
  3. package/dist/@openglobus/og.esm.js.map +1 -1
  4. package/dist/@openglobus/og.umd.js +2 -2
  5. package/dist/@openglobus/og.umd.js.map +1 -1
  6. package/package.json +7 -7
  7. package/src/og/Extent.js +3 -3
  8. package/src/og/Globe.js +277 -275
  9. package/src/og/ImageCanvas.js +3 -3
  10. package/src/og/LonLat.js +9 -9
  11. package/src/og/QueueArray.js +2 -2
  12. package/src/og/Rectangle.js +5 -5
  13. package/src/og/bv/Box.js +1 -1
  14. package/src/og/bv/Sphere.js +2 -2
  15. package/src/og/camera/Camera.js +1 -1
  16. package/src/og/camera/PlanetCamera.js +649 -646
  17. package/src/og/control/LayerSwitcher.js +1 -1
  18. package/src/og/control/MouseNavigation.js +22 -13
  19. package/src/og/control/MouseWheelZoomControl.js +2 -2
  20. package/src/og/control/ScaleControl.js +1 -1
  21. package/src/og/control/TouchNavigation.js +319 -319
  22. package/src/og/control/ZoomControl.js +132 -132
  23. package/src/og/control/visibleExtent/Segment.js +12 -12
  24. package/src/og/ellipsoid/Ellipsoid.js +577 -567
  25. package/src/og/entity/BillboardHandler.js +878 -1051
  26. package/src/og/entity/Entity.js +1 -1
  27. package/src/og/entity/EntityCollection.js +847 -857
  28. package/src/og/entity/GeoObjectHandler.js +2 -2
  29. package/src/og/entity/LabelHandler.js +888 -1040
  30. package/src/og/entity/LabelWorker.js +0 -6
  31. package/src/og/entity/PointCloud.js +495 -495
  32. package/src/og/entity/Polyline.js +2218 -2222
  33. package/src/og/entity/RayHandler.js +1 -1
  34. package/src/og/layer/CanvasTiles.js +6 -3
  35. package/src/og/layer/GeoImage.js +1 -1
  36. package/src/og/layer/KML.js +5 -5
  37. package/src/og/layer/Layer.js +804 -752
  38. package/src/og/layer/Vector.js +997 -1010
  39. package/src/og/layer/XYZ.js +359 -357
  40. package/src/og/math/Line2.js +4 -4
  41. package/src/og/math/Quat.js +2 -2
  42. package/src/og/math/Ray.js +2 -2
  43. package/src/og/math/Vec2.js +524 -524
  44. package/src/og/math/Vec3.js +900 -900
  45. package/src/og/math/Vec4.js +261 -261
  46. package/src/og/math.js +397 -398
  47. package/src/og/quadTree/EntityCollectionNode.js +389 -387
  48. package/src/og/renderer/Renderer.js +14 -20
  49. package/src/og/renderer/RendererEvents.js +1034 -1045
  50. package/src/og/scene/Planet.js +12 -9
  51. package/src/og/scene/RenderNode.js +347 -354
  52. package/src/og/segment/Segment.js +3 -1
  53. package/src/og/segment/SegmentLonLat.js +1 -4
  54. package/src/og/shaders/billboard.js +220 -204
  55. package/src/og/shaders/drawnode.js +603 -603
  56. package/src/og/shaders/label.js +595 -456
  57. package/src/og/shaders/polyline.js +365 -361
  58. package/src/og/terrain/MapboxTerrain.js +1 -1
  59. package/src/og/utils/FontAtlas.js +209 -200
  60. package/src/og/utils/GeoImageCreator.js +4 -5
  61. package/src/og/utils/TextureAtlas.js +4 -4
  62. package/src/og/utils/VectorTileCreator.js +414 -414
  63. package/src/og/utils/shared.js +1 -1
  64. package/src/og/webgl/Handler.js +28 -60
  65. package/src/og/webgl/Multisample.js +260 -260
  66. package/src/og/webgl/Program.js +411 -396
  67. package/types/bv/Box.d.ts +1 -1
  68. package/types/bv/Sphere.d.ts +1 -1
  69. package/types/camera/PlanetCamera.d.ts +3 -3
  70. package/types/control/LayerSwitcher.d.ts +1 -1
  71. package/types/ellipsoid/Ellipsoid.d.ts +9 -2
  72. package/types/entity/BillboardHandler.d.ts +0 -4
  73. package/types/entity/EntityCollection.d.ts +0 -8
  74. package/types/entity/LabelHandler.d.ts +0 -2
  75. package/types/entity/Polyline.d.ts +1 -1
  76. package/types/layer/KML.d.ts +11 -11
  77. package/types/layer/Layer.d.ts +5 -0
  78. package/types/layer/Vector.d.ts +1 -8
  79. package/types/math/Line2.d.ts +4 -4
  80. package/types/math/Ray.d.ts +2 -2
  81. package/types/math/Vec2.d.ts +1 -1
  82. package/types/math/Vec3.d.ts +1 -1
  83. package/types/math/Vec4.d.ts +2 -2
  84. package/types/math.d.ts +1 -1
  85. package/types/renderer/Renderer.d.ts +1 -1
  86. package/types/renderer/RendererEvents.d.ts +1 -1
  87. package/types/shaders/label.d.ts +1 -1
  88. package/types/utils/FontAtlas.d.ts +3 -2
  89. package/types/utils/TextureAtlas.d.ts +3 -3
  90. package/types/utils/VectorTileCreator.d.ts +4 -4
  91. package/types/utils/shared.d.ts +1 -1
  92. package/types/webgl/Handler.d.ts +6 -31
  93. 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 1
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 || 1;
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
- this.stopFlying();
368
-
369
- this._completeCallback = completeCallback;
370
-
371
- this._frameCallback = frameCallback;
372
-
373
- if (startCallback) {
374
- startCallback.call(this);
375
- }
376
-
377
- look = look || Vec3.ZERO;
378
- if (look instanceof LonLat) {
379
- look = this.planet.ellipsoid.lonLatToCartesian(look);
380
- }
381
-
382
- var ground_a = this.planet.ellipsoid.lonLatToCartesian(
383
- new LonLat(this._lonLat.lon, this._lonLat.lat)
384
- );
385
- var v_a = this._u,
386
- n_a = this._b;
387
-
388
- var lonlat_b = this.planet.ellipsoid.cartesianToLonLat(cartesian);
389
- var up_b = up || Vec3.UP;
390
- var ground_b = this.planet.ellipsoid.lonLatToCartesian(
391
- new LonLat(lonlat_b.lon, lonlat_b.lat, 0)
392
- );
393
- var eye_b = cartesian;
394
- var n_b = Vec3.sub(eye_b, look);
395
- var u_b = up_b.cross(n_b);
396
- n_b.normalize();
397
- u_b.normalize();
398
- var v_b = n_b.cross(u_b);
399
-
400
- var an = ground_a.normal();
401
- var bn = ground_b.normal();
402
- var anbn = 1.0 - an.dot(bn);
403
- var hM_a = ampl * math.SQRT_HALF * Math.sqrt(anbn > 0.0 ? anbn : 0.0);
404
-
405
- var maxHeight = 6639613;
406
- var currMaxHeight = Math.max(this._lonLat.height, lonlat_b.height);
407
- if (currMaxHeight > maxHeight) {
408
- maxHeight = currMaxHeight;
409
- }
410
- var max_h = currMaxHeight + 2.5 * hM_a * (maxHeight - currMaxHeight);
411
- var zero = Vec3.ZERO;
412
-
413
- // camera path and orientations calculation
414
- for (var i = 0; i <= this._numFrames; i++) {
415
- var d = 1 - i / this._numFrames;
416
- d = d * d * (3 - 2 * d);
417
- d *= d;
418
-
419
- // Error here
420
- var g_i = ground_a.smerp(ground_b, d).normalize();
421
- var ground_i = this.planet.getRayIntersectionEllipsoid(new Ray(zero, g_i));
422
- var t = 1 - d;
423
- var height_i =
424
- this._lonLat.height * d * d * d +
425
- max_h * 3 * d * d * t +
426
- max_h * 3 * d * t * t +
427
- lonlat_b.height * t * t * t;
428
-
429
- var eye_i = ground_i.addA(g_i.scale(height_i));
430
- var up_i = v_a.smerp(v_b, d);
431
- var look_i = Vec3.add(eye_i, n_a.smerp(n_b, d).negateTo());
432
-
433
- var n = new Vec3(eye_i.x - look_i.x, eye_i.y - look_i.y, eye_i.z - look_i.z);
434
- var u = up_i.cross(n);
435
- n.normalize();
436
- u.normalize();
437
-
438
- var v = n.cross(u);
439
- this._framesArr[i] = {
440
- eye: eye_i,
441
- n: n,
442
- u: u,
443
- v: v
444
- };
445
- }
446
-
447
- this._framesCounter = this._numFrames;
448
- this._flying = true;
449
- }
450
-
451
- /**
452
- * Flies to the geo coordiantes.
453
- * @public
454
- * @param {LonLat} lonlat - Finish coordinates.
455
- * @param {Vec3} [look] - Camera LOOK in the end of flying. Default - (0,0,0)
456
- * @param {Vec3} [up] - Camera UP vector in the end of flying. Default - (0,1,0)
457
- * @param {Number} [ampl] - Altitude amplitude factor.
458
- * @param {cameraCallback} [completeCallback] - Callback that calls after flying when flying is finished.
459
- * @param {cameraCallback} [startCallback] - Callback that calls befor the flying begins.
460
- */
461
- flyLonLat(lonlat, look, up, ampl, completeCallback, startCallback) {
462
- var _lonlat = new LonLat(lonlat.lon, lonlat.lat, lonlat.height || this._lonLat.height);
463
- this.flyCartesian(
464
- this.planet.ellipsoid.lonLatToCartesian(_lonlat),
465
- look,
466
- up,
467
- ampl,
468
- completeCallback,
469
- startCallback
470
- );
471
- }
472
-
473
- /**
474
- * Breaks the flight.
475
- * @public
476
- */
477
- stopFlying() {
478
- this.planet.layerLock.free(this._keyLock);
479
- this.planet.terrainLock.free(this._keyLock);
480
- this.planet._normalMapCreator.free(this._keyLock);
481
-
482
- this._flying = false;
483
- this._framesArr.length = 0;
484
- this._framesArr = [];
485
- this._framesCounter = -1;
486
- this._frameCallback = null;
487
- }
488
-
489
- /**
490
- * Returns camera is flying.
491
- * @public
492
- * @returns {boolean}
493
- */
494
- isFlying() {
495
- return this._flying;
496
- }
497
-
498
- /**
499
- * Rotates around planet to the left.
500
- * @public
501
- * @param {number} angle - Rotation angle.
502
- * @param {boolean} [spin] - If its true rotates around globe spin.
503
- */
504
- rotateLeft(angle, spin) {
505
- this.rotateHorizontal(angle * math.RADIANS, spin ^ true, Vec3.ZERO);
506
- this.update();
507
- }
508
-
509
- /**
510
- * Rotates around planet to the right.
511
- * @public
512
- * @param {number} angle - Rotation angle.
513
- * @param {boolean} [spin] - If its true rotates around globe spin.
514
- */
515
- rotateRight(angle, spin) {
516
- this.rotateHorizontal(-angle * math.RADIANS, spin ^ true, Vec3.ZERO);
517
- this.update();
518
- }
519
-
520
- /**
521
- * Rotates around planet to the north pole.
522
- * @public
523
- * @param {number} angle - Rotation angle.
524
- */
525
- rotateUp(angle) {
526
- this.rotateVertical(angle * math.RADIANS, Vec3.ZERO);
527
- this.update();
528
- }
529
-
530
- /**
531
- * Rotates around planet to the south pole.
532
- * @public
533
- * @param {number} angle - Rotation angle.
534
- */
535
- rotateDown(angle) {
536
- this.rotateVertical(-angle * math.RADIANS, Vec3.ZERO);
537
- this.update();
538
- }
539
-
540
- rotateVertical(angle, center, minSlope = 0) {
541
- var rot = new Mat4().setRotation(this._r, angle);
542
- var tr = new Mat4().setIdentity().translate(center);
543
- var ntr = new Mat4().setIdentity().translate(center.negateTo());
544
- var trm = tr.mul(rot).mul(ntr);
545
-
546
- let eye = trm.mulVec3(this.eye);
547
- let u = rot.mulVec3(this._u).normalize();
548
- let r = rot.mulVec3(this._r).normalize();
549
- let b = rot.mulVec3(this._b).normalize();
550
-
551
- let eyeNorm = eye.normal();
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 };