@cesium/engine 8.0.0 → 9.1.0

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 (192) hide show
  1. package/Build/ThirdParty/Workers/z-worker-pako.js +7 -10
  2. package/Build/Workers/{chunk-F4HFJMGM.js → chunk-2CSEEWHN.js} +6 -6
  3. package/Build/Workers/{chunk-7TC63SJW.js → chunk-34DGOKCO.js} +10 -12
  4. package/Build/Workers/{chunk-7ZFGPDJA.js → chunk-3RZK5NNV.js} +4 -4
  5. package/Build/Workers/{chunk-M7ERACJJ.js → chunk-3S2MFY4B.js} +13 -13
  6. package/Build/Workers/{chunk-BROJAZRZ.js → chunk-4AJGCQFX.js} +13 -13
  7. package/Build/Workers/{chunk-2FWRMUTY.js → chunk-4KIUON73.js} +4 -4
  8. package/Build/Workers/{chunk-5QULIR53.js → chunk-4PHPQRSH.js} +4 -4
  9. package/Build/Workers/{chunk-X4356LRH.js → chunk-66E3H2KU.js} +12 -12
  10. package/Build/Workers/{chunk-G43QFN4Q.js → chunk-6HCAQOVK.js} +6 -6
  11. package/Build/Workers/{chunk-23UFSGND.js → chunk-7LPEGKOF.js} +7 -7
  12. package/Build/Workers/{chunk-DDUQAJ4P.js → chunk-7VZNXIKG.js} +7 -7
  13. package/Build/Workers/{chunk-JURN7NPV.js → chunk-A6NCZSL3.js} +19 -19
  14. package/Build/Workers/{chunk-ZT7KWISZ.js → chunk-AOFMPKUB.js} +4 -4
  15. package/Build/Workers/{chunk-BIKA3NRA.js → chunk-AOIKO5Y7.js} +5 -5
  16. package/Build/Workers/{chunk-YWTJ2B4B.js → chunk-BDUJXBVF.js} +1 -1
  17. package/Build/Workers/{chunk-OGXZVPPM.js → chunk-C5CE4OG6.js} +469 -6
  18. package/Build/Workers/{chunk-FNIRWHJB.js → chunk-CE6GTZ4I.js} +11 -13
  19. package/Build/Workers/{chunk-SH5USDPI.js → chunk-CYAJYEKW.js} +6 -6
  20. package/Build/Workers/{chunk-Y5UQJLYE.js → chunk-FOZQIHZK.js} +6 -6
  21. package/Build/Workers/{chunk-2FRVPMCS.js → chunk-G7CJQKKD.js} +7 -7
  22. package/Build/Workers/{chunk-EERJKOAF.js → chunk-GIFJ77E4.js} +4 -4
  23. package/Build/Workers/{chunk-FJKNFAKQ.js → chunk-I5TDPPC4.js} +7197 -5096
  24. package/Build/Workers/{chunk-3VAZEH7M.js → chunk-IBXGK4WV.js} +2 -2
  25. package/Build/Workers/{chunk-VOXYEYJT.js → chunk-JI2445T5.js} +11 -11
  26. package/Build/Workers/{chunk-PGSJK77E.js → chunk-KPY4F4BW.js} +6 -6
  27. package/Build/Workers/{chunk-I46ZRR5W.js → chunk-LVJCR7DH.js} +17 -17
  28. package/Build/Workers/{chunk-T3XIFPYR.js → chunk-LW7WGHEU.js} +16 -16
  29. package/Build/Workers/{chunk-HU6N6EXB.js → chunk-MWYZ64MH.js} +12 -11
  30. package/Build/Workers/chunk-NI2R52QD.js +961 -0
  31. package/Build/Workers/{chunk-SOWMRMWA.js → chunk-PEABJLCK.js} +1 -1
  32. package/Build/Workers/{chunk-EG6PTBY2.js → chunk-PK7TEP3J.js} +15 -15
  33. package/Build/Workers/{chunk-GRC2ZTAF.js → chunk-POLFRINT.js} +14 -14
  34. package/Build/Workers/{chunk-Z3TIFFGF.js → chunk-PS6AEMBR.js} +7 -7
  35. package/Build/Workers/{chunk-Y2ME2IJV.js → chunk-PWF3YJJ5.js} +13 -13
  36. package/Build/Workers/{chunk-2A75IWRS.js → chunk-QKF7XXEQ.js} +7 -7
  37. package/Build/Workers/{chunk-4H7PY4U5.js → chunk-RL73GOEF.js} +2 -2
  38. package/Build/Workers/{chunk-MDWEGWPA.js → chunk-RR7EOKGZ.js} +10 -10
  39. package/Build/Workers/{chunk-F3YA3Y2Z.js → chunk-S4XDCPKD.js} +1 -1
  40. package/Build/Workers/{chunk-PPH7OFP3.js → chunk-TMMOULW3.js} +5 -5
  41. package/Build/Workers/{chunk-XGI5BXZY.js → chunk-U4IMCOF5.js} +2 -2
  42. package/Build/Workers/{chunk-4DO5W5XZ.js → chunk-UAJEGIWA.js} +6 -6
  43. package/Build/Workers/{chunk-BBWDMCVU.js → chunk-UCPPWV64.js} +1 -1
  44. package/Build/Workers/{chunk-FZRIVR7Y.js → chunk-V7JB576Q.js} +5 -5
  45. package/Build/Workers/{chunk-2UPKWTMJ.js → chunk-WEGCQ5DY.js} +6 -6
  46. package/Build/Workers/{chunk-STW2DGFI.js → chunk-WFICTTOE.js} +2 -2
  47. package/Build/Workers/{chunk-LPR3YNP2.js → chunk-WWP3I7R5.js} +5 -5
  48. package/Build/Workers/{chunk-A5DWLWCY.js → chunk-XHLDDE65.js} +10 -10
  49. package/Build/Workers/{chunk-UEXTBDBE.js → chunk-XWML5Y7N.js} +11 -13
  50. package/Build/Workers/{chunk-EHWHNOEX.js → chunk-YLZTCEBJ.js} +1 -1
  51. package/Build/Workers/{chunk-34FXV7D7.js → chunk-ZC4AGBZK.js} +2 -2
  52. package/Build/Workers/{chunk-GATZHF3K.js → chunk-ZDP32RQI.js} +2 -2
  53. package/Build/Workers/{chunk-KKCR2YOP.js → chunk-ZWPIM77Q.js} +11 -11
  54. package/Build/Workers/combineGeometry.js +22 -24
  55. package/Build/Workers/createBoxGeometry.js +16 -18
  56. package/Build/Workers/createBoxOutlineGeometry.js +14 -16
  57. package/Build/Workers/createCircleGeometry.js +24 -26
  58. package/Build/Workers/createCircleOutlineGeometry.js +17 -19
  59. package/Build/Workers/createCoplanarPolygonGeometry.js +33 -34
  60. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +29 -31
  61. package/Build/Workers/createCorridorGeometry.js +27 -29
  62. package/Build/Workers/createCorridorOutlineGeometry.js +26 -28
  63. package/Build/Workers/createCylinderGeometry.js +18 -20
  64. package/Build/Workers/createCylinderOutlineGeometry.js +16 -18
  65. package/Build/Workers/createEllipseGeometry.js +24 -26
  66. package/Build/Workers/createEllipseOutlineGeometry.js +17 -19
  67. package/Build/Workers/createEllipsoidGeometry.js +17 -19
  68. package/Build/Workers/createEllipsoidOutlineGeometry.js +16 -18
  69. package/Build/Workers/createFrustumGeometry.js +16 -18
  70. package/Build/Workers/createFrustumOutlineGeometry.js +18 -19
  71. package/Build/Workers/createGeometry.js +23 -25
  72. package/Build/Workers/createGroundPolylineGeometry.js +23 -25
  73. package/Build/Workers/createPlaneGeometry.js +14 -16
  74. package/Build/Workers/createPlaneOutlineGeometry.js +13 -15
  75. package/Build/Workers/createPolygonGeometry.js +33 -35
  76. package/Build/Workers/createPolygonOutlineGeometry.js +28 -30
  77. package/Build/Workers/createPolylineGeometry.js +23 -25
  78. package/Build/Workers/createPolylineVolumeGeometry.js +29 -31
  79. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +25 -27
  80. package/Build/Workers/createRectangleGeometry.js +27 -29
  81. package/Build/Workers/createRectangleOutlineGeometry.js +18 -20
  82. package/Build/Workers/createSimplePolylineGeometry.js +21 -23
  83. package/Build/Workers/createSphereGeometry.js +17 -19
  84. package/Build/Workers/createSphereOutlineGeometry.js +16 -18
  85. package/Build/Workers/createTaskProcessorWorker.js +3 -3
  86. package/Build/Workers/createVectorTileClampedPolylines.js +14 -16
  87. package/Build/Workers/createVectorTileGeometries.js +22 -24
  88. package/Build/Workers/createVectorTilePoints.js +12 -12
  89. package/Build/Workers/createVectorTilePolygons.js +20 -22
  90. package/Build/Workers/createVectorTilePolylines.js +14 -16
  91. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +23 -25
  92. package/Build/Workers/createVerticesFromHeightmap.js +23 -25
  93. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +19 -22
  94. package/Build/Workers/createWallGeometry.js +22 -24
  95. package/Build/Workers/createWallOutlineGeometry.js +21 -23
  96. package/Build/Workers/decodeDraco.js +11 -11
  97. package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
  98. package/Build/Workers/decodeI3S.js +10 -11
  99. package/Build/Workers/transcodeKTX2.js +8 -8
  100. package/Build/Workers/transferTypedArrayTest.js +1 -1
  101. package/Build/Workers/upsampleQuantizedTerrainMesh.js +20 -22
  102. package/Source/Core/Check.d.ts +127 -0
  103. package/Source/Core/Check.js +0 -1
  104. package/Source/Core/Geometry.js +1 -1
  105. package/Source/Core/Ion.js +1 -1
  106. package/Source/Core/PixelFormat.js +1 -0
  107. package/Source/Core/PolygonGeometry.js +1 -1
  108. package/Source/Core/Rectangle.js +89 -0
  109. package/Source/Core/VerticalExaggeration.js +2 -1
  110. package/Source/DataSources/DataSourceDisplay.js +5 -0
  111. package/Source/Renderer/ShaderBuilder.js +6 -3
  112. package/Source/Scene/ArcGisMapService.js +1 -1
  113. package/Source/Scene/Billboard.js +37 -3
  114. package/Source/Scene/BillboardCollection.js +1 -1
  115. package/Source/Scene/BingMapsImageryProvider.js +4 -0
  116. package/Source/Scene/Cesium3DTile.js +65 -0
  117. package/Source/Scene/Cesium3DTilesVoxelProvider.js +2 -9
  118. package/Source/Scene/Cesium3DTileset.js +52 -40
  119. package/Source/Scene/ClippingPolygon.js +212 -0
  120. package/Source/Scene/ClippingPolygonCollection.js +968 -0
  121. package/Source/Scene/Globe.js +14 -67
  122. package/Source/Scene/GlobeSurfaceShaderSet.js +81 -15
  123. package/Source/Scene/GlobeSurfaceTileProvider.js +81 -1
  124. package/Source/Scene/Label.js +33 -0
  125. package/Source/Scene/LabelCollection.js +2 -1
  126. package/Source/Scene/Model/Model.js +83 -0
  127. package/Source/Scene/Model/Model3DTileContent.js +21 -0
  128. package/Source/Scene/Model/ModelClippingPolygonsPipelineStage.js +92 -0
  129. package/Source/Scene/Model/ModelSceneGraph.js +5 -0
  130. package/Source/Scene/Primitive.js +0 -3
  131. package/Source/Scene/SensorVolumePortionToDisplay.js +1 -1
  132. package/Source/Scene/Terrain.js +2 -2
  133. package/Source/Scene/VoxelBoxShape.js +0 -15
  134. package/Source/Scene/VoxelCylinderShape.js +14 -131
  135. package/Source/Scene/VoxelEllipsoidShape.js +136 -227
  136. package/Source/Scene/VoxelPrimitive.js +106 -14
  137. package/Source/Scene/VoxelRenderResources.js +9 -3
  138. package/Source/Scene/VoxelShape.js +0 -10
  139. package/Source/Scene/processVoxelProperties.js +1 -0
  140. package/Source/Shaders/Builtin/CzmBuiltins.js +4 -0
  141. package/Source/Shaders/Builtin/Functions/clipPolygons.glsl +37 -0
  142. package/Source/Shaders/Builtin/Functions/clipPolygons.js +39 -0
  143. package/Source/Shaders/Builtin/Functions/unpackClippingExtents.glsl +14 -0
  144. package/Source/Shaders/Builtin/Functions/unpackClippingExtents.js +15 -0
  145. package/Source/Shaders/GlobeFS.glsl +12 -0
  146. package/Source/Shaders/GlobeFS.js +12 -0
  147. package/Source/Shaders/GlobeVS.glsl +32 -0
  148. package/Source/Shaders/GlobeVS.js +32 -0
  149. package/Source/Shaders/Model/GeometryStageVS.glsl +1 -1
  150. package/Source/Shaders/Model/GeometryStageVS.js +1 -1
  151. package/Source/Shaders/Model/ModelClippingPolygonsStageFS.glsl +6 -0
  152. package/Source/Shaders/Model/ModelClippingPolygonsStageFS.js +8 -0
  153. package/Source/Shaders/Model/ModelClippingPolygonsStageVS.glsl +27 -0
  154. package/Source/Shaders/Model/ModelClippingPolygonsStageVS.js +29 -0
  155. package/Source/Shaders/Model/ModelFS.glsl +6 -0
  156. package/Source/Shaders/Model/ModelFS.js +7 -1
  157. package/Source/Shaders/Model/ModelVS.glsl +4 -0
  158. package/Source/Shaders/Model/ModelVS.js +4 -0
  159. package/Source/Shaders/PolygonSignedDistanceFS.glsl +100 -0
  160. package/Source/Shaders/PolygonSignedDistanceFS.js +101 -0
  161. package/Source/Shaders/Voxels/IntersectBox.glsl +21 -47
  162. package/Source/Shaders/Voxels/IntersectBox.js +21 -47
  163. package/Source/Shaders/Voxels/IntersectClippingPlanes.glsl +1 -1
  164. package/Source/Shaders/Voxels/IntersectClippingPlanes.js +1 -1
  165. package/Source/Shaders/Voxels/IntersectCylinder.glsl +66 -96
  166. package/Source/Shaders/Voxels/IntersectCylinder.js +66 -96
  167. package/Source/Shaders/Voxels/IntersectEllipsoid.glsl +226 -154
  168. package/Source/Shaders/Voxels/IntersectEllipsoid.js +226 -154
  169. package/Source/Shaders/Voxels/IntersectionUtils.glsl +33 -11
  170. package/Source/Shaders/Voxels/IntersectionUtils.js +33 -11
  171. package/Source/Shaders/Voxels/Megatexture.glsl +1 -2
  172. package/Source/Shaders/Voxels/Megatexture.js +1 -2
  173. package/Source/Shaders/Voxels/Octree.glsl +14 -9
  174. package/Source/Shaders/Voxels/Octree.js +14 -9
  175. package/Source/Shaders/Voxels/VoxelFS.glsl +93 -43
  176. package/Source/Shaders/Voxels/VoxelFS.js +93 -43
  177. package/Source/Shaders/Voxels/VoxelUtils.glsl +31 -0
  178. package/Source/Shaders/Voxels/VoxelUtils.js +33 -0
  179. package/Source/Shaders/Voxels/convertUvToBox.glsl +24 -3
  180. package/Source/Shaders/Voxels/convertUvToBox.js +24 -4
  181. package/Source/Shaders/Voxels/convertUvToCylinder.glsl +50 -8
  182. package/Source/Shaders/Voxels/convertUvToCylinder.js +50 -8
  183. package/Source/Shaders/Voxels/convertUvToEllipsoid.glsl +82 -53
  184. package/Source/Shaders/Voxels/convertUvToEllipsoid.js +82 -53
  185. package/Source/ThirdParty/Workers/z-worker-pako.js +1 -1
  186. package/Source/Workers/createGeometry.js +1 -1
  187. package/index.d.ts +478 -35
  188. package/index.js +61 -52
  189. package/package.json +2 -2
  190. package/Build/Workers/chunk-BG4UCVXN.js +0 -73
  191. package/Build/Workers/chunk-TTUZP4BO.js +0 -501
  192. package/Build/Workers/chunk-YJEBABKH.js +0 -2977
@@ -7,14 +7,27 @@
7
7
  uniform vec3 u_boxUvToShapeUvTranslate;
8
8
  #endif
9
9
 
10
- vec3 convertUvToShapeUvSpace(in vec3 positionUv) {
10
+ PointJacobianT convertUvToShapeSpaceDerivative(in vec3 positionUv) {
11
+ // For BOX, UV space = shape space, so we can use positionUv as-is,
12
+ // and the Jacobian is the identity matrix, except that a step of 1
13
+ // only spans half the shape space [-1, 1], so the identity is scaled.
14
+ return PointJacobianT(positionUv, mat3(0.5));
15
+ }
16
+
17
+ vec3 convertShapeToShapeUvSpace(in vec3 positionShape) {
11
18
  #if defined(BOX_HAS_SHAPE_BOUNDS)
12
- return positionUv * u_boxUvToShapeUvScale + u_boxUvToShapeUvTranslate;
19
+ return positionShape * u_boxUvToShapeUvScale + u_boxUvToShapeUvTranslate;
13
20
  #else
14
- return positionUv;
21
+ return positionShape;
15
22
  #endif
16
23
  }
17
24
 
25
+ PointJacobianT convertUvToShapeUvSpaceDerivative(in vec3 positionUv) {
26
+ PointJacobianT pointJacobian = convertUvToShapeSpaceDerivative(positionUv);
27
+ pointJacobian.point = convertShapeToShapeUvSpace(pointJacobian.point);
28
+ return pointJacobian;
29
+ }
30
+
18
31
  vec3 convertShapeUvToUvSpace(in vec3 shapeUv) {
19
32
  #if defined(BOX_HAS_SHAPE_BOUNDS)
20
33
  return (shapeUv - u_boxUvToShapeUvTranslate) / u_boxUvToShapeUvScale;
@@ -22,3 +35,11 @@ vec3 convertShapeUvToUvSpace(in vec3 shapeUv) {
22
35
  return shapeUv;
23
36
  #endif
24
37
  }
38
+
39
+ vec3 scaleShapeUvToShapeSpace(in vec3 shapeUv) {
40
+ #if defined(BOX_HAS_SHAPE_BOUNDS)
41
+ return shapeUv / u_boxUvToShapeUvScale;
42
+ #else
43
+ return shapeUv;
44
+ #endif
45
+ }
@@ -8,14 +8,27 @@ export default "/* Box defines (set in Scene/VoxelBoxShape.js)\n\
8
8
  uniform vec3 u_boxUvToShapeUvTranslate;\n\
9
9
  #endif\n\
10
10
  \n\
11
- vec3 convertUvToShapeUvSpace(in vec3 positionUv) {\n\
11
+ PointJacobianT convertUvToShapeSpaceDerivative(in vec3 positionUv) {\n\
12
+ // For BOX, UV space = shape space, so we can use positionUv as-is,\n\
13
+ // and the Jacobian is the identity matrix, except that a step of 1\n\
14
+ // only spans half the shape space [-1, 1], so the identity is scaled.\n\
15
+ return PointJacobianT(positionUv, mat3(0.5));\n\
16
+ }\n\
17
+ \n\
18
+ vec3 convertShapeToShapeUvSpace(in vec3 positionShape) {\n\
12
19
  #if defined(BOX_HAS_SHAPE_BOUNDS)\n\
13
- return positionUv * u_boxUvToShapeUvScale + u_boxUvToShapeUvTranslate;\n\
20
+ return positionShape * u_boxUvToShapeUvScale + u_boxUvToShapeUvTranslate;\n\
14
21
  #else\n\
15
- return positionUv;\n\
22
+ return positionShape;\n\
16
23
  #endif\n\
17
24
  }\n\
18
25
  \n\
26
+ PointJacobianT convertUvToShapeUvSpaceDerivative(in vec3 positionUv) {\n\
27
+ PointJacobianT pointJacobian = convertUvToShapeSpaceDerivative(positionUv);\n\
28
+ pointJacobian.point = convertShapeToShapeUvSpace(pointJacobian.point);\n\
29
+ return pointJacobian;\n\
30
+ }\n\
31
+ \n\
19
32
  vec3 convertShapeUvToUvSpace(in vec3 shapeUv) {\n\
20
33
  #if defined(BOX_HAS_SHAPE_BOUNDS)\n\
21
34
  return (shapeUv - u_boxUvToShapeUvTranslate) / u_boxUvToShapeUvScale;\n\
@@ -23,4 +36,11 @@ vec3 convertShapeUvToUvSpace(in vec3 shapeUv) {\n\
23
36
  return shapeUv;\n\
24
37
  #endif\n\
25
38
  }\n\
26
- ";
39
+ \n\
40
+ vec3 scaleShapeUvToShapeSpace(in vec3 shapeUv) {\n\
41
+ #if defined(BOX_HAS_SHAPE_BOUNDS)\n\
42
+ return shapeUv / u_boxUvToShapeUvScale;\n\
43
+ #else\n\
44
+ return shapeUv;\n\
45
+ #endif\n\
46
+ }";
@@ -23,20 +23,37 @@
23
23
  uniform float u_cylinderShapeUvAngleRangeZeroMid;
24
24
  #endif
25
25
 
26
- vec3 convertUvToShapeUvSpace(in vec3 positionUv) {
27
- vec3 positionLocal = positionUv * 2.0 - 1.0; // [-1,+1]
26
+ PointJacobianT convertUvToShapeSpaceDerivative(in vec3 positionUv) {
27
+ // Convert from Cartesian UV space [0, 1] to Cartesian local space [-1, 1]
28
+ vec3 position = positionUv * 2.0 - 1.0;
28
29
 
29
- float radius = length(positionLocal.xy); // [0,1]
30
+ float radius = length(position.xy); // [0, 1]
31
+ vec3 radial = normalize(vec3(position.xy, 0.0));
32
+
33
+ // Shape space height is defined within [0, 1]
34
+ float height = positionUv.z; // [0, 1]
35
+ vec3 z = vec3(0.0, 0.0, 1.0);
36
+
37
+ float angle = atan(position.y, position.x);
38
+ vec3 east = normalize(vec3(-position.y, position.x, 0.0));
39
+
40
+ vec3 point = vec3(radius, height, angle);
41
+ mat3 jacobianT = mat3(radial, z, east / length(position.xy));
42
+ return PointJacobianT(point, jacobianT);
43
+ }
44
+
45
+ vec3 convertShapeToShapeUvSpace(in vec3 positionShape) {
46
+ float radius = positionShape.x;
30
47
  #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS)
31
- radius = radius * u_cylinderUvToShapeUvRadius.x + u_cylinderUvToShapeUvRadius.y; // x = scale, y = offset
48
+ radius = radius * u_cylinderUvToShapeUvRadius.x + u_cylinderUvToShapeUvRadius.y;
32
49
  #endif
33
50
 
34
- float height = positionUv.z; // [0,1]
51
+ float height = positionShape.y;
35
52
  #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT)
36
- height = height * u_cylinderUvToShapeUvHeight.x + u_cylinderUvToShapeUvHeight.y; // x = scale, y = offset
53
+ height = height * u_cylinderUvToShapeUvHeight.x + u_cylinderUvToShapeUvHeight.y;
37
54
  #endif
38
55
 
39
- float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1]
56
+ float angle = (positionShape.z + czm_pi) / czm_twoPi;
40
57
  #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE)
41
58
  #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED)
42
59
  // Comparing against u_cylinderShapeUvAngleMinMax has precision problems. u_cylinderShapeUvAngleRangeZeroMid is more conservative.
@@ -50,7 +67,32 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) {
50
67
  angle = angle < u_cylinderShapeUvAngleRangeZeroMid ? u_cylinderShapeUvAngleMinMax.y : angle;
51
68
  #endif
52
69
 
53
- angle = angle * u_cylinderUvToShapeUvAngle.x + u_cylinderUvToShapeUvAngle.y; // x = scale, y = offset
70
+ angle = angle * u_cylinderUvToShapeUvAngle.x + u_cylinderUvToShapeUvAngle.y;
71
+ #endif
72
+
73
+ return vec3(radius, height, angle);
74
+ }
75
+
76
+ PointJacobianT convertUvToShapeUvSpaceDerivative(in vec3 positionUv) {
77
+ PointJacobianT pointJacobian = convertUvToShapeSpaceDerivative(positionUv);
78
+ pointJacobian.point = convertShapeToShapeUvSpace(pointJacobian.point);
79
+ return pointJacobian;
80
+ }
81
+
82
+ vec3 scaleShapeUvToShapeSpace(in vec3 shapeUv) {
83
+ float radius = shapeUv.x;
84
+ #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS)
85
+ radius /= u_cylinderUvToShapeUvRadius.x;
86
+ #endif
87
+
88
+ float height = shapeUv.y;
89
+ #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT)
90
+ height /= u_cylinderUvToShapeUvHeight.x;
91
+ #endif
92
+
93
+ float angle = shapeUv.z * czm_twoPi;
94
+ #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE)
95
+ angle /= u_cylinderUvToShapeUvAngle.x;
54
96
  #endif
55
97
 
56
98
  return vec3(radius, height, angle);
@@ -24,20 +24,37 @@ export default "/* Cylinder defines (set in Scene/VoxelCylinderShape.js)\n\
24
24
  uniform float u_cylinderShapeUvAngleRangeZeroMid;\n\
25
25
  #endif\n\
26
26
  \n\
27
- vec3 convertUvToShapeUvSpace(in vec3 positionUv) {\n\
28
- vec3 positionLocal = positionUv * 2.0 - 1.0; // [-1,+1]\n\
27
+ PointJacobianT convertUvToShapeSpaceDerivative(in vec3 positionUv) {\n\
28
+ // Convert from Cartesian UV space [0, 1] to Cartesian local space [-1, 1]\n\
29
+ vec3 position = positionUv * 2.0 - 1.0;\n\
29
30
  \n\
30
- float radius = length(positionLocal.xy); // [0,1]\n\
31
+ float radius = length(position.xy); // [0, 1]\n\
32
+ vec3 radial = normalize(vec3(position.xy, 0.0));\n\
33
+ \n\
34
+ // Shape space height is defined within [0, 1]\n\
35
+ float height = positionUv.z; // [0, 1]\n\
36
+ vec3 z = vec3(0.0, 0.0, 1.0);\n\
37
+ \n\
38
+ float angle = atan(position.y, position.x);\n\
39
+ vec3 east = normalize(vec3(-position.y, position.x, 0.0));\n\
40
+ \n\
41
+ vec3 point = vec3(radius, height, angle);\n\
42
+ mat3 jacobianT = mat3(radial, z, east / length(position.xy));\n\
43
+ return PointJacobianT(point, jacobianT);\n\
44
+ }\n\
45
+ \n\
46
+ vec3 convertShapeToShapeUvSpace(in vec3 positionShape) {\n\
47
+ float radius = positionShape.x;\n\
31
48
  #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS)\n\
32
- radius = radius * u_cylinderUvToShapeUvRadius.x + u_cylinderUvToShapeUvRadius.y; // x = scale, y = offset\n\
49
+ radius = radius * u_cylinderUvToShapeUvRadius.x + u_cylinderUvToShapeUvRadius.y;\n\
33
50
  #endif\n\
34
51
  \n\
35
- float height = positionUv.z; // [0,1]\n\
52
+ float height = positionShape.y;\n\
36
53
  #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT)\n\
37
- height = height * u_cylinderUvToShapeUvHeight.x + u_cylinderUvToShapeUvHeight.y; // x = scale, y = offset\n\
54
+ height = height * u_cylinderUvToShapeUvHeight.x + u_cylinderUvToShapeUvHeight.y;\n\
38
55
  #endif\n\
39
56
  \n\
40
- float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1]\n\
57
+ float angle = (positionShape.z + czm_pi) / czm_twoPi;\n\
41
58
  #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE)\n\
42
59
  #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED)\n\
43
60
  // Comparing against u_cylinderShapeUvAngleMinMax has precision problems. u_cylinderShapeUvAngleRangeZeroMid is more conservative.\n\
@@ -51,7 +68,32 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) {\n\
51
68
  angle = angle < u_cylinderShapeUvAngleRangeZeroMid ? u_cylinderShapeUvAngleMinMax.y : angle;\n\
52
69
  #endif\n\
53
70
  \n\
54
- angle = angle * u_cylinderUvToShapeUvAngle.x + u_cylinderUvToShapeUvAngle.y; // x = scale, y = offset\n\
71
+ angle = angle * u_cylinderUvToShapeUvAngle.x + u_cylinderUvToShapeUvAngle.y;\n\
72
+ #endif\n\
73
+ \n\
74
+ return vec3(radius, height, angle);\n\
75
+ }\n\
76
+ \n\
77
+ PointJacobianT convertUvToShapeUvSpaceDerivative(in vec3 positionUv) {\n\
78
+ PointJacobianT pointJacobian = convertUvToShapeSpaceDerivative(positionUv);\n\
79
+ pointJacobian.point = convertShapeToShapeUvSpace(pointJacobian.point);\n\
80
+ return pointJacobian;\n\
81
+ }\n\
82
+ \n\
83
+ vec3 scaleShapeUvToShapeSpace(in vec3 shapeUv) {\n\
84
+ float radius = shapeUv.x;\n\
85
+ #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS)\n\
86
+ radius /= u_cylinderUvToShapeUvRadius.x;\n\
87
+ #endif\n\
88
+ \n\
89
+ float height = shapeUv.y;\n\
90
+ #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT)\n\
91
+ height /= u_cylinderUvToShapeUvHeight.x;\n\
92
+ #endif\n\
93
+ \n\
94
+ float angle = shapeUv.z * czm_twoPi;\n\
95
+ #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE)\n\
96
+ angle /= u_cylinderUvToShapeUvAngle.x;\n\
55
97
  #endif\n\
56
98
  \n\
57
99
  return vec3(radius, height, angle);\n\
@@ -4,14 +4,11 @@
4
4
  #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE
5
5
  #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED
6
6
  #define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE
7
- #define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_FLAT
8
- #define ELLIPSOID_IS_SPHERE
9
7
  */
10
8
 
11
9
  uniform vec3 u_ellipsoidRadiiUv; // [0,1]
12
- #if !defined(ELLIPSOID_IS_SPHERE)
13
- uniform vec3 u_ellipsoidInverseRadiiSquaredUv;
14
- #endif
10
+ uniform vec2 u_evoluteScale; // (radiiUv.x ^ 2 - radiiUv.z ^ 2) * vec2(1.0, -1.0) / radiiUv;
11
+ uniform vec3 u_ellipsoidInverseRadiiSquaredUv;
15
12
  #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY) || defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED)
16
13
  uniform vec3 u_ellipsoidShapeUvLongitudeMinMaxMid;
17
14
  #endif
@@ -21,49 +18,71 @@ uniform vec3 u_ellipsoidRadiiUv; // [0,1]
21
18
  #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE)
22
19
  uniform vec2 u_ellipsoidUvToShapeUvLatitude; // x = scale, y = offset
23
20
  #endif
24
- #if !defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_FLAT)
25
- uniform float u_ellipsoidInverseHeightDifferenceUv;
26
- uniform vec2 u_ellipseInnerRadiiUv; // [0,1]
27
- #endif
21
+ uniform float u_ellipsoidInverseHeightDifferenceUv;
28
22
 
29
23
  // robust iterative solution without trig functions
30
24
  // https://github.com/0xfaded/ellipse_demo/issues/1
31
25
  // https://stackoverflow.com/questions/22959698/distance-from-given-point-to-given-ellipse
32
- // Pro: Good when radii.x ~= radii.y
33
- // Con: Breaks at pos.x ~= 0.0, especially inside the ellipse
34
- // Con: Inaccurate with exterior points and thin ellipses
35
- float ellipseDistanceIterative (vec2 pos, vec2 radii) {
26
+ // Extended to return radius of curvature along with the point
27
+ vec3 nearestPointAndRadiusOnEllipse(vec2 pos, vec2 radii) {
36
28
  vec2 p = abs(pos);
37
- vec2 invRadii = 1.0 / radii;
38
- vec2 a = vec2(1.0, -1.0) * (radii.x * radii.x - radii.y * radii.y) * invRadii;
39
- vec2 t = vec2(0.70710678118); // sqrt(2) / 2
40
- vec2 v = radii * t;
29
+ vec2 inverseRadii = 1.0 / radii;
30
+
31
+ // We describe the ellipse parametrically: v = radii * vec2(cos(t), sin(t))
32
+ // but store the cos and sin of t in a vec2 for efficiency.
33
+ // Initial guess: t = pi/4
34
+ vec2 tTrigs = vec2(0.7071067811865476);
35
+ // Initial guess of point on ellipsoid
36
+ vec2 v = radii * tTrigs;
37
+ // Center of curvature of the ellipse at v
38
+ vec2 evolute = u_evoluteScale * tTrigs * tTrigs * tTrigs;
41
39
 
42
40
  const int iterations = 3;
43
41
  for (int i = 0; i < iterations; ++i) {
44
- vec2 e = a * pow(t, vec2(3.0));
45
- vec2 q = normalize(p - e) * length(v - e);
46
- t = normalize((q + e) * invRadii);
47
- v = radii * t;
42
+ // Find the (approximate) intersection of p - evolute with the ellipsoid.
43
+ vec2 q = normalize(p - evolute) * length(v - evolute);
44
+ // Update the estimate of t.
45
+ tTrigs = (q + evolute) * inverseRadii;
46
+ tTrigs = normalize(clamp(tTrigs, 0.0, 1.0));
47
+ v = radii * tTrigs;
48
+ evolute = u_evoluteScale * tTrigs * tTrigs * tTrigs;
48
49
  }
49
- return length(v * sign(pos) - pos) * sign(p.y - v.y);
50
+
51
+ return vec3(v * sign(pos), length(v - evolute));
50
52
  }
51
53
 
52
- vec3 convertUvToShapeUvSpace(in vec3 positionUv) {
53
- // Compute position and normal.
54
- // Convert positionUv [0,1] to local space [-1,+1] to "normalized" cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height).
55
- // A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller.
56
- vec3 positionLocal = positionUv * 2.0 - 1.0;
57
- #if defined(ELLIPSOID_IS_SPHERE)
58
- vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv.x;
59
- vec3 normal = normalize(posEllipsoid);
60
- #else
61
- vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv;
62
- vec3 normal = normalize(posEllipsoid * u_ellipsoidInverseRadiiSquaredUv); // geodetic surface normal
63
- #endif
54
+ PointJacobianT convertUvToShapeSpaceDerivative(in vec3 positionUv) {
55
+ // Convert from UV space [0, 1] to local space [-1, 1]
56
+ vec3 position = positionUv * 2.0 - 1.0;
57
+ // Undo the scaling from ellipsoid to sphere
58
+ position = position * u_ellipsoidRadiiUv;
59
+
60
+ float longitude = atan(position.y, position.x);
61
+ vec3 east = normalize(vec3(-position.y, position.x, 0.0));
62
+
63
+ // Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z)
64
+ // (assume radii.y == radii.x) and find the nearest point on the ellipse and its normal
65
+ float distanceFromZAxis = length(position.xy);
66
+ vec2 posEllipse = vec2(distanceFromZAxis, position.z);
67
+ vec3 surfacePointAndRadius = nearestPointAndRadiusOnEllipse(posEllipse, u_ellipsoidRadiiUv.xz);
68
+ vec2 surfacePoint = surfacePointAndRadius.xy;
69
+
70
+ vec2 normal2d = normalize(surfacePoint * u_ellipsoidInverseRadiiSquaredUv.xz);
71
+ float latitude = atan(normal2d.y, normal2d.x);
72
+ vec3 north = vec3(-normal2d.y * normalize(position.xy), abs(normal2d.x));
73
+
74
+ float heightSign = length(posEllipse) < length(surfacePoint) ? -1.0 : 1.0;
75
+ float height = heightSign * length(posEllipse - surfacePoint);
76
+ vec3 up = normalize(cross(east, north));
77
+
78
+ vec3 point = vec3(longitude, latitude, height);
79
+ mat3 jacobianT = mat3(east / distanceFromZAxis, north / (surfacePointAndRadius.z + height), up);
80
+ return PointJacobianT(point, jacobianT);
81
+ }
64
82
 
65
- // Compute longitude
66
- float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi;
83
+ vec3 convertShapeToShapeUvSpace(in vec3 positionShape) {
84
+ // Longitude: shift & scale to [0, 1]
85
+ float longitude = (positionShape.x + czm_pi) / czm_twoPi;
67
86
 
68
87
  // Correct the angle when max < min
69
88
  // Technically this should compare against min longitude - but it has precision problems so compare against the middle of empty space.
@@ -83,28 +102,38 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) {
83
102
  longitude = longitude * u_ellipsoidUvToShapeUvLongitude.x + u_ellipsoidUvToShapeUvLongitude.y;
84
103
  #endif
85
104
 
86
- // Compute latitude
87
- float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi;
105
+ // Latitude: shift and scale to [0, 1]
106
+ float latitude = (positionShape.y + czm_piOverTwo) / czm_pi;
88
107
  #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE)
89
108
  latitude = latitude * u_ellipsoidUvToShapeUvLatitude.x + u_ellipsoidUvToShapeUvLatitude.y;
90
109
  #endif
91
110
 
92
- // Compute height
93
- #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_FLAT)
94
- // TODO: This breaks down when minBounds == maxBounds. To fix it, this
95
- // function would have to know if ray is intersecting the front or back of the shape
96
- // and set the shape space position to 1 (front) or 0 (back) accordingly.
97
- float height = 1.0;
98
- #else
99
- #if defined(ELLIPSOID_IS_SPHERE)
100
- float height = (length(posEllipsoid) - u_ellipseInnerRadiiUv.x) * u_ellipsoidInverseHeightDifferenceUv;
101
- #else
102
- // Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84).
103
- // This is an optimization so that math can be done with ellipses instead of ellipsoids.
104
- vec2 posEllipse = vec2(length(posEllipsoid.xy), posEllipsoid.z);
105
- float height = ellipseDistanceIterative(posEllipse, u_ellipseInnerRadiiUv) * u_ellipsoidInverseHeightDifferenceUv;
106
- #endif
111
+ // Height: scale to the range [0, 1]
112
+ float height = 1.0 + positionShape.z * u_ellipsoidInverseHeightDifferenceUv;
113
+
114
+ return vec3(longitude, latitude, height);
115
+ }
116
+
117
+ PointJacobianT convertUvToShapeUvSpaceDerivative(in vec3 positionUv) {
118
+ PointJacobianT pointJacobian = convertUvToShapeSpaceDerivative(positionUv);
119
+ pointJacobian.point = convertShapeToShapeUvSpace(pointJacobian.point);
120
+ return pointJacobian;
121
+ }
122
+
123
+ vec3 scaleShapeUvToShapeSpace(in vec3 shapeUv) {
124
+ // Convert from [0, 1] to radians [-pi, pi]
125
+ float longitude = shapeUv.x * czm_twoPi;
126
+ #if defined (ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE)
127
+ longitude /= u_ellipsoidUvToShapeUvLongitude.x;
128
+ #endif
129
+
130
+ // Convert from [0, 1] to radians [-pi/2, pi/2]
131
+ float latitude = shapeUv.y * czm_pi;
132
+ #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE)
133
+ latitude /= u_ellipsoidUvToShapeUvLatitude.x;
107
134
  #endif
135
+
136
+ float height = shapeUv.z / u_ellipsoidInverseHeightDifferenceUv;
108
137
 
109
138
  return vec3(longitude, latitude, height);
110
139
  }
@@ -5,14 +5,11 @@ export default "/* Ellipsoid defines (set in Scene/VoxelEllipsoidShape.js)\n\
5
5
  #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE\n\
6
6
  #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED\n\
7
7
  #define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE\n\
8
- #define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_FLAT\n\
9
- #define ELLIPSOID_IS_SPHERE\n\
10
8
  */\n\
11
9
  \n\
12
10
  uniform vec3 u_ellipsoidRadiiUv; // [0,1]\n\
13
- #if !defined(ELLIPSOID_IS_SPHERE)\n\
14
- uniform vec3 u_ellipsoidInverseRadiiSquaredUv;\n\
15
- #endif\n\
11
+ uniform vec2 u_evoluteScale; // (radiiUv.x ^ 2 - radiiUv.z ^ 2) * vec2(1.0, -1.0) / radiiUv;\n\
12
+ uniform vec3 u_ellipsoidInverseRadiiSquaredUv;\n\
16
13
  #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY) || defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED)\n\
17
14
  uniform vec3 u_ellipsoidShapeUvLongitudeMinMaxMid;\n\
18
15
  #endif\n\
@@ -22,49 +19,71 @@ uniform vec3 u_ellipsoidRadiiUv; // [0,1]\n\
22
19
  #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE)\n\
23
20
  uniform vec2 u_ellipsoidUvToShapeUvLatitude; // x = scale, y = offset\n\
24
21
  #endif\n\
25
- #if !defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_FLAT)\n\
26
- uniform float u_ellipsoidInverseHeightDifferenceUv;\n\
27
- uniform vec2 u_ellipseInnerRadiiUv; // [0,1]\n\
28
- #endif\n\
22
+ uniform float u_ellipsoidInverseHeightDifferenceUv;\n\
29
23
  \n\
30
24
  // robust iterative solution without trig functions\n\
31
25
  // https://github.com/0xfaded/ellipse_demo/issues/1\n\
32
26
  // https://stackoverflow.com/questions/22959698/distance-from-given-point-to-given-ellipse\n\
33
- // Pro: Good when radii.x ~= radii.y\n\
34
- // Con: Breaks at pos.x ~= 0.0, especially inside the ellipse\n\
35
- // Con: Inaccurate with exterior points and thin ellipses\n\
36
- float ellipseDistanceIterative (vec2 pos, vec2 radii) {\n\
27
+ // Extended to return radius of curvature along with the point\n\
28
+ vec3 nearestPointAndRadiusOnEllipse(vec2 pos, vec2 radii) {\n\
37
29
  vec2 p = abs(pos);\n\
38
- vec2 invRadii = 1.0 / radii;\n\
39
- vec2 a = vec2(1.0, -1.0) * (radii.x * radii.x - radii.y * radii.y) * invRadii;\n\
40
- vec2 t = vec2(0.70710678118); // sqrt(2) / 2\n\
41
- vec2 v = radii * t;\n\
30
+ vec2 inverseRadii = 1.0 / radii;\n\
31
+ \n\
32
+ // We describe the ellipse parametrically: v = radii * vec2(cos(t), sin(t))\n\
33
+ // but store the cos and sin of t in a vec2 for efficiency.\n\
34
+ // Initial guess: t = pi/4\n\
35
+ vec2 tTrigs = vec2(0.7071067811865476);\n\
36
+ // Initial guess of point on ellipsoid\n\
37
+ vec2 v = radii * tTrigs;\n\
38
+ // Center of curvature of the ellipse at v\n\
39
+ vec2 evolute = u_evoluteScale * tTrigs * tTrigs * tTrigs;\n\
42
40
  \n\
43
41
  const int iterations = 3;\n\
44
42
  for (int i = 0; i < iterations; ++i) {\n\
45
- vec2 e = a * pow(t, vec2(3.0));\n\
46
- vec2 q = normalize(p - e) * length(v - e);\n\
47
- t = normalize((q + e) * invRadii);\n\
48
- v = radii * t;\n\
43
+ // Find the (approximate) intersection of p - evolute with the ellipsoid.\n\
44
+ vec2 q = normalize(p - evolute) * length(v - evolute);\n\
45
+ // Update the estimate of t.\n\
46
+ tTrigs = (q + evolute) * inverseRadii;\n\
47
+ tTrigs = normalize(clamp(tTrigs, 0.0, 1.0));\n\
48
+ v = radii * tTrigs;\n\
49
+ evolute = u_evoluteScale * tTrigs * tTrigs * tTrigs;\n\
49
50
  }\n\
50
- return length(v * sign(pos) - pos) * sign(p.y - v.y);\n\
51
+ \n\
52
+ return vec3(v * sign(pos), length(v - evolute));\n\
51
53
  }\n\
52
54
  \n\
53
- vec3 convertUvToShapeUvSpace(in vec3 positionUv) {\n\
54
- // Compute position and normal.\n\
55
- // Convert positionUv [0,1] to local space [-1,+1] to \"normalized\" cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height).\n\
56
- // A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller.\n\
57
- vec3 positionLocal = positionUv * 2.0 - 1.0;\n\
58
- #if defined(ELLIPSOID_IS_SPHERE)\n\
59
- vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv.x;\n\
60
- vec3 normal = normalize(posEllipsoid);\n\
61
- #else\n\
62
- vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv;\n\
63
- vec3 normal = normalize(posEllipsoid * u_ellipsoidInverseRadiiSquaredUv); // geodetic surface normal\n\
64
- #endif\n\
55
+ PointJacobianT convertUvToShapeSpaceDerivative(in vec3 positionUv) {\n\
56
+ // Convert from UV space [0, 1] to local space [-1, 1]\n\
57
+ vec3 position = positionUv * 2.0 - 1.0;\n\
58
+ // Undo the scaling from ellipsoid to sphere\n\
59
+ position = position * u_ellipsoidRadiiUv;\n\
60
+ \n\
61
+ float longitude = atan(position.y, position.x);\n\
62
+ vec3 east = normalize(vec3(-position.y, position.x, 0.0));\n\
63
+ \n\
64
+ // Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z)\n\
65
+ // (assume radii.y == radii.x) and find the nearest point on the ellipse and its normal\n\
66
+ float distanceFromZAxis = length(position.xy);\n\
67
+ vec2 posEllipse = vec2(distanceFromZAxis, position.z);\n\
68
+ vec3 surfacePointAndRadius = nearestPointAndRadiusOnEllipse(posEllipse, u_ellipsoidRadiiUv.xz);\n\
69
+ vec2 surfacePoint = surfacePointAndRadius.xy;\n\
70
+ \n\
71
+ vec2 normal2d = normalize(surfacePoint * u_ellipsoidInverseRadiiSquaredUv.xz);\n\
72
+ float latitude = atan(normal2d.y, normal2d.x);\n\
73
+ vec3 north = vec3(-normal2d.y * normalize(position.xy), abs(normal2d.x));\n\
74
+ \n\
75
+ float heightSign = length(posEllipse) < length(surfacePoint) ? -1.0 : 1.0;\n\
76
+ float height = heightSign * length(posEllipse - surfacePoint);\n\
77
+ vec3 up = normalize(cross(east, north));\n\
78
+ \n\
79
+ vec3 point = vec3(longitude, latitude, height);\n\
80
+ mat3 jacobianT = mat3(east / distanceFromZAxis, north / (surfacePointAndRadius.z + height), up);\n\
81
+ return PointJacobianT(point, jacobianT);\n\
82
+ }\n\
65
83
  \n\
66
- // Compute longitude\n\
67
- float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi;\n\
84
+ vec3 convertShapeToShapeUvSpace(in vec3 positionShape) {\n\
85
+ // Longitude: shift & scale to [0, 1]\n\
86
+ float longitude = (positionShape.x + czm_pi) / czm_twoPi;\n\
68
87
  \n\
69
88
  // Correct the angle when max < min\n\
70
89
  // Technically this should compare against min longitude - but it has precision problems so compare against the middle of empty space.\n\
@@ -84,28 +103,38 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) {\n\
84
103
  longitude = longitude * u_ellipsoidUvToShapeUvLongitude.x + u_ellipsoidUvToShapeUvLongitude.y;\n\
85
104
  #endif\n\
86
105
  \n\
87
- // Compute latitude\n\
88
- float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi;\n\
106
+ // Latitude: shift and scale to [0, 1]\n\
107
+ float latitude = (positionShape.y + czm_piOverTwo) / czm_pi;\n\
89
108
  #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE)\n\
90
109
  latitude = latitude * u_ellipsoidUvToShapeUvLatitude.x + u_ellipsoidUvToShapeUvLatitude.y;\n\
91
110
  #endif\n\
92
111
  \n\
93
- // Compute height\n\
94
- #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_FLAT)\n\
95
- // TODO: This breaks down when minBounds == maxBounds. To fix it, this\n\
96
- // function would have to know if ray is intersecting the front or back of the shape\n\
97
- // and set the shape space position to 1 (front) or 0 (back) accordingly.\n\
98
- float height = 1.0;\n\
99
- #else\n\
100
- #if defined(ELLIPSOID_IS_SPHERE)\n\
101
- float height = (length(posEllipsoid) - u_ellipseInnerRadiiUv.x) * u_ellipsoidInverseHeightDifferenceUv;\n\
102
- #else\n\
103
- // Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84).\n\
104
- // This is an optimization so that math can be done with ellipses instead of ellipsoids.\n\
105
- vec2 posEllipse = vec2(length(posEllipsoid.xy), posEllipsoid.z);\n\
106
- float height = ellipseDistanceIterative(posEllipse, u_ellipseInnerRadiiUv) * u_ellipsoidInverseHeightDifferenceUv;\n\
107
- #endif\n\
112
+ // Height: scale to the range [0, 1]\n\
113
+ float height = 1.0 + positionShape.z * u_ellipsoidInverseHeightDifferenceUv;\n\
114
+ \n\
115
+ return vec3(longitude, latitude, height);\n\
116
+ }\n\
117
+ \n\
118
+ PointJacobianT convertUvToShapeUvSpaceDerivative(in vec3 positionUv) {\n\
119
+ PointJacobianT pointJacobian = convertUvToShapeSpaceDerivative(positionUv);\n\
120
+ pointJacobian.point = convertShapeToShapeUvSpace(pointJacobian.point);\n\
121
+ return pointJacobian;\n\
122
+ }\n\
123
+ \n\
124
+ vec3 scaleShapeUvToShapeSpace(in vec3 shapeUv) {\n\
125
+ // Convert from [0, 1] to radians [-pi, pi]\n\
126
+ float longitude = shapeUv.x * czm_twoPi;\n\
127
+ #if defined (ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE)\n\
128
+ longitude /= u_ellipsoidUvToShapeUvLongitude.x;\n\
129
+ #endif\n\
130
+ \n\
131
+ // Convert from [0, 1] to radians [-pi/2, pi/2]\n\
132
+ float latitude = shapeUv.y * czm_pi;\n\
133
+ #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE)\n\
134
+ latitude /= u_ellipsoidUvToShapeUvLatitude.x;\n\
108
135
  #endif\n\
136
+ \n\
137
+ float height = shapeUv.z / u_ellipsoidInverseHeightDifferenceUv;\n\
109
138
  \n\
110
139
  return vec3(longitude, latitude, height);\n\
111
140
  }\n\