@openglobus/og 0.13.12 → 0.14.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 (80) hide show
  1. package/README.md +1 -4
  2. package/css/og.css +1 -1
  3. package/dist/@openglobus/og.css +1 -1
  4. package/dist/@openglobus/og.esm.js +2 -2
  5. package/dist/@openglobus/og.esm.js.map +1 -1
  6. package/dist/@openglobus/og.umd.js +2 -2
  7. package/dist/@openglobus/og.umd.js.map +1 -1
  8. package/package.json +2 -2
  9. package/src/og/Globe.js +14 -4
  10. package/src/og/camera/Camera.js +7 -7
  11. package/src/og/camera/PlanetCamera.js +1 -1
  12. package/src/og/control/LayerSwitcher.js +48 -31
  13. package/src/og/control/MouseNavigation.js +2 -2
  14. package/src/og/control/ScaleControl.js +30 -10
  15. package/src/og/control/SimpleSkyBackground.js +184 -0
  16. package/src/og/control/Sun.js +3 -2
  17. package/src/og/ellipsoid/Ellipsoid.js +119 -92
  18. package/src/og/ellipsoid/wgs84.js +13 -13
  19. package/src/og/entity/Entity.js +3 -3
  20. package/src/og/entity/GeometryHandler.js +1341 -1337
  21. package/src/og/entity/Polyline.js +0 -16
  22. package/src/og/entity/Ray.js +0 -10
  23. package/src/og/entity/RayHandler.js +3 -44
  24. package/src/og/entity/Strip.js +1 -6
  25. package/src/og/index.js +106 -95
  26. package/src/og/layer/GeoVideo.js +1 -0
  27. package/src/og/layer/Layer.js +62 -3
  28. package/src/og/layer/XYZ.js +4 -3
  29. package/src/og/math/Line3.js +140 -139
  30. package/src/og/math/Plane.js +118 -117
  31. package/src/og/math/Ray.js +242 -239
  32. package/src/og/math/Vec3.js +56 -37
  33. package/src/og/math/Vec4.js +3 -4
  34. package/src/og/math.js +21 -21
  35. package/src/og/quadTree/EarthQuadTreeStrategy.js +29 -0
  36. package/src/og/quadTree/MarsQuadTreeStrategy.js +27 -0
  37. package/src/og/quadTree/Node.js +55 -218
  38. package/src/og/quadTree/QuadTreeStrategy.js +93 -0
  39. package/src/og/quadTree/Wgs84QuadTreeStrategy.js +26 -0
  40. package/src/og/renderer/Renderer.js +13 -12
  41. package/src/og/renderer/RendererEvents.js +1065 -1065
  42. package/src/og/scene/Planet.js +84 -273
  43. package/src/og/segment/Segment.js +18 -25
  44. package/src/og/segment/SegmentLonLat.js +34 -31
  45. package/src/og/segment/SegmentLonLatWgs84.js +41 -0
  46. package/src/og/shaders/ray.js +13 -6
  47. package/src/og/shaders/toneMapping.js +5 -5
  48. package/src/og/terrain/GlobusTerrain.js +3 -2
  49. package/src/og/terrain/MapboxTerrain.js +231 -52
  50. package/src/og/utils/quadTreeType.js +11 -0
  51. package/src/og/utils/shared.js +942 -942
  52. package/src/og/webgl/Handler.js +22 -9
  53. package/types/Globe.d.ts +7 -0
  54. package/types/camera/Camera.d.ts +3 -3
  55. package/types/camera/PlanetCamera.d.ts +1 -1
  56. package/types/control/LayerSwitcher.d.ts +1 -1
  57. package/types/control/ScaleControl.d.ts +2 -1
  58. package/types/control/SimpleSkyBackground.d.ts +11 -0
  59. package/types/control/Sun.d.ts +2 -1
  60. package/types/ellipsoid/Ellipsoid.d.ts +3 -2
  61. package/types/entity/Ray.d.ts +0 -3
  62. package/types/entity/RayHandler.d.ts +0 -4
  63. package/types/index.d.ts +6 -1
  64. package/types/layer/Layer.d.ts +8 -0
  65. package/types/math/Vec3.d.ts +19 -16
  66. package/types/math/Vec4.d.ts +2 -3
  67. package/types/math.d.ts +20 -20
  68. package/types/quadTree/EarthQuadTreeStrategy.d.ts +3 -0
  69. package/types/quadTree/MarsQuadTreeStrategy.d.ts +3 -0
  70. package/types/quadTree/Node.d.ts +0 -1
  71. package/types/quadTree/QuadTreeStrategy.d.ts +21 -0
  72. package/types/quadTree/Wgs84QuadTreeStrategy.d.ts +3 -0
  73. package/types/renderer/Renderer.d.ts +1 -1
  74. package/types/scene/Planet.d.ts +6 -24
  75. package/types/segment/Segment.d.ts +4 -4
  76. package/types/segment/SegmentLonLat.d.ts +6 -2
  77. package/types/segment/SegmentLonLatWgs84.d.ts +4 -0
  78. package/types/terrain/MapboxTerrain.d.ts +2 -1
  79. package/types/utils/quadTreeType.d.ts +8 -0
  80. package/types/webgl/Handler.d.ts +4 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openglobus/og",
3
- "version": "0.13.12",
3
+ "version": "0.14.1",
4
4
  "description": "[OpenGlobus](https://www.openglobus.org/) is a javascript library designed to display interactive 3d maps and planets with map tiles, imagery and vector data, markers and 3d objects. It uses the WebGL technology, open source and completely free.",
5
5
  "directories": {
6
6
  "example": "./sandbox"
@@ -81,4 +81,4 @@
81
81
  "globe",
82
82
  "og"
83
83
  ]
84
- }
84
+ }
package/src/og/Globe.js CHANGED
@@ -20,6 +20,7 @@ import { isEmpty } from "./utils/shared.js";
20
20
  import { Handler } from "./webgl/Handler.js";
21
21
  import { createColorRGB } from "./utils/shared.js";
22
22
  import { Vec3 } from "./math/Vec3.js";
23
+ import { SimpleSkyBackground } from "./control/SimpleSkyBackground.js";
23
24
 
24
25
  /** @const {string} */
25
26
  const CANVAS_ID_PREFIX = "globus_viewport_";
@@ -70,6 +71,7 @@ const PLANET_NAME_PREFIX = "globus_planet_";
70
71
  * @param {Number} [options.minEqualZoomAltitude=10000.0] - Minimal altitude since segments on the screen bacame the same zoom level
71
72
  * @param {Number} [options.minEqualZoomCameraSlope=0.8] - Minimal camera slope above te globe where segments on the screen bacame the same zoom level
72
73
  * @param {Number} [options.loadingBatchSize=12] -
74
+ * @param {Number} [options.quadTreeStrategyPrototype] - Prototype of quadTree. QuadTreeStrategy for Earth is default.
73
75
  */
74
76
 
75
77
  class Globe {
@@ -128,8 +130,7 @@ class Globe {
128
130
  context: {
129
131
  alpha: false,
130
132
  antialias: false,
131
- powerPreference: "high-performance",
132
- premultipliedAlpha: true
133
+ premultipliedAlpha: false
133
134
  }
134
135
  }), {
135
136
  autoActivate: false,
@@ -158,6 +159,13 @@ class Globe {
158
159
  */
159
160
  this._planetName = options.name ? options.name : PLANET_NAME_PREFIX + Globe._staticCounter;
160
161
 
162
+ /**
163
+ * quad tree type.
164
+ * @private
165
+ * @type {Number}
166
+ */
167
+ this._quadTreeType = options.quadTreeType;
168
+
161
169
  if (options.atmosphere) {
162
170
  /**
163
171
  * Render node renders a planet.
@@ -178,7 +186,8 @@ class Globe {
178
186
  maxEqualZoomAltitude: options.maxEqualZoomAltitude,
179
187
  minEqualZoomAltitude: options.minEqualZoomAltitude,
180
188
  minEqualZoomCameraSlope: options.minEqualZoomCameraSlope,
181
- loadingBatchSize: options.loadingBatchSize
189
+ quadTreeStrategyPrototype: options.quadTreeStrategyPrototype,
190
+ maxLoadingRequests: options.maxLoadingRequests
182
191
  });
183
192
  }
184
193
 
@@ -212,7 +221,8 @@ class Globe {
212
221
  new TouchNavigation(),
213
222
  new EarthCoordinates(),
214
223
  new ScaleControl(),
215
- new CompassButton(options)
224
+ new CompassButton(options),
225
+ new SimpleSkyBackground()
216
226
  ]);
217
227
  }
218
228
 
@@ -15,7 +15,7 @@ import { Mat4 } from "../math/Mat4.js";
15
15
  * @param {Renderer} [renderer] - Renderer uses the camera instance.
16
16
  * @param {Object} [options] - Camera options:
17
17
  * @param {Object} [options.name] - Camera name.
18
- * @param {number} [options.viewAngle=38] - Camera angle of view. Default is 30.0
18
+ * @param {number} [options.viewAngle=47] - Camera angle of view. Default is 47.0
19
19
  * @param {number} [options.near=1] - Camera near plane distance. Default is 1.0
20
20
  * @param {number} [options.far=og.math.MAX] - Camera far plane distance. Deafult is og.math.MAX
21
21
  * @param {Vec3} [options.eye=[0,0,0]] - Camera eye position. Default (0,0,0)
@@ -77,7 +77,7 @@ class Camera {
77
77
  * @protected
78
78
  * @type {Number}
79
79
  */
80
- this._viewAngle = options.viewAngle || 38.0;
80
+ this._viewAngle = options.viewAngle || 47.0;
81
81
 
82
82
  /**
83
83
  * Camera normal matrix.
@@ -119,7 +119,7 @@ class Camera {
119
119
  this._pv = this._u.clone();
120
120
  this._pn = this._b.clone();
121
121
  this._peye = this.eye.clone();
122
- this.isMoved = false;
122
+ this.isMoving = false;
123
123
 
124
124
  this._tanViewAngle_hrad = 0.0;
125
125
  this._tanViewAngle_hradOneByHeight = 0.0;
@@ -179,12 +179,12 @@ class Camera {
179
179
  eye = this.eye;
180
180
 
181
181
  if (this._peye.equal(eye) && this._pu.equal(u) && this._pv.equal(v) && this._pn.equal(n)) {
182
- if (this.isMoved) {
182
+ if (this.isMoving) {
183
183
  this.events.dispatch(this.events.moveend, this);
184
184
  }
185
- this.isMoved = false;
185
+ this.isMoving = false;
186
186
  } else {
187
- this.isMoved = true;
187
+ this.isMoving = true;
188
188
  }
189
189
 
190
190
  this._pu.copy(u);
@@ -198,7 +198,7 @@ class Camera {
198
198
  * @public
199
199
  * @param {Renderer} renderer - OpenGlobus renderer object.
200
200
  * @param {Object} [options] - Camera options:
201
- * @param {number} [options.viewAngle] - Camera angle of view. Default is 30.0
201
+ * @param {number} [options.viewAngle] - Camera angle of view.
202
202
  * @param {number} [options.near] - Camera near plane distance. Default is 1.0
203
203
  * @param {number} [options.far] - Camera far plane distance. Deafult is og.math.MAX
204
204
  * @param {Vec3} [options.eye] - Camera eye position. Default (0,0,0)
@@ -21,7 +21,7 @@ import { Mat4 } from "../math/Mat4.js";
21
21
  * @param {RenderNode} planet - Planet render node.
22
22
  * @param {Object} [options] - Planet camera options:
23
23
  * @param {Object} [options.name] - Camera name.
24
- * @param {number} [options.viewAngle=37] - Camera angle of view. Default is 35.0
24
+ * @param {number} [options.viewAngle] - Camera angle of view.
25
25
  * @param {number} [options.near] - Camera near plane distance. Default is 1.0
26
26
  * @param {number} [options.far] - Camera far plane distance. Deafult is og.math.MAX
27
27
  * @param {number} [options.minAltitude] - Minimal altitude for the camera. Deafult is 5
@@ -7,6 +7,7 @@
7
7
  import { Control } from "./Control.js";
8
8
  import { elementFactory, appendChildren, toggleText, enableElmovement } from "./UIhelpers.js";
9
9
  import { compose } from "../utils/functionComposition.js"
10
+
10
11
  /**
11
12
  * Advanced :) layer switcher, includes base layers, overlays, geo images etc. groups.
12
13
  * Double click for zoom, drag-and-drop to change zIndex
@@ -46,14 +47,14 @@ class LayerSwitcher extends Control {
46
47
 
47
48
  }
48
49
 
49
- setupSwitcher () {
50
+ setupSwitcher() {
50
51
  const myData = this.getRecords(this.planet)
51
52
  const { $mainContainer } = this.buildBasicDOM()
52
53
  this.buildRecords(myData, $mainContainer, 0)
53
-
54
+
54
55
  }
55
-
56
- onactivate() {
56
+
57
+ onactivate() {
57
58
  this.setupSwitcher()
58
59
  }
59
60
 
@@ -87,9 +88,8 @@ class LayerSwitcher extends Control {
87
88
  const classifyObject = (object) => {
88
89
  let r = object.isBaseLayer()
89
90
  if (r === true || r === false) {
90
- return r === true ? 'BaseLayers' : 'Overlays'
91
- }
92
- else {
91
+ return r === true ? 'Base Layers' : 'Overlays'
92
+ } else {
93
93
  return 'Terrain Providers'
94
94
  }
95
95
  }
@@ -117,8 +117,10 @@ class LayerSwitcher extends Control {
117
117
  // OUTPOUT TERRAINS, BASELAYERS, OVERLAYS
118
118
  planetDataReturn(planet) {
119
119
 
120
- const { collectTerrains, collectLayers, pickBaseLayers, pickOverlays,
121
- sortByZIndex, serializeZIndices, normalizeOverlay } = this.planetDataBasic()
120
+ const {
121
+ collectTerrains, collectLayers, pickBaseLayers, pickOverlays,
122
+ sortByZIndex, serializeZIndices, normalizeOverlay
123
+ } = this.planetDataBasic()
122
124
 
123
125
  const terrains = collectTerrains(planet)
124
126
 
@@ -167,26 +169,25 @@ class LayerSwitcher extends Control {
167
169
  addNewLayer(layer) {
168
170
  // Put the data(layer) to the appropriate recordsStructure section and run the build function
169
171
  const $dialog = document.getElementById('og-layer-switcher-dialog')
170
- if($dialog){
171
- const { classifyObject } = this.planetDataBasic()
172
- const targets = [...document.body.querySelectorAll('.og-layer-switcher-record.og-depth-0 > details')]
173
- const type = classifyObject(layer)
174
- const object = this.recordsStructure().data.filter(x => x.name == type)
175
- const index = this.recordsStructure().data.findIndex(x => x.name == type)
176
- object[0].data = [layer]
177
- this.buildRecords(object[0], targets[index], 1, true)
172
+ if ($dialog) {
173
+ const { classifyObject } = this.planetDataBasic()
174
+ const targets = [...document.body.querySelectorAll('.og-layer-switcher-record.og-depth-0 > details')]
175
+ const type = classifyObject(layer)
176
+ const object = this.recordsStructure().data.filter(x => x.name == type)
177
+ const index = this.recordsStructure().data.findIndex(x => x.name == type)
178
+ object[0].data = [layer]
179
+ this.buildRecords(object[0], targets[index], 1, true)
178
180
  }
179
181
  }
180
182
 
181
183
  removeLayer(layer) {
182
- // TODO...Haven't tested it yet
183
184
  let id = layer.getID()
184
- let el = document.body.querySelector('#' + id + ".og-layer-switcher-record.og-depth-1")
185
- el.remove()
186
-
187
- if (layer.displayInLayerSwitcher) { // check necessary, or else error with layers not in switcher - e.g rulerScene layers.
188
- layer._removeCallback();
189
- layer._removeCallback = null
185
+ let arr = document.body.querySelectorAll(`.og-layer-switcher-record.og-depth-1`)
186
+ for (let i = 0; i < arr.length; i++) {
187
+ if (arr[i].id == id) {
188
+ arr[i].remove();
189
+ break;
190
+ }
190
191
  }
191
192
  }
192
193
 
@@ -205,14 +206,26 @@ class LayerSwitcher extends Control {
205
206
  // Basic DOM creation
206
207
  const $menuBtn = elementFactory('div', { id: 'og-layer-switcher-menu-btn', class: 'og-menu-btn og-OFF' },
207
208
  elementFactory('div', { id: 'og-layer-switcher-menu-icon', class: 'og-icon-holder' }))
208
- const $dialog = elementFactory('div', { class: 'og-layer-switcher-dialog og-dialog og-not-visible', id: 'og-layer-switcher-dialog' })
209
+ const $dialog = elementFactory('div', {
210
+ class: 'og-layer-switcher-dialog og-dialog og-not-visible',
211
+ id: 'og-layer-switcher-dialog'
212
+ })
209
213
  const $header = elementFactory('div', { class: 'og-layer-switcher-dialog-header' })
210
- const $header_close = elementFactory('div', { id: 'og-layer-switcher-dialog-close-btn', class: 'og-dialog-header-btn og-OFF' },
214
+ const $header_close = elementFactory('div', {
215
+ id: 'og-layer-switcher-dialog-close-btn',
216
+ class: 'og-dialog-header-btn og-OFF'
217
+ },
211
218
  elementFactory('div', { class: 'og-icon-holder' }))
212
- const $headerMinMax = elementFactory('div', { id: 'og-layer-switcher-dialog-minMax-btn', class: 'og-dialog-header-btn og-OFF' },
219
+ const $headerMinMax = elementFactory('div', {
220
+ id: 'og-layer-switcher-dialog-minMax-btn',
221
+ class: 'og-dialog-header-btn og-OFF'
222
+ },
213
223
  elementFactory('div', { class: 'og-icon-holder' }))
214
224
  const $headerTitle = elementFactory('span', { class: 'og-dialog-header-title' }, 'Layer Switcher')
215
- const $headerPin = elementFactory('div', { id: 'og-layer-switcher-dialog-pin-btn', class: 'og-dialog-header-btn og-OFF' },
225
+ const $headerPin = elementFactory('div', {
226
+ id: 'og-layer-switcher-dialog-pin-btn',
227
+ class: 'og-dialog-header-btn og-OFF'
228
+ },
216
229
  elementFactory('div', { class: 'og-icon-holder' }))
217
230
  const $mainContainer = elementFactory('div', { class: 'og-layer-switcher-main-container' })
218
231
 
@@ -234,9 +247,13 @@ class LayerSwitcher extends Control {
234
247
 
235
248
  // LISTENERS
236
249
  const whereClick = (e, wrapper, menuBtn) => {
237
- if (wrapper.contains(e.target)) { return 'inside' }
238
- else if (menuBtn.contains(e.target)) { return 'on-btn' }
239
- else { return 'outside' }
250
+ if (wrapper.contains(e.target)) {
251
+ return 'inside'
252
+ } else if (menuBtn.contains(e.target)) {
253
+ return 'on-btn'
254
+ } else {
255
+ return 'outside'
256
+ }
240
257
  }
241
258
 
242
259
  var whereClickHandler = null
@@ -356,7 +356,7 @@ class MouseNavigation extends Control {
356
356
 
357
357
  if (this.pointOnEarth && this.renderer.events.mouseState.moving) {
358
358
  this.renderer.controlsBag.scaleRot = 1.0;
359
- var l = (0.5 / cam.eye.distance(this.pointOnEarth)) * cam._lonLat.height * math.RADIANS;
359
+ var l = (0.5 / cam.eye.distance(this.pointOnEarth)) * (cam._lonLat.height < 5.0 ? 5.0 : cam._lonLat.height) * math.RADIANS;
360
360
  if (l > 0.007) l = 0.007;
361
361
  cam.rotateHorizontal(l * (e.x - e.prev_x), false, this.pointOnEarth, this.earthUp);
362
362
 
@@ -457,4 +457,4 @@ class MouseNavigation extends Control {
457
457
  }
458
458
  }
459
459
 
460
- export { MouseNavigation };
460
+ export { MouseNavigation };
@@ -7,6 +7,7 @@
7
7
  import { Control } from "./Control.js";
8
8
  import { RADIANS } from "../math.js";
9
9
  import { binarySearch, parseHTML } from "../utils/shared.js";
10
+ import { Vec3 } from "../math/Vec3.js";
10
11
 
11
12
  const scale = [
12
13
  1, 2, 3, 5, 10, 20, 30, 50, 100, 200, 300, 500, 1e3, 2e3, 3e3, 5e3, 10e3, 20e3, 30e3, 50e3,
@@ -38,6 +39,8 @@ class ScaleControl extends Control {
38
39
 
39
40
  this._minWidth = 100;
40
41
  this._maxWidth = 150;
42
+
43
+ this._isCenter = options.isCenter || false;
41
44
  }
42
45
 
43
46
  _renderTemplate() {
@@ -51,21 +54,38 @@ class ScaleControl extends Control {
51
54
 
52
55
  this.renderer.div.appendChild(this.el);
53
56
 
54
- this.renderer.events.on("draw", (e) => {
55
- if (e.events.pointerEvent()) {
56
- this._draw();
57
- }
58
- });
57
+ if (this._isCenter) {
58
+ this.renderer.activeCamera.events.on("moveend", (e) => {
59
+ this._drawScreen(this.planet.renderer.handler.getCenter());
60
+ });
59
61
 
60
- this.renderer.activeCamera.events.on("moveend", (e) => {
61
- this._draw(e);
62
- });
62
+ this.planet.terrain.events.on("loadend", (e) => {
63
+ this._drawScreen(this.planet.renderer.handler.getCenter());
64
+ });
65
+ } else {
66
+ this.renderer.events.on("mousemove", (e) => {
67
+ if (!e.leftButtonHold && !e.rightButtonHold) {
68
+ this._drawScreen(e);
69
+ }
70
+ });
71
+
72
+ this.renderer.activeCamera.events.on("moveend", (e) => {
73
+ let ms = this.renderer.events.mouseState;
74
+ if (!ms.leftButtonHold && !ms.rightButtonHold) {
75
+ this._drawScreen(ms);
76
+ }
77
+ });
78
+ }
63
79
  }
64
80
 
65
- _draw(e) {
81
+ _drawScreen(px) {
66
82
  let cam = this.renderer.activeCamera;
67
- let s0 = this.planet.renderer.handler.getCenter();
83
+ let s0 = px;
68
84
  let dist = this.planet.getDistanceFromPixel(s0);
85
+ if (dist === 0) {
86
+ s0 = cam.project(Vec3.ZERO);
87
+ dist = this.planet.getDistanceFromPixel(s0);
88
+ }
69
89
  let p0 = cam.getForward().scaleTo(dist).addA(cam.eye);
70
90
  let tempSize = dist * Math.tan(cam._viewAngle * RADIANS);
71
91
  let p1 = p0.add(cam.getRight().scaleTo(tempSize));
@@ -0,0 +1,184 @@
1
+ /**
2
+ * @module og/control/SimpleSkyBackground
3
+ */
4
+
5
+ "use strict";
6
+
7
+ import { Control } from "./Control.js";
8
+ import { Program } from '../webgl/Program.js';
9
+
10
+ /**
11
+ * Frame per second(FPS) display control.
12
+ * @class
13
+ * @extends {Control}
14
+ * @param {Object} [options] - Control options.
15
+ */
16
+ class SimpleSkyBackground extends Control {
17
+ constructor(options) {
18
+ super({
19
+ name: "SimpleSkyBackground",
20
+ ...options
21
+ });
22
+ }
23
+
24
+ oninit() {
25
+ this.renderer.handler.addProgram(simpleSkyBackgroundShader());
26
+ this.planet.events.on("draw", this._drawBackground, this);
27
+ }
28
+
29
+ onactivate() {
30
+ super.onactivate();
31
+ this.planet.events.on("draw", this._drawBackground, this);
32
+ }
33
+
34
+ ondeactivate() {
35
+ super.ondeactivate();
36
+ this.planet.events.off("draw", this._drawBackground);
37
+ }
38
+
39
+ _drawBackground() {
40
+ let h = this.renderer.handler;
41
+ let sh = h.programs.simpleSkyBackground, p = sh._program, shu = p.uniforms, gl = h.gl;
42
+ let cam = this.renderer.activeCamera;
43
+
44
+ gl.disable(gl.DEPTH_TEST);
45
+
46
+ sh.activate();
47
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.renderer._screenFrameCornersBuffer);
48
+ gl.vertexAttribPointer(p.attributes.corners, 2, gl.FLOAT, false, 0, 0);
49
+
50
+ gl.uniform3fv(shu.camPos, [cam.eye.x, cam.eye.y, cam.eye.z]);
51
+ gl.uniform2fv(shu.iResolution, [h.getWidth(), h.getHeight()]);
52
+ gl.uniform1f(shu.fov, cam.getViewAngle());
53
+ gl.uniform1f(shu.earthRadius, this.planet.ellipsoid.getPolarSize() + 1);
54
+
55
+ gl.uniformMatrix4fv(shu.viewMatrix, false, cam._viewMatrix._m);
56
+
57
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
58
+
59
+ gl.enable(gl.DEPTH_TEST);
60
+ }
61
+ }
62
+
63
+ export function simpleSkyBackground(options) {
64
+ return new SimpleSkyBackground(options);
65
+ }
66
+
67
+ function simpleSkyBackgroundShader() {
68
+ return new Program("simpleSkyBackground", {
69
+ uniforms: {
70
+ iResolution: "vec2", fov: "float", camPos: "vec3", earthRadius: "float", //projectionMatrix: "mat4",
71
+ viewMatrix: "mat4"
72
+ }, attributes: {
73
+ corners: "vec3"
74
+ }, vertexShader: `attribute vec2 corners;
75
+
76
+ varying vec2 tc;
77
+
78
+ void main(void) {
79
+ gl_Position = vec4(corners, 0.0, 1.0);
80
+ tc = corners * 0.5 + 0.5;
81
+ }`, fragmentShader: `precision highp float;
82
+
83
+ #define MAX 10e10
84
+ #define PI 3.14159265359
85
+ #define rad(x) x * PI / 180.
86
+ #define ZERO vec3(0.0)
87
+
88
+ const vec3 START_COLOR = vec3(1.0);
89
+ const vec3 END_COLOR = vec3(0.0, 153.0/255.0, 221.0/255.0);
90
+
91
+ #define RED vec4(1.0, 0.0, 0.0, 1.0)
92
+ #define GREEN vec4(0.0, 1.0, 0.0, 1.0)
93
+
94
+ uniform vec3 camPos;
95
+ uniform vec2 iResolution;
96
+ uniform float fov;
97
+ uniform float earthRadius;
98
+ uniform mat4 viewMatrix;
99
+
100
+ varying vec2 tc;
101
+
102
+ // compute the view ray in the camera coordinate
103
+ vec3 computeView(vec2 uv){
104
+ float w_h_ratio = iResolution.x / iResolution.y;
105
+ float h = tan(rad(fov/2.));
106
+ return normalize(vec3(-w_h_ratio * h, -h, -1.) + vec3(uv.x * 2. * h * w_h_ratio, uv.y*2.*h, 0.));
107
+ }
108
+
109
+ // sphere of size ra centered at point ce
110
+ vec2 sphIntersect( in vec3 ro, in vec3 rd, in vec3 ce, float ra )
111
+ {
112
+ vec3 oc = ro - ce;
113
+ float b = dot( oc, rd );
114
+ float c = dot( oc, oc ) - ra * ra;
115
+ float h = b * b - c;
116
+ if( h < 0.0 ) return vec2(MAX); // no intersection
117
+ h = sqrt( h );
118
+ return vec2( -b-h, -b+h );
119
+ }
120
+
121
+ mat3 transpose(mat3 matrix) {
122
+ vec3 row0 = matrix[0];
123
+ vec3 row1 = matrix[1];
124
+ vec3 row2 = matrix[2];
125
+ mat3 result = mat3(
126
+ vec3(row0.x, row1.x, row2.x),
127
+ vec3(row0.y, row1.y, row2.y),
128
+ vec3(row0.z, row1.z, row2.z)
129
+ );
130
+ return result;
131
+ }
132
+
133
+ float det(mat2 matrix) {
134
+ return matrix[0].x * matrix[1].y - matrix[0].y * matrix[1].x;
135
+ }
136
+
137
+ mat3 inverse(mat3 matrix) {
138
+ vec3 row0 = matrix[0];
139
+ vec3 row1 = matrix[1];
140
+ vec3 row2 = matrix[2];
141
+
142
+ vec3 minors0 = vec3(
143
+ det(mat2(row1.y, row1.z, row2.y, row2.z)),
144
+ det(mat2(row1.z, row1.x, row2.z, row2.x)),
145
+ det(mat2(row1.x, row1.y, row2.x, row2.y))
146
+ );
147
+ vec3 minors1 = vec3(
148
+ det(mat2(row2.y, row2.z, row0.y, row0.z)),
149
+ det(mat2(row2.z, row2.x, row0.z, row0.x)),
150
+ det(mat2(row2.x, row2.y, row0.x, row0.y))
151
+ );
152
+ vec3 minors2 = vec3(
153
+ det(mat2(row0.y, row0.z, row1.y, row1.z)),
154
+ det(mat2(row0.z, row0.x, row1.z, row1.x)),
155
+ det(mat2(row0.x, row0.y, row1.x, row1.y))
156
+ );
157
+
158
+ mat3 adj = transpose(mat3(minors0, minors1, minors2));
159
+
160
+ return (1.0 / dot(row0, minors0)) * adj;
161
+ }
162
+
163
+ void main(void) {
164
+
165
+ vec3 dir = computeView(tc);
166
+ dir = inverse(mat3(viewMatrix)) * dir;
167
+
168
+ vec2 ER = sphIntersect(camPos, dir, vec3(0.0), earthRadius);
169
+
170
+ float bigRadius = earthRadius * 2.5;
171
+ vec3 bigCenter = normalize(camPos) * bigRadius * 1.3;
172
+
173
+ vec2 BIG = sphIntersect(camPos, dir, bigCenter, bigRadius);
174
+
175
+ float Ix = distance(camPos + dir * BIG.y, ZERO);
176
+
177
+ float maxI = sqrt(bigRadius * bigRadius + bigRadius * bigRadius);
178
+
179
+ gl_FragColor = vec4(mix(START_COLOR, END_COLOR, Ix / maxI), 1.0);
180
+ }`
181
+ });
182
+ }
183
+
184
+ export { SimpleSkyBackground };
@@ -10,7 +10,6 @@ import { LightSource } from "../light/LightSource.js";
10
10
  import { Quat } from "../math/Quat.js";
11
11
  import { Vec3 } from "../math/Vec3.js";
12
12
 
13
- const ACTIVATION_HEIGHT = 12079000.0;
14
13
  /**
15
14
  * Real Sun geocentric position control that place the Sun on the right place by the Earth.
16
15
  * @class
@@ -39,6 +38,8 @@ class Sun extends Control {
39
38
  */
40
39
  // this._isCameraSunlight = false;
41
40
 
41
+ this.activationHeight = options.activationHeight || 12079000.0;
42
+
42
43
  this.offsetVertical = options.offsetVertical || -5000000;
43
44
 
44
45
  this.offsetHorizontal = options.offsetHorizontal || 5000000;
@@ -106,7 +107,7 @@ class Sun extends Control {
106
107
  this._currDate = this._clockPtr.currentDate;
107
108
  if (!this._stopped) {
108
109
  var cam = this.renderer.activeCamera;
109
- if (cam.getHeight() < ACTIVATION_HEIGHT || !this._active) {
110
+ if (cam.getHeight() < this.activationHeight || !this._active) {
110
111
  this._lightOn = true;
111
112
  this._f = 1;
112
113
  var n = cam.eye.normal(),