@loaders.gl/tiles 4.0.0-alpha.4 → 4.0.0-alpha.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 (197) hide show
  1. package/dist/bundle.d.ts +2 -0
  2. package/dist/bundle.d.ts.map +1 -0
  3. package/dist/bundle.js +2 -2
  4. package/dist/constants.d.ts +32 -0
  5. package/dist/constants.d.ts.map +1 -0
  6. package/dist/constants.js +30 -26
  7. package/dist/dist.min.js +8921 -0
  8. package/dist/es5/bundle.js +6 -0
  9. package/dist/es5/bundle.js.map +1 -0
  10. package/dist/es5/constants.js +44 -0
  11. package/dist/es5/constants.js.map +1 -0
  12. package/dist/es5/index.js +93 -0
  13. package/dist/es5/index.js.map +1 -0
  14. package/dist/es5/tileset/format-3d-tiles/tileset-3d-traverser.js +70 -0
  15. package/dist/es5/tileset/format-3d-tiles/tileset-3d-traverser.js.map +1 -0
  16. package/dist/es5/tileset/format-i3s/i3s-pending-tiles-register.js +45 -0
  17. package/dist/es5/tileset/format-i3s/i3s-pending-tiles-register.js.map +1 -0
  18. package/dist/es5/tileset/format-i3s/i3s-tile-manager.js +84 -0
  19. package/dist/es5/tileset/format-i3s/i3s-tile-manager.js.map +1 -0
  20. package/dist/es5/tileset/format-i3s/i3s-tileset-traverser.js +143 -0
  21. package/dist/es5/tileset/format-i3s/i3s-tileset-traverser.js.map +1 -0
  22. package/dist/es5/tileset/helpers/3d-tiles-options.js +12 -0
  23. package/dist/es5/tileset/helpers/3d-tiles-options.js.map +1 -0
  24. package/dist/es5/tileset/helpers/bounding-volume.js +176 -0
  25. package/dist/es5/tileset/helpers/bounding-volume.js.map +1 -0
  26. package/dist/es5/tileset/helpers/frame-state.js +129 -0
  27. package/dist/es5/tileset/helpers/frame-state.js.map +1 -0
  28. package/dist/es5/tileset/helpers/i3s-lod.js +60 -0
  29. package/dist/es5/tileset/helpers/i3s-lod.js.map +1 -0
  30. package/dist/es5/tileset/helpers/tiles-3d-lod.js +103 -0
  31. package/dist/es5/tileset/helpers/tiles-3d-lod.js.map +1 -0
  32. package/dist/es5/tileset/helpers/transform-utils.js +50 -0
  33. package/dist/es5/tileset/helpers/transform-utils.js.map +1 -0
  34. package/dist/es5/tileset/helpers/zoom.js +63 -0
  35. package/dist/es5/tileset/helpers/zoom.js.map +1 -0
  36. package/dist/es5/tileset/tile-3d.js +565 -0
  37. package/dist/es5/tileset/tile-3d.js.map +1 -0
  38. package/dist/es5/tileset/tileset-3d.js +890 -0
  39. package/dist/es5/tileset/tileset-3d.js.map +1 -0
  40. package/dist/es5/tileset/tileset-cache.js +85 -0
  41. package/dist/es5/tileset/tileset-cache.js.map +1 -0
  42. package/dist/es5/tileset/tileset-traverser.js +328 -0
  43. package/dist/es5/tileset/tileset-traverser.js.map +1 -0
  44. package/dist/es5/types.js +2 -0
  45. package/dist/es5/types.js.map +1 -0
  46. package/dist/es5/utils/doubly-linked-list-node.js +21 -0
  47. package/dist/es5/utils/doubly-linked-list-node.js.map +1 -0
  48. package/dist/es5/utils/doubly-linked-list.js +88 -0
  49. package/dist/es5/utils/doubly-linked-list.js.map +1 -0
  50. package/dist/es5/utils/managed-array.js +126 -0
  51. package/dist/es5/utils/managed-array.js.map +1 -0
  52. package/dist/esm/bundle.js +4 -0
  53. package/dist/esm/bundle.js.map +1 -0
  54. package/dist/esm/constants.js +32 -0
  55. package/dist/esm/constants.js.map +1 -0
  56. package/dist/esm/index.js +10 -0
  57. package/dist/esm/index.js.map +1 -0
  58. package/dist/{tileset/traversers → esm/tileset/format-3d-tiles}/tileset-3d-traverser.js +2 -13
  59. package/dist/esm/tileset/format-3d-tiles/tileset-3d-traverser.js.map +1 -0
  60. package/dist/esm/tileset/format-i3s/i3s-pending-tiles-register.js +26 -0
  61. package/dist/esm/tileset/format-i3s/i3s-pending-tiles-register.js.map +1 -0
  62. package/dist/esm/tileset/format-i3s/i3s-tile-manager.js +79 -0
  63. package/dist/esm/tileset/format-i3s/i3s-tile-manager.js.map +1 -0
  64. package/dist/{tileset/traversers → esm/tileset/format-i3s}/i3s-tileset-traverser.js +16 -28
  65. package/dist/esm/tileset/format-i3s/i3s-tileset-traverser.js.map +1 -0
  66. package/dist/esm/tileset/helpers/3d-tiles-options.js +6 -0
  67. package/dist/esm/tileset/helpers/3d-tiles-options.js.map +1 -0
  68. package/dist/esm/tileset/helpers/bounding-volume.js +155 -0
  69. package/dist/esm/tileset/helpers/bounding-volume.js.map +1 -0
  70. package/dist/esm/tileset/helpers/frame-state.js +109 -0
  71. package/dist/esm/tileset/helpers/frame-state.js.map +1 -0
  72. package/dist/esm/tileset/helpers/i3s-lod.js +53 -0
  73. package/dist/esm/tileset/helpers/i3s-lod.js.map +1 -0
  74. package/dist/esm/tileset/helpers/tiles-3d-lod.js +100 -0
  75. package/dist/{tileset → esm/tileset}/helpers/tiles-3d-lod.js.map +1 -1
  76. package/dist/esm/tileset/helpers/transform-utils.js +50 -0
  77. package/dist/esm/tileset/helpers/transform-utils.js.map +1 -0
  78. package/dist/esm/tileset/helpers/zoom.js +55 -0
  79. package/dist/esm/tileset/helpers/zoom.js.map +1 -0
  80. package/dist/esm/tileset/tile-3d.js +445 -0
  81. package/dist/esm/tileset/tile-3d.js.map +1 -0
  82. package/dist/esm/tileset/tileset-3d.js +637 -0
  83. package/dist/esm/tileset/tileset-3d.js.map +1 -0
  84. package/dist/esm/tileset/tileset-cache.js +60 -0
  85. package/dist/esm/tileset/tileset-cache.js.map +1 -0
  86. package/dist/{tileset/traversers → esm/tileset}/tileset-traverser.js +20 -72
  87. package/dist/esm/tileset/tileset-traverser.js.map +1 -0
  88. package/dist/esm/types.js +2 -0
  89. package/dist/esm/types.js.map +1 -0
  90. package/dist/esm/utils/doubly-linked-list-node.js +12 -0
  91. package/dist/esm/utils/doubly-linked-list-node.js.map +1 -0
  92. package/dist/esm/utils/doubly-linked-list.js +65 -0
  93. package/dist/esm/utils/doubly-linked-list.js.map +1 -0
  94. package/dist/esm/utils/managed-array.js +87 -0
  95. package/dist/esm/utils/managed-array.js.map +1 -0
  96. package/dist/index.d.ts +11 -0
  97. package/dist/index.d.ts.map +1 -0
  98. package/dist/index.js +26 -9
  99. package/dist/tileset/format-3d-tiles/tileset-3d-traverser.d.ts +7 -0
  100. package/dist/tileset/format-3d-tiles/tileset-3d-traverser.d.ts.map +1 -0
  101. package/dist/tileset/format-3d-tiles/tileset-3d-traverser.js +54 -0
  102. package/dist/tileset/format-i3s/i3s-pending-tiles-register.d.ts +27 -0
  103. package/dist/tileset/format-i3s/i3s-pending-tiles-register.d.ts.map +1 -0
  104. package/dist/tileset/format-i3s/i3s-pending-tiles-register.js +47 -0
  105. package/dist/tileset/format-i3s/i3s-tile-manager.d.ts +34 -0
  106. package/dist/tileset/format-i3s/i3s-tile-manager.d.ts.map +1 -0
  107. package/dist/tileset/format-i3s/i3s-tile-manager.js +80 -0
  108. package/dist/tileset/format-i3s/i3s-tileset-traverser.d.ts +25 -0
  109. package/dist/tileset/format-i3s/i3s-tileset-traverser.d.ts.map +1 -0
  110. package/dist/tileset/format-i3s/i3s-tileset-traverser.js +92 -0
  111. package/dist/tileset/helpers/3d-tiles-options.d.ts +4 -0
  112. package/dist/tileset/helpers/3d-tiles-options.d.ts.map +1 -0
  113. package/dist/tileset/helpers/3d-tiles-options.js +8 -5
  114. package/dist/tileset/helpers/bounding-volume.d.ts +19 -0
  115. package/dist/tileset/helpers/bounding-volume.d.ts.map +1 -0
  116. package/dist/tileset/helpers/bounding-volume.js +274 -69
  117. package/dist/tileset/helpers/frame-state.d.ts +28 -0
  118. package/dist/tileset/helpers/frame-state.d.ts.map +1 -0
  119. package/dist/tileset/helpers/frame-state.js +131 -49
  120. package/dist/tileset/helpers/i3s-lod.d.ts +20 -0
  121. package/dist/tileset/helpers/i3s-lod.d.ts.map +1 -0
  122. package/dist/tileset/helpers/i3s-lod.js +82 -105
  123. package/dist/tileset/helpers/tiles-3d-lod.d.ts +8 -0
  124. package/dist/tileset/helpers/tiles-3d-lod.d.ts.map +1 -0
  125. package/dist/tileset/helpers/tiles-3d-lod.js +112 -100
  126. package/dist/tileset/helpers/transform-utils.d.ts +2 -0
  127. package/dist/tileset/helpers/transform-utils.d.ts.map +1 -0
  128. package/dist/tileset/helpers/transform-utils.js +51 -56
  129. package/dist/tileset/helpers/zoom.d.ts +46 -0
  130. package/dist/tileset/helpers/zoom.d.ts.map +1 -0
  131. package/dist/tileset/helpers/zoom.js +83 -30
  132. package/dist/tileset/tile-3d.d.ts +206 -0
  133. package/dist/tileset/tile-3d.d.ts.map +1 -0
  134. package/dist/tileset/tile-3d.js +593 -531
  135. package/dist/tileset/tileset-3d.d.ts +217 -0
  136. package/dist/tileset/tileset-3d.d.ts.map +1 -0
  137. package/dist/tileset/tileset-3d.js +707 -648
  138. package/dist/tileset/tileset-cache.d.ts +18 -0
  139. package/dist/tileset/tileset-cache.d.ts.map +1 -0
  140. package/dist/tileset/tileset-cache.js +70 -71
  141. package/dist/tileset/tileset-traverser.d.ts +46 -0
  142. package/dist/tileset/tileset-traverser.d.ts.map +1 -0
  143. package/dist/tileset/tileset-traverser.js +309 -0
  144. package/dist/types.d.ts +34 -0
  145. package/dist/types.d.ts.map +1 -0
  146. package/dist/types.js +2 -0
  147. package/dist/utils/doubly-linked-list-node.d.ts +11 -0
  148. package/dist/utils/doubly-linked-list-node.d.ts.map +1 -0
  149. package/dist/utils/doubly-linked-list-node.js +17 -8
  150. package/dist/utils/doubly-linked-list.d.ts +30 -0
  151. package/dist/utils/doubly-linked-list.d.ts.map +1 -0
  152. package/dist/utils/doubly-linked-list.js +91 -72
  153. package/dist/utils/managed-array.d.ts +85 -0
  154. package/dist/utils/managed-array.d.ts.map +1 -0
  155. package/dist/utils/managed-array.js +144 -103
  156. package/package.json +10 -10
  157. package/src/constants.ts +2 -0
  158. package/src/index.ts +7 -4
  159. package/src/tileset/{traversers → format-3d-tiles}/tileset-3d-traverser.ts +4 -2
  160. package/src/tileset/format-i3s/i3s-pending-tiles-register.ts +44 -0
  161. package/src/tileset/format-i3s/i3s-tile-manager.ts +101 -0
  162. package/src/tileset/{traversers → format-i3s}/i3s-tileset-traverser.ts +27 -15
  163. package/src/tileset/helpers/bounding-volume.ts +136 -0
  164. package/src/tileset/helpers/frame-state.ts +102 -18
  165. package/src/tileset/helpers/i3s-lod.ts +75 -96
  166. package/src/tileset/helpers/tiles-3d-lod.ts +2 -0
  167. package/src/tileset/helpers/transform-utils.ts +2 -0
  168. package/src/tileset/helpers/zoom.ts +84 -9
  169. package/src/tileset/tile-3d.ts +77 -20
  170. package/src/tileset/tileset-3d.ts +205 -43
  171. package/src/tileset/tileset-cache.ts +6 -2
  172. package/src/tileset/{traversers/tileset-traverser.ts → tileset-traverser.ts} +29 -17
  173. package/src/types.ts +36 -0
  174. package/src/utils/{doubly-linked-list-node.js → doubly-linked-list-node.ts} +7 -2
  175. package/src/utils/{doubly-linked-list.js → doubly-linked-list.ts} +5 -8
  176. package/src/utils/{managed-array.js → managed-array.ts} +5 -2
  177. package/dist/bundle.js.map +0 -1
  178. package/dist/constants.js.map +0 -1
  179. package/dist/index.js.map +0 -1
  180. package/dist/tileset/helpers/3d-tiles-options.js.map +0 -1
  181. package/dist/tileset/helpers/bounding-volume.js.map +0 -1
  182. package/dist/tileset/helpers/frame-state.js.map +0 -1
  183. package/dist/tileset/helpers/i3s-lod.js.map +0 -1
  184. package/dist/tileset/helpers/transform-utils.js.map +0 -1
  185. package/dist/tileset/helpers/zoom.js.map +0 -1
  186. package/dist/tileset/tile-3d.js.map +0 -1
  187. package/dist/tileset/tileset-3d.js.map +0 -1
  188. package/dist/tileset/tileset-cache.js.map +0 -1
  189. package/dist/tileset/traversers/i3s-tile-manager.js +0 -45
  190. package/dist/tileset/traversers/i3s-tile-manager.js.map +0 -1
  191. package/dist/tileset/traversers/i3s-tileset-traverser.js.map +0 -1
  192. package/dist/tileset/traversers/tileset-3d-traverser.js.map +0 -1
  193. package/dist/tileset/traversers/tileset-traverser.js.map +0 -1
  194. package/dist/utils/doubly-linked-list-node.js.map +0 -1
  195. package/dist/utils/doubly-linked-list.js.map +0 -1
  196. package/dist/utils/managed-array.js.map +0 -1
  197. package/src/tileset/traversers/i3s-tile-manager.ts +0 -39
@@ -1,52 +1,33 @@
1
- import {toRadians} from '@math.gl/core';
2
-
3
- const WGS84_RADIUS_X = 6378137.0;
4
- // use this to bias the lod switching (1+ results in increasing the LOD quality)
5
- const qualityFactor = Math.PI / 2; // empirical derived bias factor
6
- /* eslint-disable max-statements */
7
- export function lodJudge(tile, frameState) {
8
- const viewport = frameState.viewport;
9
- const metersPerPixel = viewport.metersPerPixel;
10
-
11
- const mbsLat = tile.header.mbs[1];
12
- const mbsLon = tile.header.mbs[0];
13
- const mbsZ = tile.header.mbs[2];
14
- const mbsR = tile.header.mbs[3];
15
-
16
- const {height, width, latitude, longitude} = viewport;
17
-
18
- const viewportCenter = [longitude, latitude];
19
- const mbsCenter = [mbsLon, mbsLat, mbsZ];
20
- const mbsLatProjected = [longitude, mbsLat];
21
- const mbsLonProjected = [mbsLon, latitude];
22
-
23
- const diagonalInMeters = Math.sqrt(height * height + width * width) * metersPerPixel[0];
24
- const distanceInMeters = getDistanceFromLatLon(viewportCenter, mbsCenter);
25
-
26
- const visibleHeight = height * 0.5 + mbsR / WGS84_RADIUS_X;
27
- const visibleWidth = width * 0.5 + mbsR / WGS84_RADIUS_X;
28
-
29
- if (distanceInMeters > diagonalInMeters + mbsR / WGS84_RADIUS_X) {
30
- return 'OUT';
31
- }
32
- if (getDistanceFromLatLon(viewportCenter, mbsLatProjected) > visibleHeight) {
33
- return 'OUT';
34
- }
35
- if (getDistanceFromLatLon(viewportCenter, mbsLonProjected) > visibleWidth) {
36
- return 'OUT';
37
- }
38
-
39
- if (tile.lodMetricValue === 0) {
1
+ // loaders.gl, MIT license
2
+
3
+ import {Matrix4, Vector3} from '@math.gl/core';
4
+ import {Ellipsoid} from '@math.gl/geospatial';
5
+ import {Tile3D} from '../tile-3d';
6
+ import {FrameState} from './frame-state';
7
+
8
+ const cameraPositionCartesian = new Vector3();
9
+ const toEye = new Vector3();
10
+ const cameraPositionEnu = new Vector3();
11
+ const extraVertexEnu = new Vector3();
12
+ const projectedOriginVector = new Vector3();
13
+ const enuToCartesianMatrix = new Matrix4();
14
+ const cartesianToEnuMatrix = new Matrix4();
15
+
16
+ /**
17
+ * For the maxScreenThreshold error metric, maxError means that you should replace the node with it's children
18
+ as soon as the nodes bounding sphere has a screen radius larger than maxError pixels.
19
+ In this sense a value of 0 means you should always load it's children,
20
+ or if it's a leaf node, you should always display it.
21
+ * @param tile
22
+ * @param frameState
23
+ * @returns
24
+ */
25
+ export function getLodStatus(tile: Tile3D, frameState: FrameState): 'DIG' | 'OUT' | 'DRAW' {
26
+ if (tile.lodMetricValue === 0 || isNaN(tile.lodMetricValue)) {
40
27
  return 'DIG';
41
28
  }
42
-
43
- // For the maxScreenThreshold error metric, maxError means that you should replace the node with it's children
44
- // as soon as the nodes bounding sphere has a screen radius larger than maxError pixels.
45
- // In this sense a value of 0 means you should always load it's children,
46
- // or if it's a leaf node, you should always display it.
47
- let screenSize = getI3ScreenSize(tile, frameState); // in pixels
48
- screenSize *= qualityFactor;
49
- if (screenSize < 0.5) {
29
+ const screenSize = 2 * getProjectedRadius(tile, frameState);
30
+ if (screenSize < 2) {
50
31
  return 'OUT';
51
32
  }
52
33
  if (!tile.header.children || screenSize <= tile.lodMetricValue) {
@@ -57,58 +38,56 @@ export function lodJudge(tile, frameState) {
57
38
  return 'OUT';
58
39
  }
59
40
 
60
- /* eslint-enable max-statements */
61
-
62
- function projectVertexToSphere([x, y, z]) {
63
- const azim = toRadians(x);
64
- const incl = toRadians(y);
65
- const radius = 1.0 + z / WGS84_RADIUS_X;
66
- const radCosInc = radius * Math.cos(incl);
67
- x = radCosInc * Math.cos(azim);
68
- y = radCosInc * Math.sin(azim);
69
- z = radius * Math.sin(incl);
70
- return [x, y, z];
71
- }
72
-
73
- function getDistanceFromLatLon(observer: number[], center: number[]) {
74
- const [observerLon, observerLat, observerZ = 0.0] = observer;
75
- const [centerLon, centerLat, centerZ = 0.0] = center;
76
-
77
- const projectedCenter = projectVertexToSphere([centerLon, centerLat, centerZ]);
78
- const projectedObserver = projectVertexToSphere([observerLon, observerLat, observerZ]);
79
- const dx = projectedObserver[0] - projectedCenter[0];
80
- const dy = projectedObserver[1] - projectedCenter[1];
81
- const dz = projectedObserver[2] - projectedCenter[2];
82
- return dx * dx + dy * dy + dz * dz;
83
- }
84
-
85
- export function getI3ScreenSize(tile, frameState) {
86
- const viewport = frameState.viewport;
41
+ /**
42
+ * Calculate size of MBS radius projected on the screen plane
43
+ * @param tile
44
+ * @param frameState
45
+ * @returns
46
+ */
47
+ // eslint-disable-next-line max-statements
48
+ export function getProjectedRadius(tile: Tile3D, frameState: FrameState): number {
49
+ const {topDownViewport: viewport} = frameState;
87
50
  const mbsLat = tile.header.mbs[1];
88
51
  const mbsLon = tile.header.mbs[0];
89
52
  const mbsZ = tile.header.mbs[2];
90
53
  const mbsR = tile.header.mbs[3];
91
-
92
- const mbsCenter = [mbsLon, mbsLat, mbsZ];
54
+ const mbsCenterCartesian = [...tile.boundingVolume.center];
93
55
  const cameraPositionCartographic = viewport.unprojectPosition(viewport.cameraPosition);
94
- const dSquared = getDistanceFromLatLon(cameraPositionCartographic, mbsCenter);
95
- const mbsRNormalized = mbsR / WGS84_RADIUS_X;
96
- const d = dSquared - mbsRNormalized * mbsRNormalized;
97
- const fltMax = 3.4028235e38; // convert from 0x7f7fffff which is the maximum
98
- if (d <= 0.0) {
99
- return 0.5 * fltMax;
100
- }
101
- // https://stackoverflow.com/questions/21648630/radius-of-projected-sphere-in-screen-space
102
- // There is a formula there to calculate projected radius:
103
- // return 1.0 / Math.tan(fov) * r / Math.sqrt(d * d - r * r); // Right
104
- // Hack: 300 is a Magic number to get the correct LoD. Possibly, d and r are calculated in a wrong way.
105
- const screenSizeFactor =
106
- ((getTanOfHalfVFAngle(frameState) * mbsRNormalized) / Math.sqrt(d)) * 300;
107
- return screenSizeFactor;
108
- }
109
-
110
- function getTanOfHalfVFAngle(frameState) {
111
- const {projectionMatrix} = frameState.viewport;
112
- const t = projectionMatrix[5];
113
- return t;
56
+ Ellipsoid.WGS84.cartographicToCartesian(cameraPositionCartographic, cameraPositionCartesian);
57
+
58
+ // ---------------------------
59
+ // Calculate mbs border vertex
60
+ // ---------------------------
61
+ toEye.copy(cameraPositionCartesian).subtract(mbsCenterCartesian).normalize();
62
+ // Add extra vector to form plane
63
+ Ellipsoid.WGS84.eastNorthUpToFixedFrame(mbsCenterCartesian, enuToCartesianMatrix);
64
+ cartesianToEnuMatrix.copy(enuToCartesianMatrix).invert();
65
+ cameraPositionEnu.copy(cameraPositionCartesian).transform(cartesianToEnuMatrix);
66
+ // Mean Proportionals in Right Triangles - Altitude rule
67
+ // https://mathbitsnotebook.com/Geometry/RightTriangles/RTmeanRight.html
68
+ const projection = Math.sqrt(
69
+ cameraPositionEnu[0] * cameraPositionEnu[0] + cameraPositionEnu[1] * cameraPositionEnu[1]
70
+ );
71
+ const extraZ = (projection * projection) / cameraPositionEnu[2];
72
+ extraVertexEnu.copy([cameraPositionEnu[0], cameraPositionEnu[1], extraZ]);
73
+ const extraVertexCartesian = extraVertexEnu.transform(enuToCartesianMatrix);
74
+ const extraVectorCartesian = extraVertexCartesian.subtract(mbsCenterCartesian).normalize();
75
+ // We need radius vector orthogonal to toEye vector
76
+ const radiusVector = toEye.cross(extraVectorCartesian).normalize().scale(mbsR);
77
+ const sphereMbsBorderVertexCartesian = radiusVector.add(mbsCenterCartesian);
78
+ const sphereMbsBorderVertexCartographic = Ellipsoid.WGS84.cartesianToCartographic(
79
+ sphereMbsBorderVertexCartesian
80
+ );
81
+ // ---------------------------
82
+
83
+ // Project center vertex and border vertex and calculate projected radius of MBS
84
+ const projectedOrigin = viewport.project([mbsLon, mbsLat, mbsZ]);
85
+ const projectedMbsBorderVertex = viewport.project(
86
+ sphereMbsBorderVertexCartographic as [number, number, number]
87
+ );
88
+ const projectedRadius = projectedOriginVector
89
+ .copy(projectedOrigin)
90
+ .subtract(projectedMbsBorderVertex)
91
+ .magnitude();
92
+ return projectedRadius;
114
93
  }
@@ -1,3 +1,5 @@
1
+ // loaders.gl, MIT license
2
+
1
3
  // This file is derived from the Cesium code base under Apache 2 license
2
4
  // See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md
3
5
 
@@ -1,3 +1,5 @@
1
+ // loaders.gl, MIT license
2
+
1
3
  import {Ellipsoid} from '@math.gl/geospatial';
2
4
  import {Matrix4, Vector3} from '@math.gl/core';
3
5
  import {assert} from '@loaders.gl/loader-utils';
@@ -1,4 +1,9 @@
1
+ // loaders.gl, MIT license
2
+
1
3
  import {Vector3} from '@math.gl/core';
4
+ import {BoundingSphere, OrientedBoundingBox} from '@math.gl/culling';
5
+ import {Ellipsoid} from '@math.gl/geospatial';
6
+ import {BoundingRectangle} from '../../types';
2
7
 
3
8
  const WGS84_RADIUS_X = 6378137.0;
4
9
  const WGS84_RADIUS_Y = 6378137.0;
@@ -8,22 +13,29 @@ const scratchVector = new Vector3();
8
13
 
9
14
  /**
10
15
  * Calculate appropriate zoom value for a particular boundingVolume
11
- * @param {BoundingSphere, OrientedBoundingBox} boundingVolume - the instance of bounding volume
16
+ * @param boundingVolume - the instance of bounding volume
17
+ * @param cartorgraphicCenter - cartographic center of the bounding volume
12
18
  * @returns {number} - zoom value
13
19
  */
14
- export function getZoomFromBoundingVolume(boundingVolume) {
15
- const {halfAxes, radius, width, height} = boundingVolume;
16
-
17
- if (halfAxes) {
20
+ export function getZoomFromBoundingVolume(
21
+ boundingVolume: BoundingSphere | OrientedBoundingBox | BoundingRectangle,
22
+ cartorgraphicCenter: Vector3
23
+ ) {
24
+ if (boundingVolume instanceof OrientedBoundingBox) {
18
25
  // OrientedBoundingBox
26
+ const {halfAxes} = boundingVolume;
19
27
  const obbSize = getObbSize(halfAxes);
20
28
  // Use WGS84_RADIUS_Z to allign with BoundingSphere algorithm
21
- return Math.log2(WGS84_RADIUS_Z / obbSize);
22
- } else if (radius) {
29
+ // Add the tile elevation value for correct zooming to elevated tiles
30
+ return Math.log2(WGS84_RADIUS_Z / (obbSize + cartorgraphicCenter[2]));
31
+ } else if (boundingVolume instanceof BoundingSphere) {
23
32
  // BoundingSphere
24
- return Math.log2(WGS84_RADIUS_Z / radius);
25
- } else if (height && width) {
33
+ const {radius} = boundingVolume;
34
+ // Add the tile elevation value for correct zooming to elevated tiles
35
+ return Math.log2(WGS84_RADIUS_Z / (radius + cartorgraphicCenter[2]));
36
+ } else if (boundingVolume.width && boundingVolume.height) {
26
37
  // BoundingRectangle
38
+ const {width, height} = boundingVolume;
27
39
  const zoomX = Math.log2(WGS84_RADIUS_X / width);
28
40
  const zoomY = Math.log2(WGS84_RADIUS_Y / height);
29
41
 
@@ -33,6 +45,69 @@ export function getZoomFromBoundingVolume(boundingVolume) {
33
45
  return 1;
34
46
  }
35
47
 
48
+ /**
49
+ * Calculate initial zoom for the tileset from 3D `fullExtent` defined in
50
+ * the tileset metadata
51
+ * @param fullExtent - 3D extent of the tileset
52
+ * @param fullExtent.xmin - minimal longitude in decimal degrees
53
+ * @param fullExtent.xmax - maximal longitude in decimal degrees
54
+ * @param fullExtent.ymin - minimal latitude in decimal degrees
55
+ * @param fullExtent.ymax - maximal latitude in decimal degrees
56
+ * @param fullExtent.zmin - minimal elevation in meters
57
+ * @param fullExtent.zmax - maximal elevation in meters
58
+ * @param cartorgraphicCenter - tileset center in cartographic coordinate system
59
+ * @param cartesianCenter - tileset center in cartesian coordinate system
60
+ * @returns - initial zoom for the tileset
61
+ */
62
+ export function getZoomFromFullExtent(
63
+ fullExtent: {
64
+ xmin: number;
65
+ xmax: number;
66
+ ymin: number;
67
+ ymax: number;
68
+ zmin: number;
69
+ zmax: number;
70
+ },
71
+ cartorgraphicCenter: Vector3,
72
+ cartesianCenter: Vector3
73
+ ) {
74
+ const extentVertex = Ellipsoid.WGS84.cartographicToCartesian(
75
+ [fullExtent.xmax, fullExtent.ymax, fullExtent.zmax],
76
+ new Vector3()
77
+ );
78
+ const extentSize = Math.sqrt(
79
+ Math.pow(extentVertex[0] - cartesianCenter[0], 2) +
80
+ Math.pow(extentVertex[1] - cartesianCenter[1], 2) +
81
+ Math.pow(extentVertex[2] - cartesianCenter[2], 2)
82
+ );
83
+ return Math.log2(WGS84_RADIUS_Z / (extentSize + cartorgraphicCenter[2]));
84
+ }
85
+
86
+ /**
87
+ * Calculate initial zoom for the tileset from 2D `extent` defined in
88
+ * the tileset metadata
89
+ * @param extent - 2D extent of the tileset. It is array of 4 elements [xmin, ymin, xmax, ymax]
90
+ * @param extent[0] - minimal longitude in decimal degrees
91
+ * @param extent[1] - minimal latitude in decimal degrees
92
+ * @param extent[2] - maximal longitude in decimal degrees
93
+ * @param extent[3] - maximal latitude in decimal degrees
94
+ * @param cartorgraphicCenter - tileset center in cartographic coordinate system
95
+ * @param cartesianCenter - tileset center in cartesian coordinate system
96
+ * @returns - initial zoom for the tileset
97
+ */
98
+ export function getZoomFromExtent(
99
+ extent: [number, number, number, number],
100
+ cartorgraphicCenter: Vector3,
101
+ cartesianCenter: Vector3
102
+ ) {
103
+ const [xmin, ymin, xmax, ymax] = extent;
104
+ return getZoomFromFullExtent(
105
+ {xmin, xmax, ymin, ymax, zmin: 0, zmax: 0},
106
+ cartorgraphicCenter,
107
+ cartesianCenter
108
+ );
109
+ }
110
+
36
111
  function getObbSize(halfAxes) {
37
112
  halfAxes.getColumn(0, scratchVector);
38
113
  const axeY = halfAxes.getColumn(1);
@@ -1,20 +1,27 @@
1
+ // loaders.gl, MIT license
2
+
1
3
  // This file is derived from the Cesium code base under Apache 2 license
2
4
  // See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md
5
+
3
6
  import {Vector3, Matrix4} from '@math.gl/core';
4
7
  import {CullingVolume} from '@math.gl/culling';
5
8
 
6
9
  import {load} from '@loaders.gl/core';
10
+
11
+ // Note: circular dependency
12
+ import type {Tileset3D} from './tileset-3d';
7
13
  import {TILE_REFINEMENT, TILE_CONTENT_STATE, TILESET_TYPE} from '../constants';
8
14
 
9
15
  import {FrameState} from './helpers/frame-state';
10
- import {createBoundingVolume} from './helpers/bounding-volume';
16
+ import {
17
+ createBoundingVolume,
18
+ getCartographicBounds,
19
+ CartographicBounds
20
+ } from './helpers/bounding-volume';
11
21
  import {getTiles3DScreenSpaceError} from './helpers/tiles-3d-lod';
12
- import {getI3ScreenSize} from './helpers/i3s-lod';
22
+ import {getProjectedRadius} from './helpers/i3s-lod';
13
23
  import {get3dTilesOptions} from './helpers/3d-tiles-options';
14
- import TilesetTraverser from './traversers/tileset-traverser';
15
-
16
- // Note: circular dependency
17
- import type Tileset3D from './tileset-3d';
24
+ import {TilesetTraverser} from './tileset-traverser';
18
25
 
19
26
  const scratchVector = new Vector3();
20
27
 
@@ -25,14 +32,14 @@ function defined(x) {
25
32
  /**
26
33
  * @param tileset - Tileset3D instance
27
34
  * @param header - tile header - JSON loaded from a dataset
28
- * @param parentHeader - parent TileHeader instance
35
+ * @param parentHeader - parent Tile3D instance
29
36
  * @param extendedId - optional ID to separate copies of a tile for different viewports.
30
37
  * const extendedId = `${tile.id}-${frameState.viewport.id}`;
31
38
  */
32
- export type TileHeaderProps = {
39
+ export type Tile3DProps = {
33
40
  tileset: Tileset3D;
34
41
  header: Object;
35
- parentHeader: TileHeader;
42
+ parentHeader: Tile3D;
36
43
  extendedId: string;
37
44
  };
38
45
 
@@ -41,12 +48,12 @@ export type TileHeaderProps = {
41
48
  * the content is loaded on-demand when needed based on the view.
42
49
  * Do not construct this directly, instead access tiles through {@link Tileset3D#tileVisible}.
43
50
  */
44
- export default class TileHeader {
51
+ export class Tile3D {
45
52
  tileset: Tileset3D;
46
53
  header: any;
47
54
  id: string;
48
55
  url: string;
49
- parent: TileHeader;
56
+ parent: Tile3D;
50
57
  refine: number;
51
58
  type: string;
52
59
  contentUrl: string;
@@ -56,10 +63,12 @@ export default class TileHeader {
56
63
  content: any;
57
64
  contentState: any;
58
65
  gpuMemoryUsageInBytes: number;
59
- children: TileHeader[];
66
+ children: Tile3D[];
60
67
  depth: number;
61
68
  viewportIds: any[];
62
69
  transform: Matrix4;
70
+ extensions: any;
71
+ implicitTiling?: any;
63
72
 
64
73
  // Container to store application specific data
65
74
  userData: {[key: string]: any};
@@ -81,9 +90,10 @@ export default class TileHeader {
81
90
  // @ts-ignore
82
91
  private _shouldRefine: boolean;
83
92
 
93
+ private _boundingBox?: CartographicBounds;
94
+
84
95
  // Members this are updated every frame for tree traversal and rendering optimizations:
85
- // @ts-ignore
86
- private _distanceToCamera: number;
96
+ public _distanceToCamera: number;
87
97
  // @ts-ignore
88
98
  private _centerZDepth: number;
89
99
  private _screenSpaceError: number;
@@ -114,10 +124,10 @@ export default class TileHeader {
114
124
 
115
125
  /**
116
126
  * @constructs
117
- * Create a TileHeader instance
127
+ * Create a Tile3D instance
118
128
  * @param tileset - Tileset3D instance
119
129
  * @param header - tile header - JSON loaded from a dataset
120
- * @param parentHeader - parent TileHeader instance
130
+ * @param parentHeader - parent Tile3D instance
121
131
  * @param extendedId - optional ID to separate copies of a tile for different viewports.
122
132
  * const extendedId = `${tile.id}-${frameState.viewport.id}`;
123
133
  */
@@ -125,7 +135,7 @@ export default class TileHeader {
125
135
  constructor(
126
136
  tileset: Tileset3D,
127
137
  header: {[key: string]: any},
128
- parentHeader?: TileHeader,
138
+ parentHeader?: Tile3D,
129
139
  extendedId = ''
130
140
  ) {
131
141
  // PUBLIC MEMBERS
@@ -168,6 +178,7 @@ export default class TileHeader {
168
178
 
169
179
  // Container to store application specific data
170
180
  this.userData = {};
181
+ this.extensions = null;
171
182
 
172
183
  // PRIVATE MEMBERS
173
184
  this._priority = 0;
@@ -204,6 +215,7 @@ export default class TileHeader {
204
215
  // TODO Cesium 3d tiles specific
205
216
  this._expireDate = null;
206
217
  this._expiredContent = null;
218
+ this.implicitTiling = null;
207
219
 
208
220
  Object.seal(this);
209
221
  }
@@ -283,11 +295,36 @@ export default class TileHeader {
283
295
  return this.contentState === TILE_CONTENT_STATE.FAILED;
284
296
  }
285
297
 
298
+ /**
299
+ * Distance from the tile's bounding volume center to the camera
300
+ */
301
+ get distanceToCamera(): number {
302
+ return this._distanceToCamera;
303
+ }
304
+
305
+ /**
306
+ * Screen space error for LOD selection
307
+ */
308
+ get screenSpaceError(): number {
309
+ return this._screenSpaceError;
310
+ }
311
+
312
+ /**
313
+ * Get bounding box in cartographic coordinates
314
+ * @returns [min, max] each in [longitude, latitude, altitude]
315
+ */
316
+ get boundingBox(): CartographicBounds {
317
+ if (!this._boundingBox) {
318
+ this._boundingBox = getCartographicBounds(this.header.boundingVolume, this.boundingVolume);
319
+ }
320
+ return this._boundingBox;
321
+ }
322
+
286
323
  /** Get the tile's screen space error. */
287
324
  getScreenSpaceError(frameState, useParentLodMetric) {
288
325
  switch (this.tileset.type) {
289
326
  case TILESET_TYPE.I3S:
290
- return getI3ScreenSize(this, frameState);
327
+ return getProjectedRadius(this, frameState);
291
328
  case TILESET_TYPE.TILES3D:
292
329
  return getTiles3DScreenSpaceError(this, frameState, useParentLodMetric);
293
330
  default:
@@ -296,6 +333,14 @@ export default class TileHeader {
296
333
  }
297
334
  }
298
335
 
336
+ /**
337
+ * Make tile unselected than means it won't be shown
338
+ * but it can be still loaded in memory
339
+ */
340
+ unselect(): void {
341
+ this._selectedFrame = 0;
342
+ }
343
+
299
344
  /*
300
345
  * If skipLevelOfDetail is off try to load child tiles as soon as possible so that their parent can refine sooner.
301
346
  * Tiles are prioritized by screen space error.
@@ -747,8 +792,20 @@ export default class TileHeader {
747
792
  case 'i3s':
748
793
  return {
749
794
  ...this.tileset.options.i3s,
750
- tile: this.header,
751
- tileset: this.tileset.tileset,
795
+ _tileOptions: {
796
+ attributeUrls: this.header.attributeUrls,
797
+ textureUrl: this.header.textureUrl,
798
+ textureFormat: this.header.textureFormat,
799
+ textureLoaderOptions: this.header.textureLoaderOptions,
800
+ materialDefinition: this.header.materialDefinition,
801
+ isDracoGeometry: this.header.isDracoGeometry,
802
+ mbs: this.header.mbs
803
+ },
804
+ _tilesetOptions: {
805
+ store: this.tileset.tileset.store,
806
+ attributeStorageInfo: this.tileset.tileset.attributeStorageInfo,
807
+ fields: this.tileset.tileset.fields
808
+ },
752
809
  isTileHeader: false
753
810
  };
754
811
  case '3d-tiles':