@openglobus/og 0.11.1 → 0.11.6

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 (255) hide show
  1. package/package.json +18 -20
  2. package/src/og/Clock.js +11 -11
  3. package/src/og/Deferred.js +1 -1
  4. package/src/og/Events.js +9 -7
  5. package/src/og/Extent.js +117 -72
  6. package/src/og/Globe.js +35 -22
  7. package/src/og/ImageCanvas.js +24 -18
  8. package/src/og/Lock.js +2 -2
  9. package/src/og/LonLat.js +40 -37
  10. package/src/og/Popup.js +21 -15
  11. package/src/og/QueueArray.js +7 -3
  12. package/src/og/Rectangle.js +11 -6
  13. package/src/og/Stack.js +8 -5
  14. package/src/og/ajax.js +21 -33
  15. package/src/og/astro/astro.js +5 -5
  16. package/src/og/astro/earth.js +23 -17
  17. package/src/og/astro/jd.js +44 -39
  18. package/src/og/astro/orbit.js +20 -18
  19. package/src/og/astro/rotation.js +17 -8
  20. package/src/og/bv/Box.js +7 -3
  21. package/src/og/bv/Sphere.js +17 -9
  22. package/src/og/camera/Camera.js +137 -86
  23. package/src/og/camera/Frustum.js +30 -19
  24. package/src/og/camera/PlanetCamera.js +30 -26
  25. package/src/og/control/CompassButton.js +8 -2
  26. package/src/og/control/Control.js +13 -11
  27. package/src/og/control/DebugInfo.js +4 -1
  28. package/src/og/control/EarthCoordinates.js +62 -41
  29. package/src/og/control/EarthNavigation.js +20 -22
  30. package/src/og/control/GeoImageDragControl.js +1 -1
  31. package/src/og/control/KeyboardNavigation.js +12 -12
  32. package/src/og/control/LayerSwitcher.js +24 -23
  33. package/src/og/control/Lighting.js +1 -1
  34. package/src/og/control/MouseNavigation.js +1 -1
  35. package/src/og/control/ScaleControl.js +1 -1
  36. package/src/og/control/SegmentBoundVisualization.js +8 -9
  37. package/src/og/control/ShowFps.js +15 -10
  38. package/src/og/control/SimpleNavigation.js +8 -10
  39. package/src/og/control/Sun.js +25 -15
  40. package/src/og/control/ToggleWireframe.js +5 -5
  41. package/src/og/control/TouchNavigation.js +58 -45
  42. package/src/og/control/ZoomControl.js +41 -25
  43. package/src/og/control/index.js +4 -0
  44. package/src/og/ellipsoid/Ellipsoid.js +181 -85
  45. package/src/og/ellipsoid/wgs84.js +4 -4
  46. package/src/og/entity/BaseBillboard.js +97 -44
  47. package/src/og/entity/Billboard.js +15 -11
  48. package/src/og/entity/BillboardHandler.js +314 -64
  49. package/src/og/entity/Entity.js +106 -74
  50. package/src/og/entity/EntityCollection.js +72 -49
  51. package/src/og/entity/GeoObject.js +228 -0
  52. package/src/og/entity/GeoObjectHandler.js +910 -0
  53. package/src/og/entity/Geometry.js +29 -26
  54. package/src/og/entity/GeometryHandler.js +598 -126
  55. package/src/og/entity/Label.js +74 -40
  56. package/src/og/entity/LabelHandler.js +47 -246
  57. package/src/og/entity/LabelWorker.js +213 -0
  58. package/src/og/entity/Object3d.js +504 -0
  59. package/src/og/entity/PointCloud.js +81 -33
  60. package/src/og/entity/PointCloudHandler.js +9 -9
  61. package/src/og/entity/Polyline.js +39 -39
  62. package/src/og/entity/Ray.js +61 -28
  63. package/src/og/entity/ShapeHandler.js +1 -1
  64. package/src/og/entity/Strip.js +77 -48
  65. package/src/og/entity/StripHandler.js +27 -27
  66. package/src/og/entity/index.js +8 -16
  67. package/src/og/input/KeyboardHandler.js +107 -104
  68. package/src/og/input/MouseHandler.js +81 -78
  69. package/src/og/input/TouchHandler.js +55 -51
  70. package/src/og/layer/BaseGeoImage.js +61 -30
  71. package/src/og/layer/CanvasTiles.js +26 -24
  72. package/src/og/layer/GeoImage.js +10 -10
  73. package/src/og/layer/GeoTexture2d.js +1 -1
  74. package/src/og/layer/GeoVideo.js +3 -3
  75. package/src/og/layer/KML.js +66 -40
  76. package/src/og/layer/Layer.js +27 -17
  77. package/src/og/layer/Material.js +93 -61
  78. package/src/og/layer/Vector.js +118 -72
  79. package/src/og/layer/WMS.js +36 -19
  80. package/src/og/layer/XYZ.js +55 -48
  81. package/src/og/light/LightSource.js +47 -40
  82. package/src/og/math/Line2.js +24 -24
  83. package/src/og/math/Line3.js +103 -102
  84. package/src/og/math/Mat3.js +134 -121
  85. package/src/og/math/Mat4.js +603 -459
  86. package/src/og/math/Plane.js +21 -20
  87. package/src/og/math/Quat.js +980 -927
  88. package/src/og/math/Ray.js +195 -187
  89. package/src/og/math/Vec2.js +127 -117
  90. package/src/og/math/Vec3.js +206 -176
  91. package/src/og/math/Vec4.js +49 -53
  92. package/src/og/math/coder.js +18 -18
  93. package/src/og/math.js +12 -12
  94. package/src/og/mercator.js +11 -11
  95. package/src/og/proj/EPSG3857.js +4 -4
  96. package/src/og/proj/EPSG4326.js +4 -4
  97. package/src/og/proj/Proj.js +31 -31
  98. package/src/og/quadTree/EntityCollectionNode.js +310 -300
  99. package/src/og/quadTree/Node.js +1008 -993
  100. package/src/og/renderer/Renderer.js +768 -747
  101. package/src/og/renderer/RendererEvents.js +9 -6
  102. package/src/og/scene/Axes.js +1 -1
  103. package/src/og/scene/BaseNode.js +8 -9
  104. package/src/og/scene/Planet.js +115 -87
  105. package/src/og/scene/RenderNode.js +29 -22
  106. package/src/og/scene/SkyBox.js +1 -1
  107. package/src/og/segment/Segment.js +1886 -1878
  108. package/src/og/segment/SegmentLonLat.js +298 -268
  109. package/src/og/segment/segmentHelper.js +11 -11
  110. package/src/og/shaders/bloom.js +1 -1
  111. package/src/og/shaders/blur.js +2 -2
  112. package/src/og/shaders/depth.js +1 -1
  113. package/src/og/shaders/geoObject.js +211 -0
  114. package/src/og/shaders/label.js +1 -1
  115. package/src/og/shaders/lumFilter.js +1 -1
  116. package/src/og/shaders/pointCloud.js +42 -42
  117. package/src/og/shaders/screenFrame.js +1 -1
  118. package/src/og/shaders/shape.js +15 -21
  119. package/src/og/shaders/skybox.js +37 -37
  120. package/src/og/shaders/toneMapping.js +1 -1
  121. package/src/og/shapes/BaseShape.js +129 -57
  122. package/src/og/shapes/Icosphere.js +30 -15
  123. package/src/og/shapes/Sphere.js +13 -16
  124. package/src/og/terrain/BilTerrain.js +2 -1
  125. package/src/og/terrain/EmptyTerrain.js +2 -2
  126. package/src/og/terrain/Geoid.js +2 -2
  127. package/src/og/terrain/GlobusTerrain.js +10 -10
  128. package/src/og/terrain/MapboxTerrain.js +1 -1
  129. package/src/og/utils/GeoImageCreator.js +9 -9
  130. package/src/og/utils/Loader.js +6 -6
  131. package/src/og/utils/NormalMapCreator.js +13 -13
  132. package/src/og/utils/TerrainWorker.js +1 -1
  133. package/src/og/utils/TextureAtlas.js +20 -22
  134. package/src/og/utils/VectorTileCreator.js +5 -5
  135. package/src/og/utils/earcut.js +1 -1
  136. package/src/og/utils/shared.js +15 -15
  137. package/src/og/webgl/Framebuffer.js +101 -53
  138. package/src/og/webgl/Handler.js +125 -85
  139. package/src/og/webgl/Multisample.js +55 -27
  140. package/src/og/webgl/Program.js +80 -35
  141. package/src/og/webgl/ProgramController.js +27 -23
  142. package/src/og/webgl/callbacks.js +8 -8
  143. package/types/Clock.d.ts +6 -2
  144. package/types/Deferred.d.ts +1 -1
  145. package/types/Events.d.ts +8 -4
  146. package/types/Extent.d.ts +37 -33
  147. package/types/Globe.d.ts +15 -13
  148. package/types/ImageCanvas.d.ts +5 -3
  149. package/types/LonLat.d.ts +24 -24
  150. package/types/Popup.d.ts +4 -0
  151. package/types/QueueArray.d.ts +6 -2
  152. package/types/Rectangle.d.ts +10 -4
  153. package/types/Stack.d.ts +4 -0
  154. package/types/ajax.d.ts +1 -1
  155. package/types/astro/earth.d.ts +3 -2
  156. package/types/bv/Box.d.ts +10 -5
  157. package/types/bv/Sphere.d.ts +13 -7
  158. package/types/camera/Camera.d.ts +90 -81
  159. package/types/camera/Frustum.d.ts +26 -22
  160. package/types/camera/PlanetCamera.d.ts +49 -53
  161. package/types/control/CompassButton.d.ts +4 -4
  162. package/types/control/Control.d.ts +7 -4
  163. package/types/control/DebugInfo.d.ts +3 -4
  164. package/types/control/EarthCoordinates.d.ts +6 -6
  165. package/types/control/EarthNavigation.d.ts +42 -0
  166. package/types/control/KeyboardNavigation.d.ts +3 -4
  167. package/types/control/LayerSwitcher.d.ts +3 -5
  168. package/types/control/Lighting.d.ts +3 -3
  169. package/types/control/MouseNavigation.d.ts +47 -0
  170. package/types/control/ScaleControl.d.ts +3 -3
  171. package/types/control/ShowFps.d.ts +3 -4
  172. package/types/control/SimpleNavigation.d.ts +3 -6
  173. package/types/control/Sun.d.ts +8 -10
  174. package/types/control/ToggleWireframe.d.ts +3 -3
  175. package/types/control/TouchNavigation.d.ts +48 -0
  176. package/types/control/ZoomControl.d.ts +3 -4
  177. package/types/control/index.d.ts +3 -1
  178. package/types/ellipsoid/Ellipsoid.d.ts +47 -43
  179. package/types/ellipsoid/wgs84.d.ts +3 -2
  180. package/types/entity/BaseBillboard.d.ts +41 -34
  181. package/types/entity/Billboard.d.ts +7 -7
  182. package/types/entity/BillboardHandler.d.ts +4 -0
  183. package/types/entity/Entity.d.ts +101 -83
  184. package/types/entity/EntityCollection.d.ts +57 -43
  185. package/types/entity/GeoObject.d.ts +111 -0
  186. package/types/entity/GeoObjectHandler.d.ts +77 -0
  187. package/types/entity/Geometry.d.ts +9 -7
  188. package/types/entity/GeometryHandler.d.ts +2 -2
  189. package/types/entity/Label.d.ts +24 -29
  190. package/types/entity/LabelHandler.d.ts +9 -2
  191. package/types/entity/LabelWorker.d.ts +9 -0
  192. package/types/entity/PointCloud.d.ts +8 -8
  193. package/types/entity/PointCloudHandler.d.ts +3 -3
  194. package/types/entity/Polyline.d.ts +58 -55
  195. package/types/entity/Ray.d.ts +19 -18
  196. package/types/entity/Strip.d.ts +8 -7
  197. package/types/entity/StripHandler.d.ts +3 -3
  198. package/types/entity/index.d.ts +7 -7
  199. package/types/input/KeyboardHandler.d.ts +10 -0
  200. package/types/input/MouseHandler.d.ts +5 -0
  201. package/types/input/TouchHandler.d.ts +5 -0
  202. package/types/layer/BaseGeoImage.d.ts +23 -35
  203. package/types/layer/CanvasTiles.d.ts +15 -22
  204. package/types/layer/GeoImage.d.ts +5 -18
  205. package/types/layer/GeoVideo.d.ts +5 -30
  206. package/types/layer/KML.d.ts +20 -15
  207. package/types/layer/Layer.d.ts +326 -0
  208. package/types/layer/Material.d.ts +45 -0
  209. package/types/layer/Vector.d.ts +208 -0
  210. package/types/layer/WMS.d.ts +4 -7
  211. package/types/layer/XYZ.d.ts +19 -25
  212. package/types/light/LightSource.d.ts +54 -53
  213. package/types/math/Line2.d.ts +11 -0
  214. package/types/math/Line3.d.ts +10 -0
  215. package/types/math/Mat3.d.ts +30 -18
  216. package/types/math/Mat4.d.ts +71 -52
  217. package/types/math/Plane.d.ts +5 -4
  218. package/types/math/Quat.d.ts +379 -0
  219. package/types/math/Ray.d.ts +82 -0
  220. package/types/math/Vec2.d.ts +102 -101
  221. package/types/math/Vec3.d.ts +143 -142
  222. package/types/math/Vec4.d.ts +40 -39
  223. package/types/math/coder.d.ts +12 -11
  224. package/types/math.d.ts +8 -8
  225. package/types/mercator.d.ts +3 -3
  226. package/types/proj/EPSG3857.d.ts +3 -2
  227. package/types/proj/EPSG4326.d.ts +3 -2
  228. package/types/proj/Proj.d.ts +42 -0
  229. package/types/quadTree/EntityCollectionNode.d.ts +34 -0
  230. package/types/quadTree/Node.d.ts +61 -0
  231. package/types/renderer/Renderer.d.ts +300 -0
  232. package/types/renderer/RendererEvents.d.ts +10 -7
  233. package/types/scene/BaseNode.d.ts +9 -9
  234. package/types/scene/Planet.d.ts +131 -126
  235. package/types/scene/RenderNode.d.ts +22 -23
  236. package/types/segment/Segment.d.ts +279 -0
  237. package/types/segment/SegmentLonLat.d.ts +16 -0
  238. package/types/shaders/geoObject.d.ts +3 -0
  239. package/types/shapes/BaseShape.d.ts +43 -40
  240. package/types/shapes/Sphere.d.ts +7 -7
  241. package/types/terrain/BilTerrain.d.ts +0 -1
  242. package/types/terrain/EmptyTerrain.d.ts +4 -4
  243. package/types/terrain/GlobusTerrain.d.ts +17 -54
  244. package/types/terrain/MapboxTerrain.d.ts +0 -1
  245. package/types/utils/GeoImageCreator.d.ts +3 -2
  246. package/types/utils/TextureAtlas.d.ts +8 -8
  247. package/types/utils/shared.d.ts +25 -24
  248. package/types/webgl/Framebuffer.d.ts +5 -5
  249. package/types/webgl/Handler.d.ts +68 -43
  250. package/types/webgl/Multisample.d.ts +5 -5
  251. package/types/webgl/Program.d.ts +8 -2
  252. package/types/webgl/ProgramController.d.ts +18 -13
  253. package/src/og/inherits.js +0 -8
  254. package/src/og/utils/polylabel.js +0 -176
  255. package/types/inherits.d.ts +0 -4
@@ -1,993 +1,1008 @@
1
- "use strict";
2
-
3
- import { Extent } from "../Extent.js";
4
- import { LonLat } from "../LonLat.js";
5
- import { EPSG4326 } from "../proj/EPSG4326.js";
6
- import { EPSG3857 } from "../proj/EPSG3857.js";
7
- import { Vec3 } from "../math/Vec3.js";
8
- import { MAX_LAT, POLE } from "../mercator.js";
9
- import { MAX, MIN } from "../math.js";
10
- import { getMatrixSubArray, getMatrixSubArrayBoundsExt } from "../utils/shared.js";
11
-
12
- import {
13
- COMSIDE,
14
- E,
15
- MAX_RENDERED_NODES,
16
- N,
17
- NE,
18
- NEIGHBOUR,
19
- NOTRENDERING,
20
- NW,
21
- OPPART,
22
- OPSIDE,
23
- PARTOFFSET,
24
- RENDERING,
25
- S,
26
- SE,
27
- SW,
28
- VISIBLE_DISTANCE,
29
- W,
30
- WALKTHROUGH
31
- } from "./quadTree.js";
32
-
33
- import { MAX_NORMAL_ZOOM } from "../segment/Segment.js";
34
-
35
- const VISIBLE_HEIGHT = 1400000.0;
36
-
37
- let _tempHigh = new Vec3(),
38
- _tempLow = new Vec3();
39
-
40
- /**
41
- * Quad tree planet segment node.
42
- * @constructor
43
- * @param {og.planetSegment.Segment|og.planetSegment.SegmentLonLat} segmentPrototype - Planet segment node constructor.
44
- * @param {og.scene.RenderNode} planet - Planet render node.
45
- * @param {number} partId - NorthEast, SouthWest etc.
46
- * @param {og.quadTree.Node} parent - Parent of this node.
47
- * @param {number} id - Tree node identifier (id * 4 + 1);
48
- * @param {number} tileZoom - Deep index of the quad tree.
49
- * @param {og.Extent} extent - Planet segment extent.
50
- */
51
- const Node = function (SegmentPrototype, planet, partId, parent, id, tileZoom, extent) {
52
- this.SegmentPrototype = SegmentPrototype;
53
- this.planet = planet;
54
- this.parentNode = parent;
55
- this.partId = partId;
56
- this.nodeId = partId + id;
57
- this.state = null;
58
- this.appliedTerrainNodeId = -1;
59
- this.sideSize = [1, 1, 1, 1];
60
- this.sideSizeLog2 = [0, 0, 0, 0];
61
- this.ready = false;
62
- this.neighbors = [[], [], [], []];
63
- this.equalizedNeighborId = [-1, -1, -1, -1];
64
- this.equalizedNeighborGridSize = [-1, -1, -1, -1];
65
- this.nodes = [null, null, null, null];
66
- this.segment = new SegmentPrototype(this, planet, tileZoom, extent);
67
- this._cameraInside = false;
68
- this.inFrustum = 0;
69
- this.createBounds();
70
- this.planet._createdNodesCount++;
71
- };
72
-
73
- const _vertOrder = [
74
- { x: 0, y: 0 },
75
- { x: 1, y: 0 },
76
- { x: 0, y: 1 },
77
- { x: 1, y: 1 }
78
- ];
79
- const _neGridSize = Math.sqrt(_vertOrder.length) - 1;
80
-
81
- Node.prototype.createChildrenNodes = function () {
82
- this.ready = true;
83
-
84
- var p = this.planet;
85
- var ps = this.segment;
86
- var ext = ps._extent;
87
- var size_x = ext.getWidth() * 0.5;
88
- var size_y = ext.getHeight() * 0.5;
89
- var ne = ext.northEast,
90
- sw = ext.southWest;
91
- var z = ps.tileZoom + 1;
92
- var id = this.nodeId * 4 + 1;
93
- var c = new LonLat(sw.lon + size_x, sw.lat + size_y);
94
- var nd = this.nodes;
95
-
96
- nd[NW] = new Node(
97
- this.SegmentPrototype,
98
- p,
99
- NW,
100
- this,
101
- id,
102
- z,
103
- new Extent(new LonLat(sw.lon, sw.lat + size_y), new LonLat(sw.lon + size_x, ne.lat))
104
- );
105
-
106
- nd[NE] = new Node(
107
- this.SegmentPrototype,
108
- p,
109
- NE,
110
- this,
111
- id,
112
- z,
113
- new Extent(c, new LonLat(ne.lon, ne.lat))
114
- );
115
-
116
- nd[SW] = new Node(
117
- this.SegmentPrototype,
118
- p,
119
- SW,
120
- this,
121
- id,
122
- z,
123
- new Extent(new LonLat(sw.lon, sw.lat), c)
124
- );
125
-
126
- nd[SE] = new Node(
127
- this.SegmentPrototype,
128
- p,
129
- SE,
130
- this,
131
- id,
132
- z,
133
- new Extent(new LonLat(sw.lon + size_x, sw.lat), new LonLat(ne.lon, sw.lat + size_y))
134
- );
135
- };
136
-
137
- Node.prototype.createBounds = function () {
138
- let seg = this.segment;
139
- seg._setExtentLonLat();
140
- if (seg.tileZoom === 0) {
141
- seg.setBoundingSphere(0.0, 0.0, 0.0, new Vec3(0.0, 0.0, seg.planet.ellipsoid._a));
142
- } else if (seg.tileZoom < seg.planet.terrain.minZoom) {
143
- seg.createBoundsByExtent();
144
- } else {
145
- seg.createBoundsByParent();
146
- }
147
- };
148
-
149
- Node.prototype.getState = function () {
150
- if (this.state === -1) {
151
- return this.state;
152
- }
153
- var pn = this.parentNode;
154
- while (pn) {
155
- if (pn.state !== WALKTHROUGH) {
156
- return NOTRENDERING;
157
- }
158
- pn = pn.parentNode;
159
- }
160
- return this.state;
161
- };
162
-
163
- /**
164
- * Returns the same deep existent neighbour node.
165
- * @public
166
- * @param {Number} side - Neighbour side index e.g. og.quadTree.N, og.quadTree.W etc.
167
- * @returns {og.quadTree.Node} -
168
- */
169
- Node.prototype.getEqualNeighbor = function (side) {
170
- var pn = this;
171
- var part = NEIGHBOUR[side][pn.partId];
172
- if (part !== -1) {
173
- return pn.parentNode.nodes[part];
174
- } else {
175
- var pathId = [];
176
- while (pn.parentNode) {
177
- pathId.push(pn.partId);
178
- part = NEIGHBOUR[side][pn.partId];
179
- pn = pn.parentNode;
180
- if (part !== -1) {
181
- var i = pathId.length;
182
- side = OPSIDE[side];
183
- while (pn && i--) {
184
- part = OPPART[side][pathId[i]];
185
- pn = pn.nodes[part];
186
- }
187
- return pn;
188
- }
189
- }
190
- }
191
- };
192
-
193
- Node.prototype.isBrother = function (node) {
194
- return !(this.parentNode || node.parentNode) || this.parentNode.id === node.parentNode.id;
195
- };
196
-
197
- Node.prototype.renderTree = function (cam, maxZoom, terrainReadySegment, stopLoading) {
198
- if (
199
- this.planet._renderedNodes.length >= MAX_RENDERED_NODES ||
200
- this.planet._nodeCounterError_ > 2000
201
- ) {
202
- return;
203
- }
204
-
205
- this.planet._nodeCounterError_++;
206
-
207
- this.state = WALKTHROUGH;
208
-
209
- this.neighbors[0] = null;
210
- this.neighbors[1] = null;
211
- this.neighbors[2] = null;
212
- this.neighbors[3] = null;
213
-
214
- this.neighbors[0] = [];
215
- this.neighbors[1] = [];
216
- this.neighbors[2] = [];
217
- this.neighbors[3] = [];
218
-
219
- let seg = this.segment,
220
- planet = this.planet;
221
-
222
- this._cameraInside = false;
223
-
224
- let insideLonLat = null;
225
-
226
- // Search a node which the camera is flying over.
227
- if (!this.parentNode || this.parentNode._cameraInside) {
228
- let inside;
229
- if (Math.abs(cam._lonLat.lat) <= MAX_LAT && seg._projection.id === EPSG3857.id) {
230
- inside = seg._extent.isInside(cam._lonLatMerc);
231
- insideLonLat = cam._lonLatMerc;
232
- } else if (seg._projection.id === EPSG4326.id) {
233
- inside = seg._extent.isInside(cam._lonLat);
234
- insideLonLat = cam._lonLat;
235
- }
236
-
237
- if (inside) {
238
- cam._insideSegmentPosition.lon = insideLonLat.lon;
239
- cam._insideSegmentPosition.lat = insideLonLat.lat;
240
- cam._insideSegment = seg;
241
- this._cameraInside = true;
242
- }
243
- }
244
-
245
- this.inFrustum = 0;
246
-
247
- let frustums = cam.frustums,
248
- numFrustums = frustums.length;
249
-
250
- if (seg.tileZoom < 6) {
251
- for (let i = 0; i < numFrustums; i++) {
252
- if (frustums[i].containsSphere(seg.bsphere)) {
253
- this.inFrustum |= 1 << i;
254
- }
255
- }
256
- } else {
257
- let commonFrustumFlag = 1 << (numFrustums - 1 - 1);
258
- for (let i = 0; commonFrustumFlag && i < numFrustums; i++) {
259
- if (seg.terrainReady) {
260
- if (frustums[i].containsBox(seg.bbox)) {
261
- commonFrustumFlag >>= 1;
262
- this.inFrustum |= 1 << i;
263
- }
264
- } else {
265
- if (frustums[i].containsSphere(seg.bsphere)) {
266
- commonFrustumFlag >>= 1;
267
- this.inFrustum |= 1 << i;
268
- }
269
- }
270
- }
271
- }
272
-
273
- if (this.inFrustum || this._cameraInside) {
274
- let h = cam._lonLat.height;
275
-
276
- let altVis =
277
- cam.eye.distance(seg.bsphere.center) - seg.bsphere.radius <
278
- VISIBLE_DISTANCE * Math.sqrt(h) ||
279
- (seg.tileZoom < 4 && !seg.terrainReady) ||
280
- seg.tileZoom < 2;
281
-
282
- if ((this.inFrustum && (altVis || h > 10000.0)) || this._cameraInside) {
283
- seg._collectVisibleNodes();
284
- }
285
-
286
- if (seg.tileZoom < 2 && seg.normalMapReady) {
287
- this.traverseNodes(cam, maxZoom, terrainReadySegment, stopLoading);
288
- } else if ((!maxZoom && seg.acceptForRendering(cam)) || seg.tileZoom === maxZoom) {
289
- this.prepareForRendering(cam, altVis, this.inFrustum, terrainReadySegment, stopLoading);
290
- } else if (seg.tileZoom < planet.terrain._maxNodeZoom && seg.terrainReady) {
291
- // Deleting terrainReady here, you have to remove
292
- // this.appliedTerrainNodeId !== pn.nodeId in whileTerrainLoading,
293
- // also have to fix createBoundsByParent(*)
294
- this.traverseNodes(cam, maxZoom, seg, stopLoading);
295
- } else {
296
- this.prepareForRendering(cam, altVis, this.inFrustum, terrainReadySegment, stopLoading);
297
- }
298
- } else {
299
- this.state = NOTRENDERING;
300
- }
301
- };
302
-
303
- Node.prototype.traverseNodes = function (cam, maxZoom, terrainReadySegment, stopLoading) {
304
- if (!this.ready) {
305
- this.createChildrenNodes();
306
- }
307
-
308
- let n = this.nodes;
309
-
310
- n[0].renderTree(cam, maxZoom, terrainReadySegment, stopLoading);
311
- n[1].renderTree(cam, maxZoom, terrainReadySegment, stopLoading);
312
- n[2].renderTree(cam, maxZoom, terrainReadySegment, stopLoading);
313
- n[3].renderTree(cam, maxZoom, terrainReadySegment, stopLoading);
314
- };
315
-
316
- Node.prototype.prepareForRendering = function (
317
- cam,
318
- altVis,
319
- inFrustum,
320
- terrainReadySegment,
321
- stopLoading
322
- ) {
323
- let seg = this.segment;
324
-
325
- if (cam._lonLat.height < VISIBLE_HEIGHT) {
326
- if (altVis) {
327
- this.renderNode(inFrustum, !inFrustum, terrainReadySegment, stopLoading);
328
- } else {
329
- this.state = NOTRENDERING;
330
- }
331
- } else {
332
- if (seg.tileZoom < 2) {
333
- this.renderNode(inFrustum, !inFrustum, terrainReadySegment, stopLoading);
334
- } else if (seg.tileZoom > MAX_NORMAL_ZOOM) {
335
- this.renderNode(inFrustum, !inFrustum, terrainReadySegment, stopLoading);
336
- } else if (
337
- seg._swNorm.dot(cam._n) > 0.0 ||
338
- seg._nwNorm.dot(cam._n) > 0.0 ||
339
- seg._neNorm.dot(cam._n) > 0.0 ||
340
- seg._seNorm.dot(cam._n) > 0.0
341
- ) {
342
- this.renderNode(inFrustum, !inFrustum, terrainReadySegment, stopLoading);
343
- } else {
344
- this.state = NOTRENDERING;
345
- }
346
- }
347
- };
348
-
349
- Node.prototype.renderNode = function (inFrustum, onlyTerrain, terrainReadySegment, stopLoading) {
350
- var seg = this.segment;
351
-
352
- // Create and load terrain data
353
- if (!seg.terrainReady) {
354
- if (!seg.initialized) {
355
- seg.initialize();
356
- }
357
-
358
- this.whileTerrainLoading(terrainReadySegment, stopLoading);
359
-
360
- if (!seg.plainProcessing) {
361
- seg.createPlainSegmentAsync();
362
- }
363
-
364
- if (seg.plainReady && !stopLoading) {
365
- seg.loadTerrain();
366
- }
367
- }
368
-
369
- // Create normal map texture
370
- if (seg.planet.lightEnabled && !seg.normalMapReady && !seg.parentNormalMapReady) {
371
- this.whileNormalMapCreating();
372
- }
373
-
374
- if (onlyTerrain) {
375
- this.state = -1;
376
- return;
377
- }
378
-
379
- // Calculate minimal and maximal zoom index on the screen
380
- if (!this._cameraInside && seg.tileZoom > this.planet.maxCurrZoom) {
381
- this.planet.maxCurrZoom = seg.tileZoom;
382
- }
383
-
384
- if (seg.tileZoom < this.planet.minCurrZoom) {
385
- this.planet.minCurrZoom = seg.tileZoom;
386
- }
387
-
388
- seg._addViewExtent();
389
-
390
- // Finally this node proceeds to rendering.
391
- this.addToRender(inFrustum);
392
- };
393
-
394
- /**
395
- * Seraching for neighbours and pickup current node to render processing.
396
- * @public
397
- */
398
- Node.prototype.addToRender = function (inFrustum) {
399
- this.state = RENDERING;
400
-
401
- var nodes = this.planet._renderedNodes;
402
-
403
- for (var i = nodes.length - 1; i >= 0; --i) {
404
- var ni = nodes[i];
405
-
406
- var cs = this.getCommonSide(ni);
407
-
408
- if (cs !== -1) {
409
- var opcs = OPSIDE[cs];
410
-
411
- if (this.neighbors[cs].length === 0 || ni.neighbors[opcs].length === 0) {
412
- var ap = this.segment;
413
- var bp = ni.segment;
414
- var ld = ap.gridSize / (bp.gridSize * Math.pow(2, bp.tileZoom - ap.tileZoom));
415
-
416
- let cs_size = ap.gridSize,
417
- opcs_size = bp.gridSize;
418
-
419
- if (ld > 1) {
420
- cs_size = Math.ceil(ap.gridSize / ld);
421
- opcs_size = bp.gridSize;
422
- } else if (ld < 1) {
423
- cs_size = ap.gridSize;
424
- opcs_size = Math.ceil(bp.gridSize * ld);
425
- }
426
-
427
- this.sideSize[cs] = cs_size;
428
- ni.sideSize[opcs] = opcs_size;
429
-
430
- this.sideSizeLog2[cs] = Math.log2(cs_size);
431
- ni.sideSizeLog2[opcs] = Math.log2(opcs_size);
432
- }
433
-
434
- this.neighbors[cs].push(ni);
435
- ni.neighbors[opcs].push(this);
436
- }
437
- }
438
-
439
- nodes.push(this);
440
-
441
- if (!this.segment.terrainReady) {
442
- this.planet._renderCompleted = false;
443
- }
444
-
445
- let k = 0,
446
- rf = this.planet._renderedNodesInFrustum;
447
- while (inFrustum) {
448
- if (inFrustum & 1) {
449
- rf[k].push(this);
450
- }
451
- k++;
452
- inFrustum >>= 1;
453
- }
454
- };
455
-
456
- Node.prototype.getCommonSide = function (node) {
457
- var as = this.segment,
458
- bs = node.segment;
459
-
460
- if (as.tileZoom === bs.tileZoom && as._tileGroup === bs._tileGroup) {
461
- return as.getNeighborSide(bs);
462
- } else {
463
- var a = as._extentLonLat,
464
- b = bs._extentLonLat;
465
-
466
- var a_ne = a.northEast,
467
- a_sw = a.southWest,
468
- b_ne = b.northEast,
469
- b_sw = b.southWest;
470
-
471
- var a_ne_lon = a_ne.lon,
472
- a_ne_lat = a_ne.lat,
473
- a_sw_lon = a_sw.lon,
474
- a_sw_lat = a_sw.lat,
475
- b_ne_lon = b_ne.lon,
476
- b_ne_lat = b_ne.lat,
477
- b_sw_lon = b_sw.lon,
478
- b_sw_lat = b_sw.lat;
479
-
480
- if (as._tileGroup === bs._tileGroup) {
481
- if (
482
- a_ne_lon === b_sw_lon &&
483
- ((a_ne_lat <= b_ne_lat && a_sw_lat >= b_sw_lat) ||
484
- (a_ne_lat >= b_ne_lat && a_sw_lat <= b_sw_lat))
485
- ) {
486
- return E;
487
- } else if (
488
- a_sw_lon === b_ne_lon &&
489
- ((a_ne_lat <= b_ne_lat && a_sw_lat >= b_sw_lat) ||
490
- (a_ne_lat >= b_ne_lat && a_sw_lat <= b_sw_lat))
491
- ) {
492
- return W;
493
- } else if (
494
- a_ne_lat === b_sw_lat &&
495
- ((a_sw_lon >= b_sw_lon && a_ne_lon <= b_ne_lon) ||
496
- (a_sw_lon <= b_sw_lon && a_ne_lon >= b_ne_lon))
497
- ) {
498
- return N;
499
- } else if (
500
- a_sw_lat === b_ne_lat &&
501
- ((a_sw_lon >= b_sw_lon && a_ne_lon <= b_ne_lon) ||
502
- (a_sw_lon <= b_sw_lon && a_ne_lon >= b_ne_lon))
503
- ) {
504
- return S;
505
- } else if (
506
- bs.tileX === 0 &&
507
- as.tileX === Math.pow(2, as.tileZoom) - 1 &&
508
- ((a_ne_lat <= b_ne_lat && a_sw_lat >= b_sw_lat) ||
509
- (a_ne_lat >= b_ne_lat && a_sw_lat <= b_sw_lat))
510
- ) {
511
- return E;
512
- } else if (
513
- as.tileX === 0 &&
514
- bs.tileX === Math.pow(2, bs.tileZoom) - 1 &&
515
- ((a_ne_lat <= b_ne_lat && a_sw_lat >= b_sw_lat) ||
516
- (a_ne_lat >= b_ne_lat && a_sw_lat <= b_sw_lat))
517
- ) {
518
- return W;
519
- }
520
- }
521
-
522
- if (
523
- as._tileGroup === 0 &&
524
- bs._tileGroup === 1 &&
525
- as.tileY === 0 &&
526
- bs.tileY === Math.pow(2, bs.tileZoom) - 1 &&
527
- ((a_sw_lon >= b_sw_lon && a_ne_lon <= b_ne_lon) ||
528
- (a_sw_lon <= b_sw_lon && a_ne_lon >= b_ne_lon))
529
- ) {
530
- return N;
531
- } else if (
532
- as._tileGroup === 2 &&
533
- bs._tileGroup === 0 &&
534
- as.tileY === 0 &&
535
- bs.tileY === Math.pow(2, bs.tileZoom) - 1 &&
536
- ((a_sw_lon >= b_sw_lon && a_ne_lon <= b_ne_lon) ||
537
- (a_sw_lon <= b_sw_lon && a_ne_lon >= b_ne_lon))
538
- ) {
539
- return N;
540
- } else if (
541
- bs._tileGroup === 1 &&
542
- as._tileGroup === 0 &&
543
- as.tileY === Math.pow(2, as.tileZoom) - 1 &&
544
- bs.tileY === 0 &&
545
- ((a_sw_lon >= b_sw_lon && a_ne_lon <= b_ne_lon) ||
546
- (a_sw_lon <= b_sw_lon && a_ne_lon >= b_ne_lon))
547
- ) {
548
- return S;
549
- } else if (
550
- as._tileGroup === 1 &&
551
- bs._tileGroup === 0 &&
552
- as.tileY === Math.pow(2, as.tileZoom) - 1 &&
553
- bs.tileY === 0 &&
554
- ((a_sw_lon >= b_sw_lon && a_ne_lon <= b_ne_lon) ||
555
- (a_sw_lon <= b_sw_lon && a_ne_lon >= b_ne_lon))
556
- ) {
557
- return S;
558
- }
559
- }
560
-
561
- return -1;
562
- };
563
-
564
- // TODO: test test test
565
- Node.prototype.___getCommonSide___ = function (b) {
566
- var a = this,
567
- as = a.segment,
568
- bs = b.segment;
569
-
570
- if (as.tileZoom === bs.tileZoom) {
571
- return as.getNeighborSide(bs);
572
- } else if (as.tileZoom > bs.tileZoom) {
573
- let dz = as.tileZoom - bs.tileZoom,
574
- i = dz,
575
- p = this;
576
-
577
- while (i--) {
578
- p = p.parentNode;
579
- }
580
-
581
- let side = p.segment.getNeighborSide(bs);
582
-
583
- if (side !== -1) {
584
- i = dz;
585
- p = this;
586
- let _n = true;
587
-
588
- while (i--) {
589
- _n = _n && COMSIDE[p.partId][side];
590
- }
591
-
592
- if (_n) {
593
- return side;
594
- }
595
- }
596
- } else {
597
- let dz = bs.tileZoom - as.tileZoom,
598
- i = dz,
599
- p = b;
600
-
601
- while (i--) {
602
- p = p.parentNode;
603
- }
604
-
605
- let side = p.segment.getNeighborSide(as);
606
-
607
- if (side !== -1) {
608
- i = dz;
609
- p = b;
610
- let _n = true;
611
-
612
- while (i--) {
613
- _n = _n && COMSIDE[p.partId][side];
614
- }
615
-
616
- if (_n) {
617
- return OPSIDE[side];
618
- }
619
- }
620
- }
621
-
622
- return -1;
623
- };
624
-
625
- Node.prototype.whileNormalMapCreating = function () {
626
- var seg = this.segment;
627
- var maxZ = this.planet.terrain.maxZoom;
628
-
629
- if (seg.tileZoom <= maxZ && !seg.terrainIsLoading && seg.terrainReady && !seg._inTheQueue) {
630
- seg.planet._normalMapCreator.queue(seg);
631
- }
632
-
633
- var pn = this;
634
-
635
- while (pn.parentNode && !pn.segment.normalMapReady) {
636
- pn = pn.parentNode;
637
- }
638
-
639
- var dZ2 = 2 << (seg.tileZoom - pn.segment.tileZoom - 1);
640
-
641
- seg.normalMapTexture = pn.segment.normalMapTexture;
642
- seg.normalMapTextureBias[0] = seg.tileX - pn.segment.tileX * dZ2;
643
- seg.normalMapTextureBias[1] = seg.tileY - pn.segment.tileY * dZ2;
644
- seg.normalMapTextureBias[2] = 1.0 / dZ2;
645
-
646
- if (seg.tileZoom > maxZ) {
647
- if (pn.segment.tileZoom === maxZ) {
648
- seg.parentNormalMapReady = true;
649
- }
650
- }
651
- };
652
-
653
- let BOUNDS = {
654
- xmin: 0.0,
655
- ymin: 0.0,
656
- zmin: 0.0,
657
- xmax: 0.0,
658
- ymax: 0.0,
659
- zmax: 0.0
660
- };
661
-
662
- Node.prototype.whileTerrainLoading = function (terrainReadySegment, stopLoading) {
663
- const seg = this.segment;
664
- const terrain = this.planet.terrain;
665
-
666
- let pn = this;
667
-
668
- if (terrainReadySegment && terrainReadySegment.terrainReady) {
669
- pn = terrainReadySegment.node;
670
- } else {
671
- while (pn.parentNode && !pn.segment.terrainReady) {
672
- pn = pn.parentNode;
673
- }
674
- }
675
-
676
- if (pn.segment.terrainReady && this.appliedTerrainNodeId !== pn.nodeId) {
677
- let dZ2 = 2 << (seg.tileZoom - pn.segment.tileZoom - 1),
678
- offsetX = seg.tileX - pn.segment.tileX * dZ2,
679
- offsetY = seg.tileY - pn.segment.tileY * dZ2;
680
-
681
- let pseg = pn.segment;
682
-
683
- let tempVertices, tempVerticesHigh, tempVerticesLow, noDataVertices;
684
-
685
- this.appliedTerrainNodeId = pn.nodeId;
686
-
687
- let gridSize = pn.segment.gridSize / dZ2,
688
- gridSizeExt = pn.segment.fileGridSize / dZ2;
689
-
690
- BOUNDS.xmin = MAX;
691
- BOUNDS.xmax = MIN;
692
- BOUNDS.ymin = MAX;
693
- BOUNDS.ymax = MIN;
694
- BOUNDS.zmin = MAX;
695
- BOUNDS.zmax = MIN;
696
-
697
- if (gridSize >= 1) {
698
- seg.gridSize = gridSize;
699
-
700
- let len = (gridSize + 1) * (gridSize + 1) * 3;
701
- tempVertices = new Float64Array(len);
702
- tempVerticesHigh = new Float32Array(len);
703
- tempVerticesLow = new Float32Array(len);
704
-
705
- if (pseg.noDataVertices) {
706
- noDataVertices = new Uint8Array(len / 3);
707
- }
708
-
709
- getMatrixSubArrayBoundsExt(
710
- pseg.terrainVertices,
711
- pseg.terrainVerticesHigh,
712
- pseg.terrainVerticesLow,
713
- pseg.noDataVertices,
714
- pseg.gridSize,
715
- gridSize * offsetY,
716
- gridSize * offsetX,
717
- gridSize,
718
- tempVertices,
719
- tempVerticesHigh,
720
- tempVerticesLow,
721
- BOUNDS,
722
- noDataVertices
723
- );
724
- } else if (gridSizeExt >= 1) {
725
- seg.gridSize = gridSizeExt;
726
-
727
- let len = (gridSizeExt + 1) * (gridSizeExt + 1) * 3;
728
- tempVertices = new Float64Array(len);
729
- tempVerticesHigh = new Float32Array(len);
730
- tempVerticesLow = new Float32Array(len);
731
-
732
- if (pseg.noDataVertices) {
733
- noDataVertices = new Uint8Array(len / 3);
734
- }
735
-
736
- getMatrixSubArrayBoundsExt(
737
- pseg.normalMapVertices,
738
- pseg.normalMapVerticesHigh,
739
- pseg.normalMapVerticesLow,
740
- pseg.noDataVertices,
741
- pn.segment.fileGridSize,
742
- gridSizeExt * offsetY,
743
- gridSizeExt * offsetX,
744
- gridSizeExt,
745
- tempVertices,
746
- tempVerticesHigh,
747
- tempVerticesLow,
748
- BOUNDS,
749
- noDataVertices
750
- );
751
- } else {
752
- seg.gridSize = _neGridSize;
753
-
754
- let i0 = Math.floor(gridSize * offsetY),
755
- j0 = Math.floor(gridSize * offsetX);
756
-
757
- let bigOne;
758
- if (pseg.gridSize === 1) {
759
- bigOne = pseg.terrainVertices;
760
- } else {
761
- bigOne = getMatrixSubArray(pseg.terrainVertices, pseg.gridSize, i0, j0, 1);
762
- }
763
-
764
- let insideSize = 1.0 / gridSize;
765
-
766
- let t_i0 = offsetY - insideSize * i0,
767
- t_j0 = offsetX - insideSize * j0;
768
-
769
- let v_lt = new Vec3(bigOne[0], bigOne[1], bigOne[2]),
770
- v_rb = new Vec3(bigOne[9], bigOne[10], bigOne[11]);
771
-
772
- let vn = new Vec3(bigOne[3] - bigOne[0], bigOne[4] - bigOne[1], bigOne[5] - bigOne[2]),
773
- vw = new Vec3(bigOne[6] - bigOne[0], bigOne[7] - bigOne[1], bigOne[8] - bigOne[2]),
774
- ve = new Vec3(
775
- bigOne[3] - bigOne[9],
776
- bigOne[4] - bigOne[10],
777
- bigOne[5] - bigOne[11]
778
- ),
779
- vs = new Vec3(
780
- bigOne[6] - bigOne[9],
781
- bigOne[7] - bigOne[10],
782
- bigOne[8] - bigOne[11]
783
- );
784
-
785
- let coords = new Vec3();
786
-
787
- tempVertices = new Float64Array(3 * _vertOrder.length);
788
- tempVerticesHigh = new Float32Array(3 * _vertOrder.length);
789
- tempVerticesLow = new Float32Array(3 * _vertOrder.length);
790
-
791
- for (var i = 0; i < _vertOrder.length; i++) {
792
- let vi_y = _vertOrder[i].y + t_i0,
793
- vi_x = _vertOrder[i].x + t_j0;
794
-
795
- let vi_x_is = vi_x * gridSize,
796
- vi_y_is = vi_y * gridSize;
797
-
798
- if (vi_y + vi_x < insideSize) {
799
- coords = vn.scaleTo(vi_x_is).addA(vw.scaleTo(vi_y_is)).addA(v_lt);
800
- } else {
801
- coords = vs
802
- .scaleTo(1 - vi_x_is)
803
- .addA(ve.scaleTo(1 - vi_y_is))
804
- .addA(v_rb);
805
- }
806
-
807
- Vec3.doubleToTwoFloats(coords, _tempHigh, _tempLow);
808
-
809
- let i3 = i * 3;
810
-
811
- tempVertices[i3] = coords.x;
812
- tempVertices[i3 + 1] = coords.y;
813
- tempVertices[i3 + 2] = coords.z;
814
-
815
- tempVerticesHigh[i3] = _tempHigh.x;
816
- tempVerticesHigh[i3 + 1] = _tempHigh.y;
817
- tempVerticesHigh[i3 + 2] = _tempHigh.z;
818
-
819
- tempVerticesLow[i3] = _tempLow.x;
820
- tempVerticesLow[i3 + 1] = _tempLow.y;
821
- tempVerticesLow[i3 + 2] = _tempLow.z;
822
-
823
- if (coords.x < BOUNDS.xmin) BOUNDS.xmin = coords.x;
824
- if (coords.x > BOUNDS.xmax) BOUNDS.xmax = coords.x;
825
- if (coords.y < BOUNDS.ymin) BOUNDS.ymin = coords.y;
826
- if (coords.y > BOUNDS.ymax) BOUNDS.ymax = coords.y;
827
- if (coords.z < BOUNDS.zmin) BOUNDS.zmin = coords.z;
828
- if (coords.z > BOUNDS.zmax) BOUNDS.zmax = coords.z;
829
- }
830
- }
831
-
832
- seg.readyToEngage = true;
833
-
834
- seg.terrainVertices = tempVertices;
835
- seg.terrainVerticesHigh = tempVerticesHigh;
836
- seg.terrainVerticesLow = tempVerticesLow;
837
-
838
- seg.tempVertices = tempVertices;
839
- seg.tempVerticesHigh = tempVerticesHigh;
840
- seg.tempVerticesLow = tempVerticesLow;
841
-
842
- seg.noDataVertices = noDataVertices;
843
-
844
- seg.setBoundingVolume(
845
- BOUNDS.xmin,
846
- BOUNDS.ymin,
847
- BOUNDS.zmin,
848
- BOUNDS.xmax,
849
- BOUNDS.ymax,
850
- BOUNDS.zmax
851
- );
852
-
853
- if (seg.tileZoom > terrain.maxZoom) {
854
- if (pn.segment.tileZoom >= terrain.maxZoom) {
855
- //TODO: find better place for this
856
- seg._plainRadius = pn.segment._plainRadius / dZ2;
857
-
858
- seg.terrainReady = true;
859
- seg.terrainIsLoading = false;
860
-
861
- seg.terrainVertices = tempVertices;
862
- seg.terrainVerticesHigh = tempVerticesHigh;
863
- seg.terrainVerticesLow = tempVerticesLow;
864
-
865
- this.appliedTerrainNodeId = this.nodeId;
866
-
867
- if (pn.segment.terrainExists) {
868
- seg.terrainExists = true;
869
- seg.normalMapVertices = tempVertices;
870
- seg.fileGridSize = Math.sqrt(tempVertices.length / 3) - 1;
871
-
872
- let fgs = Math.sqrt(pseg.normalMapNormals.length / 3) - 1,
873
- fgsZ = fgs / dZ2;
874
-
875
- if (fgs > 1) {
876
- seg.normalMapNormals = getMatrixSubArray(
877
- pseg.normalMapNormals,
878
- fgs,
879
- fgsZ * offsetY,
880
- fgsZ * offsetX,
881
- fgsZ
882
- );
883
- } else {
884
- // TODO: interpolation
885
- seg.normalMapNormals = pseg.normalMapNormals;
886
- }
887
- }
888
- } else {
889
- pn = this;
890
- while (pn.parentNode && pn.segment.tileZoom !== terrain.maxZoom) {
891
- pn = pn.parentNode;
892
- }
893
-
894
- let pns = pn.segment;
895
-
896
- if (!pns.initialized) {
897
- pns.initialize();
898
- }
899
-
900
- if (!pns.plainProcessing) {
901
- pn.segment.createPlainSegmentAsync();
902
- }
903
-
904
- if (pns.plainReady && !stopLoading) {
905
- pns.loadTerrain(true);
906
- }
907
- }
908
- }
909
- }
910
- };
911
-
912
- Node.prototype.destroy = function () {
913
- this.state = NOTRENDERING;
914
- this.segment.destroySegment();
915
- var n = this.neighbors;
916
- n[N] && n[N].neighbors && (n[N].neighbors[S] = []);
917
- n[E] && n[E].neighbors && (n[E].neighbors[W] = []);
918
- n[S] && n[S].neighbors && (n[S].neighbors[N] = []);
919
- n[W] && n[W].neighbors && (n[W].neighbors[E] = []);
920
- this.neighbors = null;
921
- this.parentNode = null;
922
- this.sideSize = null;
923
- this.sideSizeLog2 = null;
924
- this.segment = null;
925
- };
926
-
927
- Node.prototype.clearTree = function () {
928
- var state = this.getState();
929
-
930
- if (state === NOTRENDERING) {
931
- this.destroyBranches();
932
- } else if (state === RENDERING) {
933
- this.destroyBranches();
934
- } else {
935
- for (var i = 0; i < this.nodes.length; i++) {
936
- this.nodes[i] && this.nodes[i].clearTree();
937
- }
938
- }
939
- };
940
-
941
- Node.prototype.clearBranches = function () {
942
- for (let i = 0; i < this.nodes.length; i++) {
943
- this.nodes[i].clearBranches();
944
- this.nodes[i].segment.deleteMaterials();
945
- }
946
- };
947
-
948
- Node.prototype.destroyBranches = function () {
949
- if (this.ready) {
950
- var nodesToRemove = [],
951
- i;
952
-
953
- for (i = 0; i < this.nodes.length; i++) {
954
- nodesToRemove[i] = this.nodes[i];
955
- }
956
-
957
- this.ready = false;
958
- this.nodes.length = 0;
959
-
960
- for (i = 0; i < nodesToRemove.length; i++) {
961
- nodesToRemove[i].destroyBranches();
962
- nodesToRemove[i].destroy();
963
- nodesToRemove[i] = null;
964
- }
965
-
966
- nodesToRemove.length = 0;
967
- nodesToRemove = null;
968
- }
969
- };
970
-
971
- Node.prototype.traverseTree = function (callback) {
972
- callback(this);
973
- if (this.ready) {
974
- for (var i = 0; i < this.nodes.length; i++) {
975
- this.nodes[i].traverseTree(callback);
976
- }
977
- }
978
- };
979
-
980
- Node.prototype.getOffsetOppositeNeighbourSide = function (neighbourNode, side) {
981
- let pNode = this,
982
- neighbourZoom = neighbourNode.segment.tileZoom,
983
- offset = 0;
984
-
985
- while (pNode.segment.tileZoom > neighbourZoom) {
986
- offset += PARTOFFSET[pNode.partId][side] / (1 << (pNode.segment.tileZoom - neighbourZoom));
987
- pNode = pNode.parentNode;
988
- }
989
-
990
- return offset;
991
- };
992
-
993
- export { Node };
1
+ "use strict";
2
+
3
+ import { Extent } from "../Extent.js";
4
+ import { LonLat } from "../LonLat.js";
5
+ import { MAX, MIN } from "../math.js";
6
+ import { Vec3 } from "../math/Vec3.js";
7
+ import { MAX_LAT } from "../mercator.js";
8
+ import { EPSG3857 } from "../proj/EPSG3857.js";
9
+ import { EPSG4326 } from "../proj/EPSG4326.js";
10
+ import { MAX_NORMAL_ZOOM } from "../segment/Segment.js";
11
+ import { getMatrixSubArray, getMatrixSubArrayBoundsExt } from "../utils/shared.js";
12
+ import {
13
+ COMSIDE,
14
+ E,
15
+ MAX_RENDERED_NODES,
16
+ N,
17
+ NE,
18
+ NEIGHBOUR,
19
+ NOTRENDERING,
20
+ NW,
21
+ OPPART,
22
+ OPSIDE,
23
+ PARTOFFSET,
24
+ RENDERING,
25
+ S,
26
+ SE,
27
+ SW,
28
+ VISIBLE_DISTANCE,
29
+ W,
30
+ WALKTHROUGH
31
+ } from "./quadTree.js";
32
+
33
+ const VISIBLE_HEIGHT = 1400000.0;
34
+
35
+ let _tempHigh = new Vec3(),
36
+ _tempLow = new Vec3();
37
+
38
+ const _vertOrder = [
39
+ { x: 0, y: 0 },
40
+ { x: 1, y: 0 },
41
+ { x: 0, y: 1 },
42
+ { x: 1, y: 1 }
43
+ ];
44
+ const _neGridSize = Math.sqrt(_vertOrder.length) - 1;
45
+
46
+ let BOUNDS = {
47
+ xmin: 0.0,
48
+ ymin: 0.0,
49
+ zmin: 0.0,
50
+ xmax: 0.0,
51
+ ymax: 0.0,
52
+ zmax: 0.0
53
+ };
54
+
55
+ /**
56
+ * Quad tree planet segment node.
57
+ * @constructor
58
+ * @param {Segment|og.planetSegment.SegmentLonLat} segmentPrototype - Planet segment node constructor.
59
+ * @param {RenderNode} planet - Planet render node.
60
+ * @param {number} partId - NorthEast, SouthWest etc.
61
+ * @param {quadTree.Node} parent - Parent of this node.
62
+ * @param {number} id - Tree node identifier (id * 4 + 1);
63
+ * @param {number} tileZoom - Deep index of the quad tree.
64
+ * @param {Extent} extent - Planet segment extent.
65
+ */
66
+ class Node {
67
+ constructor(SegmentPrototype, planet, partId, parent, id, tileZoom, extent) {
68
+ this.SegmentPrototype = SegmentPrototype;
69
+ this.planet = planet;
70
+ this.parentNode = parent;
71
+ this.partId = partId;
72
+ this.nodeId = partId + id;
73
+ this.state = null;
74
+ this.appliedTerrainNodeId = -1;
75
+ this.sideSize = [1, 1, 1, 1];
76
+ this.sideSizeLog2 = [0, 0, 0, 0];
77
+ this.ready = false;
78
+ this.neighbors = [[], [], [], []];
79
+ this.equalizedNeighborId = [-1, -1, -1, -1];
80
+ this.equalizedNeighborGridSize = [-1, -1, -1, -1];
81
+ this.nodes = [null, null, null, null];
82
+ this.segment = new SegmentPrototype(this, planet, tileZoom, extent);
83
+ this._cameraInside = false;
84
+ this.inFrustum = 0;
85
+ this.createBounds();
86
+ this.planet._createdNodesCount++;
87
+ }
88
+
89
+ createChildrenNodes() {
90
+ this.ready = true;
91
+
92
+ var p = this.planet;
93
+ var ps = this.segment;
94
+ var ext = ps._extent;
95
+ var size_x = ext.getWidth() * 0.5;
96
+ var size_y = ext.getHeight() * 0.5;
97
+ var ne = ext.northEast,
98
+ sw = ext.southWest;
99
+ var z = ps.tileZoom + 1;
100
+ var id = this.nodeId * 4 + 1;
101
+ var c = new LonLat(sw.lon + size_x, sw.lat + size_y);
102
+ var nd = this.nodes;
103
+
104
+ nd[NW] = new Node(
105
+ this.SegmentPrototype,
106
+ p,
107
+ NW,
108
+ this,
109
+ id,
110
+ z,
111
+ new Extent(new LonLat(sw.lon, sw.lat + size_y), new LonLat(sw.lon + size_x, ne.lat))
112
+ );
113
+
114
+ nd[NE] = new Node(
115
+ this.SegmentPrototype,
116
+ p,
117
+ NE,
118
+ this,
119
+ id,
120
+ z,
121
+ new Extent(c, new LonLat(ne.lon, ne.lat))
122
+ );
123
+
124
+ nd[SW] = new Node(
125
+ this.SegmentPrototype,
126
+ p,
127
+ SW,
128
+ this,
129
+ id,
130
+ z,
131
+ new Extent(new LonLat(sw.lon, sw.lat), c)
132
+ );
133
+
134
+ nd[SE] = new Node(
135
+ this.SegmentPrototype,
136
+ p,
137
+ SE,
138
+ this,
139
+ id,
140
+ z,
141
+ new Extent(new LonLat(sw.lon + size_x, sw.lat), new LonLat(ne.lon, sw.lat + size_y))
142
+ );
143
+ }
144
+
145
+ createBounds() {
146
+ let seg = this.segment;
147
+ seg._setExtentLonLat();
148
+ if (seg.tileZoom === 0) {
149
+ seg.setBoundingSphere(0.0, 0.0, 0.0, new Vec3(0.0, 0.0, seg.planet.ellipsoid._a));
150
+ } else if (seg.tileZoom < seg.planet.terrain.minZoom) {
151
+ seg.createBoundsByExtent();
152
+ } else {
153
+ seg.createBoundsByParent();
154
+ }
155
+ }
156
+
157
+ getState() {
158
+ if (this.state === -1) {
159
+ return this.state;
160
+ }
161
+ var pn = this.parentNode;
162
+ while (pn) {
163
+ if (pn.state !== WALKTHROUGH) {
164
+ return NOTRENDERING;
165
+ }
166
+ pn = pn.parentNode;
167
+ }
168
+ return this.state;
169
+ }
170
+
171
+ /**
172
+ * Returns the same deep existent neighbour node.
173
+ * @public
174
+ * @param {Number} side - Neighbour side index e.g. og.quadTree.N, og.quadTree.W etc.
175
+ * @returns {quadTree.Node} -
176
+ */
177
+ getEqualNeighbor(side) {
178
+ var pn = this;
179
+ var part = NEIGHBOUR[side][pn.partId];
180
+ if (part !== -1) {
181
+ return pn.parentNode.nodes[part];
182
+ } else {
183
+ var pathId = [];
184
+ while (pn.parentNode) {
185
+ pathId.push(pn.partId);
186
+ part = NEIGHBOUR[side][pn.partId];
187
+ pn = pn.parentNode;
188
+ if (part !== -1) {
189
+ var i = pathId.length;
190
+ side = OPSIDE[side];
191
+ while (pn && i--) {
192
+ part = OPPART[side][pathId[i]];
193
+ pn = pn.nodes[part];
194
+ }
195
+ return pn;
196
+ }
197
+ }
198
+ }
199
+ }
200
+
201
+ isBrother(node) {
202
+ return !(this.parentNode || node.parentNode) || this.parentNode.id === node.parentNode.id;
203
+ }
204
+
205
+ renderTree(cam, maxZoom, terrainReadySegment, stopLoading) {
206
+ if (
207
+ this.planet._renderedNodes.length >= MAX_RENDERED_NODES ||
208
+ this.planet._nodeCounterError_ > 2000
209
+ ) {
210
+ return;
211
+ }
212
+
213
+ this.planet._nodeCounterError_++;
214
+
215
+ this.state = WALKTHROUGH;
216
+
217
+ this.neighbors[0] = null;
218
+ this.neighbors[1] = null;
219
+ this.neighbors[2] = null;
220
+ this.neighbors[3] = null;
221
+
222
+ this.neighbors[0] = [];
223
+ this.neighbors[1] = [];
224
+ this.neighbors[2] = [];
225
+ this.neighbors[3] = [];
226
+
227
+ let seg = this.segment,
228
+ planet = this.planet;
229
+
230
+ this._cameraInside = false;
231
+
232
+ let insideLonLat = null;
233
+
234
+ // Search a node which the camera is flying over.
235
+ if (!this.parentNode || this.parentNode._cameraInside) {
236
+ let inside;
237
+ if (Math.abs(cam._lonLat.lat) <= MAX_LAT && seg._projection.id === EPSG3857.id) {
238
+ inside = seg._extent.isInside(cam._lonLatMerc);
239
+ insideLonLat = cam._lonLatMerc;
240
+ } else if (seg._projection.id === EPSG4326.id) {
241
+ inside = seg._extent.isInside(cam._lonLat);
242
+ insideLonLat = cam._lonLat;
243
+ }
244
+
245
+ if (inside) {
246
+ cam._insideSegmentPosition.lon = insideLonLat.lon;
247
+ cam._insideSegmentPosition.lat = insideLonLat.lat;
248
+ cam._insideSegment = seg;
249
+ this._cameraInside = true;
250
+ }
251
+ }
252
+
253
+ this.inFrustum = 0;
254
+
255
+ let frustums = cam.frustums,
256
+ numFrustums = frustums.length;
257
+
258
+ if (seg.tileZoom < 6) {
259
+ for (let i = 0; i < numFrustums; i++) {
260
+ if (frustums[i].containsSphere(seg.bsphere)) {
261
+ this.inFrustum |= 1 << i;
262
+ }
263
+ }
264
+ } else {
265
+ let commonFrustumFlag = 1 << (numFrustums - 1 - 1);
266
+ for (let i = 0; commonFrustumFlag && i < numFrustums; i++) {
267
+ if (seg.terrainReady) {
268
+ if (frustums[i].containsBox(seg.bbox)) {
269
+ commonFrustumFlag >>= 1;
270
+ this.inFrustum |= 1 << i;
271
+ }
272
+ } else {
273
+ if (frustums[i].containsSphere(seg.bsphere)) {
274
+ commonFrustumFlag >>= 1;
275
+ this.inFrustum |= 1 << i;
276
+ }
277
+ }
278
+ }
279
+ }
280
+
281
+ if (this.inFrustum || this._cameraInside || seg.tileZoom < 3) {
282
+ let h = cam._lonLat.height;
283
+
284
+ let altVis =
285
+ cam.eye.distance(seg.bsphere.center) - seg.bsphere.radius <
286
+ VISIBLE_DISTANCE * Math.sqrt(h) ||
287
+ (seg.tileZoom < 4 && !seg.terrainReady) ||
288
+ seg.tileZoom < 2;
289
+
290
+ if ((this.inFrustum && (altVis || h > 10000.0)) || this._cameraInside) {
291
+ seg._collectVisibleNodes();
292
+ }
293
+
294
+ if (seg.tileZoom < 2 && seg.normalMapReady) {
295
+ this.traverseNodes(cam, maxZoom, terrainReadySegment, stopLoading);
296
+ } else if ((!maxZoom && seg.acceptForRendering(cam)) || seg.tileZoom === maxZoom) {
297
+ this.prepareForRendering(
298
+ cam,
299
+ altVis,
300
+ this.inFrustum,
301
+ terrainReadySegment,
302
+ stopLoading
303
+ );
304
+ } else if (seg.tileZoom < planet.terrain._maxNodeZoom && seg.terrainReady) {
305
+ // Deleting terrainReady here, you have to remove
306
+ // this.appliedTerrainNodeId !== pn.nodeId in whileTerrainLoading,
307
+ // also have to fix createBoundsByParent(*)
308
+ this.traverseNodes(cam, maxZoom, seg, stopLoading);
309
+ } else {
310
+ this.prepareForRendering(
311
+ cam,
312
+ altVis,
313
+ this.inFrustum,
314
+ terrainReadySegment,
315
+ stopLoading
316
+ );
317
+ }
318
+ } else {
319
+ this.state = NOTRENDERING;
320
+ }
321
+ }
322
+
323
+ traverseNodes(cam, maxZoom, terrainReadySegment, stopLoading) {
324
+ if (!this.ready) {
325
+ this.createChildrenNodes();
326
+ }
327
+
328
+ let n = this.nodes;
329
+
330
+ n[0].renderTree(cam, maxZoom, terrainReadySegment, stopLoading);
331
+ n[1].renderTree(cam, maxZoom, terrainReadySegment, stopLoading);
332
+ n[2].renderTree(cam, maxZoom, terrainReadySegment, stopLoading);
333
+ n[3].renderTree(cam, maxZoom, terrainReadySegment, stopLoading);
334
+ }
335
+
336
+ prepareForRendering(cam, altVis, inFrustum, terrainReadySegment, stopLoading) {
337
+ let seg = this.segment;
338
+
339
+ if (cam._lonLat.height < VISIBLE_HEIGHT) {
340
+ if (altVis) {
341
+ this.renderNode(inFrustum, !inFrustum, terrainReadySegment, stopLoading);
342
+ } else {
343
+ this.state = NOTRENDERING;
344
+ }
345
+ } else {
346
+ if (seg.tileZoom < 2) {
347
+ this.renderNode(inFrustum, !inFrustum, terrainReadySegment, stopLoading);
348
+ } else if (seg.tileZoom > MAX_NORMAL_ZOOM) {
349
+ this.renderNode(inFrustum, !inFrustum, terrainReadySegment, stopLoading);
350
+ } else if (
351
+ seg._swNorm.dot(cam._n) > 0.0 ||
352
+ seg._nwNorm.dot(cam._n) > 0.0 ||
353
+ seg._neNorm.dot(cam._n) > 0.0 ||
354
+ seg._seNorm.dot(cam._n) > 0.0
355
+ ) {
356
+ this.renderNode(inFrustum, !inFrustum, terrainReadySegment, stopLoading);
357
+ } else {
358
+ this.state = NOTRENDERING;
359
+ }
360
+ }
361
+ }
362
+
363
+ renderNode(inFrustum, onlyTerrain, terrainReadySegment, stopLoading) {
364
+ var seg = this.segment;
365
+
366
+ // Create and load terrain data
367
+ if (!seg.terrainReady) {
368
+ if (!seg.initialized) {
369
+ seg.initialize();
370
+ }
371
+
372
+ this.whileTerrainLoading(terrainReadySegment, stopLoading);
373
+
374
+ if (!seg.plainProcessing) {
375
+ seg.createPlainSegmentAsync();
376
+ }
377
+
378
+ if (seg.plainReady && !stopLoading) {
379
+ seg.loadTerrain();
380
+ }
381
+ }
382
+
383
+ // Create normal map texture
384
+ if (seg.planet.lightEnabled && !seg.normalMapReady /* && !seg.parentNormalMapReady*/) {
385
+ this.whileNormalMapCreating();
386
+ }
387
+
388
+ if (onlyTerrain) {
389
+ this.state = -1;
390
+ return;
391
+ }
392
+
393
+ // Calculate minimal and maximal zoom index on the screen
394
+ if (!this._cameraInside && seg.tileZoom > this.planet.maxCurrZoom) {
395
+ this.planet.maxCurrZoom = seg.tileZoom;
396
+ }
397
+
398
+ if (seg.tileZoom < this.planet.minCurrZoom) {
399
+ this.planet.minCurrZoom = seg.tileZoom;
400
+ }
401
+
402
+ seg._addViewExtent();
403
+
404
+ // Finally this node proceeds to rendering.
405
+ this.addToRender(inFrustum);
406
+ }
407
+
408
+ /**
409
+ * Seraching for neighbours and pickup current node to render processing.
410
+ * @public
411
+ */
412
+ addToRender(inFrustum) {
413
+ this.state = RENDERING;
414
+
415
+ var nodes = this.planet._renderedNodes;
416
+
417
+ for (var i = nodes.length - 1; i >= 0; --i) {
418
+ var ni = nodes[i];
419
+
420
+ var cs = this.getCommonSide(ni);
421
+
422
+ if (cs !== -1) {
423
+ var opcs = OPSIDE[cs];
424
+
425
+ if (this.neighbors[cs].length === 0 || ni.neighbors[opcs].length === 0) {
426
+ var ap = this.segment;
427
+ var bp = ni.segment;
428
+ var ld = ap.gridSize / (bp.gridSize * Math.pow(2, bp.tileZoom - ap.tileZoom));
429
+
430
+ let cs_size = ap.gridSize,
431
+ opcs_size = bp.gridSize;
432
+
433
+ if (ld > 1) {
434
+ cs_size = Math.ceil(ap.gridSize / ld);
435
+ opcs_size = bp.gridSize;
436
+ } else if (ld < 1) {
437
+ cs_size = ap.gridSize;
438
+ opcs_size = Math.ceil(bp.gridSize * ld);
439
+ }
440
+
441
+ this.sideSize[cs] = cs_size;
442
+ ni.sideSize[opcs] = opcs_size;
443
+
444
+ this.sideSizeLog2[cs] = Math.log2(cs_size);
445
+ ni.sideSizeLog2[opcs] = Math.log2(opcs_size);
446
+ }
447
+
448
+ this.neighbors[cs].push(ni);
449
+ ni.neighbors[opcs].push(this);
450
+ }
451
+ }
452
+
453
+ nodes.push(this);
454
+
455
+ if (!this.segment.terrainReady) {
456
+ this.planet._renderCompleted = false;
457
+ }
458
+
459
+ let k = 0,
460
+ rf = this.planet._renderedNodesInFrustum;
461
+ while (inFrustum) {
462
+ if (inFrustum & 1) {
463
+ rf[k].push(this);
464
+ }
465
+ k++;
466
+ inFrustum >>= 1;
467
+ }
468
+ }
469
+
470
+ getCommonSide(node) {
471
+ var as = this.segment,
472
+ bs = node.segment;
473
+
474
+ if (as.tileZoom === bs.tileZoom && as._tileGroup === bs._tileGroup) {
475
+ return as.getNeighborSide(bs);
476
+ } else {
477
+ var a = as._extentLonLat,
478
+ b = bs._extentLonLat;
479
+
480
+ var a_ne = a.northEast,
481
+ a_sw = a.southWest,
482
+ b_ne = b.northEast,
483
+ b_sw = b.southWest;
484
+
485
+ var a_ne_lon = a_ne.lon,
486
+ a_ne_lat = a_ne.lat,
487
+ a_sw_lon = a_sw.lon,
488
+ a_sw_lat = a_sw.lat,
489
+ b_ne_lon = b_ne.lon,
490
+ b_ne_lat = b_ne.lat,
491
+ b_sw_lon = b_sw.lon,
492
+ b_sw_lat = b_sw.lat;
493
+
494
+ if (as._tileGroup === bs._tileGroup) {
495
+ if (
496
+ a_ne_lon === b_sw_lon &&
497
+ ((a_ne_lat <= b_ne_lat && a_sw_lat >= b_sw_lat) ||
498
+ (a_ne_lat >= b_ne_lat && a_sw_lat <= b_sw_lat))
499
+ ) {
500
+ return E;
501
+ } else if (
502
+ a_sw_lon === b_ne_lon &&
503
+ ((a_ne_lat <= b_ne_lat && a_sw_lat >= b_sw_lat) ||
504
+ (a_ne_lat >= b_ne_lat && a_sw_lat <= b_sw_lat))
505
+ ) {
506
+ return W;
507
+ } else if (
508
+ a_ne_lat === b_sw_lat &&
509
+ ((a_sw_lon >= b_sw_lon && a_ne_lon <= b_ne_lon) ||
510
+ (a_sw_lon <= b_sw_lon && a_ne_lon >= b_ne_lon))
511
+ ) {
512
+ return N;
513
+ } else if (
514
+ a_sw_lat === b_ne_lat &&
515
+ ((a_sw_lon >= b_sw_lon && a_ne_lon <= b_ne_lon) ||
516
+ (a_sw_lon <= b_sw_lon && a_ne_lon >= b_ne_lon))
517
+ ) {
518
+ return S;
519
+ } else if (
520
+ bs.tileX === 0 &&
521
+ as.tileX === Math.pow(2, as.tileZoom) - 1 &&
522
+ ((a_ne_lat <= b_ne_lat && a_sw_lat >= b_sw_lat) ||
523
+ (a_ne_lat >= b_ne_lat && a_sw_lat <= b_sw_lat))
524
+ ) {
525
+ return E;
526
+ } else if (
527
+ as.tileX === 0 &&
528
+ bs.tileX === Math.pow(2, bs.tileZoom) - 1 &&
529
+ ((a_ne_lat <= b_ne_lat && a_sw_lat >= b_sw_lat) ||
530
+ (a_ne_lat >= b_ne_lat && a_sw_lat <= b_sw_lat))
531
+ ) {
532
+ return W;
533
+ }
534
+ }
535
+
536
+ if (
537
+ as._tileGroup === 0 &&
538
+ bs._tileGroup === 1 &&
539
+ as.tileY === 0 &&
540
+ bs.tileY === Math.pow(2, bs.tileZoom) - 1 &&
541
+ ((a_sw_lon >= b_sw_lon && a_ne_lon <= b_ne_lon) ||
542
+ (a_sw_lon <= b_sw_lon && a_ne_lon >= b_ne_lon))
543
+ ) {
544
+ return N;
545
+ } else if (
546
+ as._tileGroup === 2 &&
547
+ bs._tileGroup === 0 &&
548
+ as.tileY === 0 &&
549
+ bs.tileY === Math.pow(2, bs.tileZoom) - 1 &&
550
+ ((a_sw_lon >= b_sw_lon && a_ne_lon <= b_ne_lon) ||
551
+ (a_sw_lon <= b_sw_lon && a_ne_lon >= b_ne_lon))
552
+ ) {
553
+ return N;
554
+ } else if (
555
+ bs._tileGroup === 1 &&
556
+ as._tileGroup === 0 &&
557
+ as.tileY === Math.pow(2, as.tileZoom) - 1 &&
558
+ bs.tileY === 0 &&
559
+ ((a_sw_lon >= b_sw_lon && a_ne_lon <= b_ne_lon) ||
560
+ (a_sw_lon <= b_sw_lon && a_ne_lon >= b_ne_lon))
561
+ ) {
562
+ return S;
563
+ } else if (
564
+ as._tileGroup === 1 &&
565
+ bs._tileGroup === 0 &&
566
+ as.tileY === Math.pow(2, as.tileZoom) - 1 &&
567
+ bs.tileY === 0 &&
568
+ ((a_sw_lon >= b_sw_lon && a_ne_lon <= b_ne_lon) ||
569
+ (a_sw_lon <= b_sw_lon && a_ne_lon >= b_ne_lon))
570
+ ) {
571
+ return S;
572
+ }
573
+ }
574
+
575
+ return -1;
576
+ }
577
+
578
+ // TODO: test test test
579
+ ___getCommonSide___(b) {
580
+ var a = this,
581
+ as = a.segment,
582
+ bs = b.segment;
583
+
584
+ if (as.tileZoom === bs.tileZoom) {
585
+ return as.getNeighborSide(bs);
586
+ } else if (as.tileZoom > bs.tileZoom) {
587
+ let dz = as.tileZoom - bs.tileZoom,
588
+ i = dz,
589
+ p = this;
590
+
591
+ while (i--) {
592
+ p = p.parentNode;
593
+ }
594
+
595
+ let side = p.segment.getNeighborSide(bs);
596
+
597
+ if (side !== -1) {
598
+ i = dz;
599
+ p = this;
600
+ let _n = true;
601
+
602
+ while (i--) {
603
+ _n = _n && COMSIDE[p.partId][side];
604
+ }
605
+
606
+ if (_n) {
607
+ return side;
608
+ }
609
+ }
610
+ } else {
611
+ let dz = bs.tileZoom - as.tileZoom,
612
+ i = dz,
613
+ p = b;
614
+
615
+ while (i--) {
616
+ p = p.parentNode;
617
+ }
618
+
619
+ let side = p.segment.getNeighborSide(as);
620
+
621
+ if (side !== -1) {
622
+ i = dz;
623
+ p = b;
624
+ let _n = true;
625
+
626
+ while (i--) {
627
+ _n = _n && COMSIDE[p.partId][side];
628
+ }
629
+
630
+ if (_n) {
631
+ return OPSIDE[side];
632
+ }
633
+ }
634
+ }
635
+
636
+ return -1;
637
+ }
638
+
639
+ whileNormalMapCreating() {
640
+ var seg = this.segment;
641
+ var maxZ = this.planet.terrain.maxZoom;
642
+
643
+ if (seg.tileZoom <= maxZ && !seg.terrainIsLoading && seg.terrainReady && !seg._inTheQueue) {
644
+ seg.planet._normalMapCreator.queue(seg);
645
+ }
646
+
647
+ var pn = this;
648
+
649
+ while (pn.parentNode && !pn.segment.normalMapReady) {
650
+ pn = pn.parentNode;
651
+ }
652
+
653
+ var dZ2 = 2 << (seg.tileZoom - pn.segment.tileZoom - 1);
654
+
655
+ seg.normalMapTexture = pn.segment.normalMapTexture;
656
+ seg.normalMapTextureBias[0] = seg.tileX - pn.segment.tileX * dZ2;
657
+ seg.normalMapTextureBias[1] = seg.tileY - pn.segment.tileY * dZ2;
658
+ seg.normalMapTextureBias[2] = 1.0 / dZ2;
659
+
660
+ if (seg.tileZoom > maxZ) {
661
+ if (pn.segment.tileZoom === maxZ) {
662
+ seg.parentNormalMapReady = true;
663
+ }
664
+ }
665
+ }
666
+
667
+ whileTerrainLoading(terrainReadySegment, stopLoading) {
668
+ const seg = this.segment;
669
+ const terrain = this.planet.terrain;
670
+
671
+ let pn = this;
672
+
673
+ if (terrainReadySegment && terrainReadySegment.terrainReady) {
674
+ pn = terrainReadySegment.node;
675
+ } else {
676
+ while (pn.parentNode && !pn.segment.terrainReady) {
677
+ pn = pn.parentNode;
678
+ }
679
+ }
680
+
681
+ if (pn.segment.terrainReady && this.appliedTerrainNodeId !== pn.nodeId) {
682
+ let dZ2 = 2 << (seg.tileZoom - pn.segment.tileZoom - 1),
683
+ offsetX = seg.tileX - pn.segment.tileX * dZ2,
684
+ offsetY = seg.tileY - pn.segment.tileY * dZ2;
685
+
686
+ let pseg = pn.segment;
687
+
688
+ let tempVertices, tempVerticesHigh, tempVerticesLow, noDataVertices;
689
+
690
+ this.appliedTerrainNodeId = pn.nodeId;
691
+
692
+ let gridSize = pn.segment.gridSize / dZ2,
693
+ gridSizeExt = pn.segment.fileGridSize / dZ2;
694
+
695
+ BOUNDS.xmin = MAX;
696
+ BOUNDS.xmax = MIN;
697
+ BOUNDS.ymin = MAX;
698
+ BOUNDS.ymax = MIN;
699
+ BOUNDS.zmin = MAX;
700
+ BOUNDS.zmax = MIN;
701
+
702
+ if (gridSize >= 1) {
703
+ seg.gridSize = gridSize;
704
+
705
+ let len = (gridSize + 1) * (gridSize + 1) * 3;
706
+ tempVertices = new Float64Array(len);
707
+ tempVerticesHigh = new Float32Array(len);
708
+ tempVerticesLow = new Float32Array(len);
709
+
710
+ if (pseg.noDataVertices) {
711
+ noDataVertices = new Uint8Array(len / 3);
712
+ }
713
+
714
+ getMatrixSubArrayBoundsExt(
715
+ pseg.terrainVertices,
716
+ pseg.terrainVerticesHigh,
717
+ pseg.terrainVerticesLow,
718
+ pseg.noDataVertices,
719
+ pseg.gridSize,
720
+ gridSize * offsetY,
721
+ gridSize * offsetX,
722
+ gridSize,
723
+ tempVertices,
724
+ tempVerticesHigh,
725
+ tempVerticesLow,
726
+ BOUNDS,
727
+ noDataVertices
728
+ );
729
+ } else if (gridSizeExt >= 1) {
730
+ seg.gridSize = gridSizeExt;
731
+
732
+ let len = (gridSizeExt + 1) * (gridSizeExt + 1) * 3;
733
+ tempVertices = new Float64Array(len);
734
+ tempVerticesHigh = new Float32Array(len);
735
+ tempVerticesLow = new Float32Array(len);
736
+
737
+ if (pseg.noDataVertices) {
738
+ noDataVertices = new Uint8Array(len / 3);
739
+ }
740
+
741
+ getMatrixSubArrayBoundsExt(
742
+ pseg.normalMapVertices,
743
+ pseg.normalMapVerticesHigh,
744
+ pseg.normalMapVerticesLow,
745
+ pseg.noDataVertices,
746
+ pn.segment.fileGridSize,
747
+ gridSizeExt * offsetY,
748
+ gridSizeExt * offsetX,
749
+ gridSizeExt,
750
+ tempVertices,
751
+ tempVerticesHigh,
752
+ tempVerticesLow,
753
+ BOUNDS,
754
+ noDataVertices
755
+ );
756
+ } else {
757
+ seg.gridSize = _neGridSize;
758
+
759
+ let i0 = Math.floor(gridSize * offsetY),
760
+ j0 = Math.floor(gridSize * offsetX);
761
+
762
+ let bigOne;
763
+ if (pseg.gridSize === 1) {
764
+ bigOne = pseg.terrainVertices;
765
+ } else {
766
+ bigOne = getMatrixSubArray(pseg.terrainVertices, pseg.gridSize, i0, j0, 1);
767
+ }
768
+
769
+ let insideSize = 1.0 / gridSize;
770
+
771
+ let t_i0 = offsetY - insideSize * i0,
772
+ t_j0 = offsetX - insideSize * j0;
773
+
774
+ let v_lt = new Vec3(bigOne[0], bigOne[1], bigOne[2]),
775
+ v_rb = new Vec3(bigOne[9], bigOne[10], bigOne[11]);
776
+
777
+ let vn = new Vec3(
778
+ bigOne[3] - bigOne[0],
779
+ bigOne[4] - bigOne[1],
780
+ bigOne[5] - bigOne[2]
781
+ ),
782
+ vw = new Vec3(
783
+ bigOne[6] - bigOne[0],
784
+ bigOne[7] - bigOne[1],
785
+ bigOne[8] - bigOne[2]
786
+ ),
787
+ ve = new Vec3(
788
+ bigOne[3] - bigOne[9],
789
+ bigOne[4] - bigOne[10],
790
+ bigOne[5] - bigOne[11]
791
+ ),
792
+ vs = new Vec3(
793
+ bigOne[6] - bigOne[9],
794
+ bigOne[7] - bigOne[10],
795
+ bigOne[8] - bigOne[11]
796
+ );
797
+
798
+ let coords = new Vec3();
799
+
800
+ tempVertices = new Float64Array(3 * _vertOrder.length);
801
+ tempVerticesHigh = new Float32Array(3 * _vertOrder.length);
802
+ tempVerticesLow = new Float32Array(3 * _vertOrder.length);
803
+
804
+ for (var i = 0; i < _vertOrder.length; i++) {
805
+ let vi_y = _vertOrder[i].y + t_i0,
806
+ vi_x = _vertOrder[i].x + t_j0;
807
+
808
+ let vi_x_is = vi_x * gridSize,
809
+ vi_y_is = vi_y * gridSize;
810
+
811
+ if (vi_y + vi_x < insideSize) {
812
+ coords = vn.scaleTo(vi_x_is).addA(vw.scaleTo(vi_y_is)).addA(v_lt);
813
+ } else {
814
+ coords = vs
815
+ .scaleTo(1 - vi_x_is)
816
+ .addA(ve.scaleTo(1 - vi_y_is))
817
+ .addA(v_rb);
818
+ }
819
+
820
+ Vec3.doubleToTwoFloats(coords, _tempHigh, _tempLow);
821
+
822
+ let i3 = i * 3;
823
+
824
+ tempVertices[i3] = coords.x;
825
+ tempVertices[i3 + 1] = coords.y;
826
+ tempVertices[i3 + 2] = coords.z;
827
+
828
+ tempVerticesHigh[i3] = _tempHigh.x;
829
+ tempVerticesHigh[i3 + 1] = _tempHigh.y;
830
+ tempVerticesHigh[i3 + 2] = _tempHigh.z;
831
+
832
+ tempVerticesLow[i3] = _tempLow.x;
833
+ tempVerticesLow[i3 + 1] = _tempLow.y;
834
+ tempVerticesLow[i3 + 2] = _tempLow.z;
835
+
836
+ if (coords.x < BOUNDS.xmin) BOUNDS.xmin = coords.x;
837
+ if (coords.x > BOUNDS.xmax) BOUNDS.xmax = coords.x;
838
+ if (coords.y < BOUNDS.ymin) BOUNDS.ymin = coords.y;
839
+ if (coords.y > BOUNDS.ymax) BOUNDS.ymax = coords.y;
840
+ if (coords.z < BOUNDS.zmin) BOUNDS.zmin = coords.z;
841
+ if (coords.z > BOUNDS.zmax) BOUNDS.zmax = coords.z;
842
+ }
843
+ }
844
+
845
+ seg.readyToEngage = true;
846
+
847
+ seg.terrainVertices = tempVertices;
848
+ seg.terrainVerticesHigh = tempVerticesHigh;
849
+ seg.terrainVerticesLow = tempVerticesLow;
850
+
851
+ seg.tempVertices = tempVertices;
852
+ seg.tempVerticesHigh = tempVerticesHigh;
853
+ seg.tempVerticesLow = tempVerticesLow;
854
+
855
+ seg.noDataVertices = noDataVertices;
856
+
857
+ seg.setBoundingVolume(
858
+ BOUNDS.xmin,
859
+ BOUNDS.ymin,
860
+ BOUNDS.zmin,
861
+ BOUNDS.xmax,
862
+ BOUNDS.ymax,
863
+ BOUNDS.zmax
864
+ );
865
+
866
+ if (seg.tileZoom > terrain.maxZoom) {
867
+ if (pn.segment.tileZoom >= terrain.maxZoom) {
868
+ //TODO: find better place for this
869
+ seg._plainRadius = pn.segment._plainRadius / dZ2;
870
+
871
+ seg.terrainReady = true;
872
+ seg.terrainIsLoading = false;
873
+
874
+ seg.terrainVertices = tempVertices;
875
+ seg.terrainVerticesHigh = tempVerticesHigh;
876
+ seg.terrainVerticesLow = tempVerticesLow;
877
+
878
+ this.appliedTerrainNodeId = this.nodeId;
879
+
880
+ if (pn.segment.terrainExists) {
881
+ seg.terrainExists = true;
882
+ seg.normalMapVertices = tempVertices;
883
+ seg.fileGridSize = Math.sqrt(tempVertices.length / 3) - 1;
884
+
885
+ let fgs = Math.sqrt(pseg.normalMapNormals.length / 3) - 1,
886
+ fgsZ = fgs / dZ2;
887
+
888
+ if (fgs > 1) {
889
+ seg.normalMapNormals = getMatrixSubArray(
890
+ pseg.normalMapNormals,
891
+ fgs,
892
+ fgsZ * offsetY,
893
+ fgsZ * offsetX,
894
+ fgsZ
895
+ );
896
+ } else {
897
+ // TODO: interpolation
898
+ seg.normalMapNormals = pseg.normalMapNormals;
899
+ }
900
+ }
901
+ } else {
902
+ pn = this;
903
+ while (pn.parentNode && pn.segment.tileZoom !== terrain.maxZoom) {
904
+ pn = pn.parentNode;
905
+ }
906
+
907
+ let pns = pn.segment;
908
+
909
+ if (!pns.initialized) {
910
+ pns.initialize();
911
+ }
912
+
913
+ if (!pns.plainProcessing) {
914
+ pn.segment.createPlainSegmentAsync();
915
+ }
916
+
917
+ if (pns.plainReady && !stopLoading) {
918
+ pns.loadTerrain(true);
919
+ }
920
+ }
921
+ }
922
+ }
923
+ }
924
+
925
+ destroy() {
926
+ this.state = NOTRENDERING;
927
+ this.segment.destroySegment();
928
+ var n = this.neighbors;
929
+ n[N] && n[N].neighbors && (n[N].neighbors[S] = []);
930
+ n[E] && n[E].neighbors && (n[E].neighbors[W] = []);
931
+ n[S] && n[S].neighbors && (n[S].neighbors[N] = []);
932
+ n[W] && n[W].neighbors && (n[W].neighbors[E] = []);
933
+ this.neighbors = null;
934
+ this.parentNode = null;
935
+ this.sideSize = null;
936
+ this.sideSizeLog2 = null;
937
+ this.segment = null;
938
+ }
939
+
940
+ clearTree() {
941
+ var state = this.getState();
942
+
943
+ if (state === NOTRENDERING) {
944
+ this.destroyBranches();
945
+ } else if (state === RENDERING) {
946
+ this.destroyBranches();
947
+ } else {
948
+ for (var i = 0; i < this.nodes.length; i++) {
949
+ this.nodes[i] && this.nodes[i].clearTree();
950
+ }
951
+ }
952
+ }
953
+
954
+ clearBranches() {
955
+ for (let i = 0; i < this.nodes.length; i++) {
956
+ this.nodes[i].clearBranches();
957
+ this.nodes[i].segment.deleteMaterials();
958
+ }
959
+ }
960
+
961
+ destroyBranches() {
962
+ if (this.ready) {
963
+ var nodesToRemove = [],
964
+ i;
965
+
966
+ for (i = 0; i < this.nodes.length; i++) {
967
+ nodesToRemove[i] = this.nodes[i];
968
+ }
969
+
970
+ this.ready = false;
971
+ this.nodes.length = 0;
972
+
973
+ for (i = 0; i < nodesToRemove.length; i++) {
974
+ nodesToRemove[i].destroyBranches();
975
+ nodesToRemove[i].destroy();
976
+ nodesToRemove[i] = null;
977
+ }
978
+
979
+ nodesToRemove.length = 0;
980
+ nodesToRemove = null;
981
+ }
982
+ }
983
+
984
+ traverseTree(callback) {
985
+ callback(this);
986
+ if (this.ready) {
987
+ for (var i = 0; i < this.nodes.length; i++) {
988
+ this.nodes[i].traverseTree(callback);
989
+ }
990
+ }
991
+ }
992
+
993
+ getOffsetOppositeNeighbourSide(neighbourNode, side) {
994
+ let pNode = this,
995
+ neighbourZoom = neighbourNode.segment.tileZoom,
996
+ offset = 0;
997
+
998
+ while (pNode.segment.tileZoom > neighbourZoom) {
999
+ offset +=
1000
+ PARTOFFSET[pNode.partId][side] / (1 << (pNode.segment.tileZoom - neighbourZoom));
1001
+ pNode = pNode.parentNode;
1002
+ }
1003
+
1004
+ return offset;
1005
+ }
1006
+ }
1007
+
1008
+ export { Node };