@cesium/engine 20.0.2-ion.0 → 21.0.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 (182) hide show
  1. package/Build/ThirdParty/Workers/zip-web-worker.js +637 -0
  2. package/Build/Workers/{chunk-WZKTQZUW.js → chunk-2T4WAVWX.js} +6 -6
  3. package/Build/Workers/{chunk-6LULWCX3.js → chunk-3G5XEUPY.js} +1 -1
  4. package/Build/Workers/{chunk-OIMV4OE5.js → chunk-3MSNTCHW.js} +9 -9
  5. package/Build/Workers/{chunk-VZNF2GT7.js → chunk-3OPG2FGI.js} +4 -4
  6. package/Build/Workers/{chunk-MTBXKKSQ.js → chunk-3PUG3T2H.js} +12 -12
  7. package/Build/Workers/{chunk-XWRUYDF6.js → chunk-4PH27XAL.js} +2 -2
  8. package/Build/Workers/{chunk-P2V7PVDH.js → chunk-4VJYMLR6.js} +8 -8
  9. package/Build/Workers/{chunk-MFXTB5I4.js → chunk-5B3PGBQW.js} +11 -11
  10. package/Build/Workers/{chunk-USK6ZAY2.js → chunk-5GHCWGC4.js} +1 -1
  11. package/Build/Workers/{chunk-AHFTST3Q.js → chunk-5PEQUMCB.js} +12 -12
  12. package/Build/Workers/{chunk-23B3EYUM.js → chunk-64WSG7AT.js} +4 -4
  13. package/Build/Workers/{chunk-CEA3L7M7.js → chunk-6J6WGCWP.js} +4 -4
  14. package/Build/Workers/{chunk-VSMKMGX4.js → chunk-75B34CC6.js} +5 -5
  15. package/Build/Workers/{chunk-IS5FETN7.js → chunk-7PLX65MV.js} +5 -5
  16. package/Build/Workers/{chunk-FNUSHLOY.js → chunk-AR2FUSG6.js} +1 -1
  17. package/Build/Workers/{chunk-VLGVUVJY.js → chunk-ARYRHDEB.js} +6 -6
  18. package/Build/Workers/{chunk-FHLPYFIW.js → chunk-B7INTBBB.js} +13 -13
  19. package/Build/Workers/{chunk-BHAATGZA.js → chunk-BDPSQXLX.js} +5 -5
  20. package/Build/Workers/{chunk-QZGZIAK2.js → chunk-BU4CGMHO.js} +6 -6
  21. package/Build/Workers/{chunk-YNPZU55A.js → chunk-BUBVUXDO.js} +6 -6
  22. package/Build/Workers/{chunk-LS63ERFB.js → chunk-CF72FAKC.js} +4 -4
  23. package/Build/Workers/{chunk-D4XRQNUO.js → chunk-DJ4ROETJ.js} +5 -5
  24. package/Build/Workers/{chunk-ABTG74AR.js → chunk-E5XCZVIY.js} +1 -1
  25. package/Build/Workers/{chunk-AFKNTEMH.js → chunk-EAYW4CFP.js} +16 -16
  26. package/Build/Workers/{chunk-YXTWHLJA.js → chunk-EHFMZFVC.js} +4 -4
  27. package/Build/Workers/{chunk-H7HFDM3G.js → chunk-FFCKCQPK.js} +5 -5
  28. package/Build/Workers/{chunk-V6ZGOX4I.js → chunk-GKCZ2G36.js} +7 -7
  29. package/Build/Workers/{chunk-VODCZKV2.js → chunk-HJ7IZBEI.js} +4 -4
  30. package/Build/Workers/{chunk-66MGJQFZ.js → chunk-JJZWDROM.js} +2 -2
  31. package/Build/Workers/{chunk-F4PS6RFF.js → chunk-JUOEBO4F.js} +10 -10
  32. package/Build/Workers/{chunk-WORBFT5H.js → chunk-K4IDXMIZ.js} +9 -9
  33. package/Build/Workers/{chunk-Q3OWKSC5.js → chunk-LL6HN3W4.js} +10 -10
  34. package/Build/Workers/{chunk-YUHWFX5H.js → chunk-LNTUIO55.js} +2 -2
  35. package/Build/Workers/{chunk-VA7LWA5Q.js → chunk-LWOCFJEH.js} +9 -9
  36. package/Build/Workers/{chunk-5DF5RVIO.js → chunk-MMUISYW4.js} +16 -16
  37. package/Build/Workers/{chunk-K6THSIDU.js → chunk-MXYW4BQ3.js} +2 -2
  38. package/Build/Workers/{chunk-X55ZOYMS.js → chunk-N6DVKXZD.js} +12 -12
  39. package/Build/Workers/{chunk-NKKNQMEH.js → chunk-NP46ZIBY.js} +3 -3
  40. package/Build/Workers/{chunk-QID3DXQA.js → chunk-OW6F6CPZ.js} +7 -7
  41. package/Build/Workers/{chunk-CYC7JX3P.js → chunk-P6OAOFBU.js} +8 -8
  42. package/Build/Workers/{chunk-FYYP46TF.js → chunk-PXDMWXO5.js} +2 -2
  43. package/Build/Workers/{chunk-TZDR2BAP.js → chunk-QS7623NH.js} +6 -6
  44. package/Build/Workers/{chunk-D5X2LOJ2.js → chunk-ROH45IXJ.js} +7 -7
  45. package/Build/Workers/{chunk-UR36KLNW.js → chunk-S2P6LCIB.js} +4 -4
  46. package/Build/Workers/{chunk-Z2W7ZIGV.js → chunk-S4NZVXU6.js} +2 -2
  47. package/Build/Workers/{chunk-YSDOO7AG.js → chunk-SGGO5WVA.js} +5 -5
  48. package/Build/Workers/{chunk-H5IQLAJP.js → chunk-TG7N7TPY.js} +47 -50
  49. package/Build/Workers/{chunk-XIDMFHR4.js → chunk-TUZQG4RW.js} +14 -14
  50. package/Build/Workers/{chunk-JVG6T2WE.js → chunk-UHVE7V65.js} +12 -12
  51. package/Build/Workers/{chunk-FAQ2XNFV.js → chunk-UY2HVPDL.js} +5 -5
  52. package/Build/Workers/{chunk-CUU3WGXJ.js → chunk-YNLPRFUQ.js} +6 -6
  53. package/Build/Workers/{chunk-X6GXYB3M.js → chunk-ZYOHBCCE.js} +1 -1
  54. package/Build/Workers/combineGeometry.js +21 -21
  55. package/Build/Workers/createBoxGeometry.js +15 -15
  56. package/Build/Workers/createBoxOutlineGeometry.js +13 -13
  57. package/Build/Workers/createCircleGeometry.js +23 -23
  58. package/Build/Workers/createCircleOutlineGeometry.js +16 -16
  59. package/Build/Workers/createCoplanarPolygonGeometry.js +30 -30
  60. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +28 -28
  61. package/Build/Workers/createCorridorGeometry.js +26 -26
  62. package/Build/Workers/createCorridorOutlineGeometry.js +25 -25
  63. package/Build/Workers/createCylinderGeometry.js +17 -17
  64. package/Build/Workers/createCylinderOutlineGeometry.js +15 -15
  65. package/Build/Workers/createEllipseGeometry.js +23 -23
  66. package/Build/Workers/createEllipseOutlineGeometry.js +16 -16
  67. package/Build/Workers/createEllipsoidGeometry.js +16 -16
  68. package/Build/Workers/createEllipsoidOutlineGeometry.js +15 -15
  69. package/Build/Workers/createFrustumGeometry.js +15 -15
  70. package/Build/Workers/createFrustumOutlineGeometry.js +15 -15
  71. package/Build/Workers/createGeometry.js +21 -21
  72. package/Build/Workers/createGroundPolylineGeometry.js +19 -19
  73. package/Build/Workers/createPlaneGeometry.js +13 -13
  74. package/Build/Workers/createPlaneOutlineGeometry.js +12 -12
  75. package/Build/Workers/createPolygonGeometry.js +29 -29
  76. package/Build/Workers/createPolygonOutlineGeometry.js +27 -27
  77. package/Build/Workers/createPolylineGeometry.js +22 -22
  78. package/Build/Workers/createPolylineVolumeGeometry.js +28 -28
  79. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +24 -24
  80. package/Build/Workers/createRectangleGeometry.js +24 -24
  81. package/Build/Workers/createRectangleOutlineGeometry.js +17 -17
  82. package/Build/Workers/createSimplePolylineGeometry.js +20 -20
  83. package/Build/Workers/createSphereGeometry.js +16 -16
  84. package/Build/Workers/createSphereOutlineGeometry.js +15 -15
  85. package/Build/Workers/createTaskProcessorWorker.js +3 -3
  86. package/Build/Workers/createVectorTileClampedPolylines.js +12 -12
  87. package/Build/Workers/createVectorTileGeometries.js +21 -21
  88. package/Build/Workers/createVectorTilePoints.js +11 -11
  89. package/Build/Workers/createVectorTilePolygons.js +19 -19
  90. package/Build/Workers/createVectorTilePolylines.js +12 -12
  91. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +19 -19
  92. package/Build/Workers/createVerticesFromHeightmap.js +19 -19
  93. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +16 -16
  94. package/Build/Workers/createWallGeometry.js +21 -21
  95. package/Build/Workers/createWallOutlineGeometry.js +20 -20
  96. package/Build/Workers/decodeDraco.js +10 -10
  97. package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
  98. package/Build/Workers/decodeI3S.js +9 -9
  99. package/Build/Workers/gaussianSplatSorter.js +4 -4
  100. package/Build/Workers/gaussianSplatTextureGenerator.js +4 -4
  101. package/Build/Workers/transcodeKTX2.js +6 -6
  102. package/Build/Workers/transferTypedArrayTest.js +1 -1
  103. package/Build/Workers/upsampleQuantizedTerrainMesh.js +19 -19
  104. package/Source/Core/Event.js +41 -49
  105. package/Source/Core/GoogleMaps.js +2 -2
  106. package/Source/Core/Ion.js +1 -1
  107. package/Source/Core/IonResource.js +30 -4
  108. package/Source/Core/Resource.js +5 -1
  109. package/Source/DataSources/KmlDataSource.js +62 -63
  110. package/Source/DataSources/exportKml.js +27 -30
  111. package/Source/Scene/ArcGisMapService.js +1 -1
  112. package/Source/Scene/Azure2DImageryProvider.js +308 -0
  113. package/Source/Scene/Billboard.js +4 -0
  114. package/Source/Scene/BillboardCollection.js +9 -2
  115. package/Source/Scene/ClippingPlaneCollection.js +3 -3
  116. package/Source/Scene/ClippingPolygon.js +91 -2
  117. package/Source/Scene/CreditDisplay.js +1 -1
  118. package/Source/Scene/GaussianSplat3DTileContent.js +54 -9
  119. package/Source/Scene/GaussianSplatPrimitive.js +49 -50
  120. package/Source/Scene/Google2DImageryProvider.js +614 -0
  121. package/Source/Scene/IonImageryProvider.js +22 -1
  122. package/Source/Scene/LabelCollection.js +1 -0
  123. package/Source/Scene/Material.js +248 -80
  124. package/Source/Scene/Primitive.js +6 -0
  125. package/Source/Scene/PrimitiveState.js +123 -0
  126. package/Source/Scene/Scene.js +2 -2
  127. package/Source/Scene/VoxelBoundsCollection.js +494 -0
  128. package/Source/Scene/VoxelBoxShape.js +236 -101
  129. package/Source/Scene/VoxelCylinderShape.js +315 -204
  130. package/Source/Scene/VoxelEllipsoidShape.js +402 -119
  131. package/Source/Scene/VoxelPrimitive.js +119 -84
  132. package/Source/Scene/VoxelRenderResources.js +17 -10
  133. package/Source/Scene/VoxelShape.js +21 -6
  134. package/Source/Scene/buildVoxelDrawCommands.js +61 -20
  135. package/Source/Scene/createGooglePhotorealistic3DTileset.js +1 -1
  136. package/Source/Scene/getClippingFunction.js +79 -88
  137. package/Source/Shaders/BillboardCollectionVS.glsl +2 -0
  138. package/Source/Shaders/BillboardCollectionVS.js +2 -0
  139. package/Source/Shaders/Voxels/IntersectBox.glsl +20 -33
  140. package/Source/Shaders/Voxels/IntersectBox.js +20 -33
  141. package/Source/Shaders/Voxels/IntersectCylinder.glsl +28 -32
  142. package/Source/Shaders/Voxels/IntersectCylinder.js +28 -32
  143. package/Source/Shaders/Voxels/IntersectDepth.glsl +1 -4
  144. package/Source/Shaders/Voxels/IntersectDepth.js +1 -4
  145. package/Source/Shaders/Voxels/IntersectEllipsoid.glsl +12 -20
  146. package/Source/Shaders/Voxels/IntersectEllipsoid.js +12 -20
  147. package/Source/Shaders/Voxels/IntersectLongitude.glsl +21 -9
  148. package/Source/Shaders/Voxels/IntersectLongitude.js +21 -9
  149. package/Source/Shaders/Voxels/{IntersectClippingPlanes.glsl → IntersectPlane.glsl} +5 -3
  150. package/Source/Shaders/Voxels/{IntersectClippingPlanes.js → IntersectPlane.js} +5 -3
  151. package/Source/Shaders/Voxels/Intersection.glsl +3 -3
  152. package/Source/Shaders/Voxels/Intersection.js +3 -3
  153. package/Source/Shaders/Voxels/Octree.glsl +46 -51
  154. package/Source/Shaders/Voxels/Octree.js +46 -51
  155. package/Source/Shaders/Voxels/VoxelFS.glsl +50 -48
  156. package/Source/Shaders/Voxels/VoxelFS.js +50 -48
  157. package/Source/Shaders/Voxels/VoxelUtils.glsl +0 -19
  158. package/Source/Shaders/Voxels/VoxelUtils.js +0 -19
  159. package/Source/Shaders/Voxels/convertLocalToBoxUv.glsl +30 -0
  160. package/Source/Shaders/Voxels/convertLocalToBoxUv.js +32 -0
  161. package/Source/Shaders/Voxels/convertLocalToCylinderUv.glsl +97 -0
  162. package/Source/Shaders/Voxels/convertLocalToCylinderUv.js +99 -0
  163. package/Source/Shaders/Voxels/convertLocalToEllipsoidUv.glsl +193 -0
  164. package/Source/Shaders/Voxels/convertLocalToEllipsoidUv.js +195 -0
  165. package/Source/ThirdParty/Workers/zip-web-worker.js +1 -0
  166. package/Source/ThirdParty/zip-module.wasm +0 -0
  167. package/index.d.ts +317 -14
  168. package/index.js +141 -139
  169. package/package.json +2 -2
  170. package/Build/ThirdParty/Workers/pako_deflate.min.js +0 -503
  171. package/Build/ThirdParty/Workers/pako_inflate.min.js +0 -698
  172. package/Build/ThirdParty/Workers/z-worker-pako.js +0 -601
  173. package/Source/Core/defaultValue.js +0 -48
  174. package/Source/Shaders/Voxels/convertUvToBox.glsl +0 -45
  175. package/Source/Shaders/Voxels/convertUvToBox.js +0 -46
  176. package/Source/Shaders/Voxels/convertUvToCylinder.glsl +0 -99
  177. package/Source/Shaders/Voxels/convertUvToCylinder.js +0 -101
  178. package/Source/Shaders/Voxels/convertUvToEllipsoid.glsl +0 -139
  179. package/Source/Shaders/Voxels/convertUvToEllipsoid.js +0 -141
  180. package/Source/ThirdParty/Workers/pako_deflate.min.js +0 -2
  181. package/Source/ThirdParty/Workers/pako_inflate.min.js +0 -2
  182. package/Source/ThirdParty/Workers/z-worker-pako.js +0 -1
@@ -26,7 +26,7 @@
26
26
  #endif
27
27
  uniform float u_eccentricitySquared;
28
28
  uniform vec2 u_ellipsoidRenderLatitudeSinMinMax;
29
- uniform vec2 u_clipMinMaxHeight;
29
+ uniform vec2 u_clipMinMaxHeight; // Values are negative: clipHeight - maxShapeHeight
30
30
 
31
31
  RayShapeIntersection intersectZPlane(in Ray ray, in float z) {
32
32
  float t = -ray.pos.z / ray.dir.z;
@@ -44,11 +44,11 @@ RayShapeIntersection intersectZPlane(in Ray ray, in float z) {
44
44
  }
45
45
  }
46
46
 
47
- RayShapeIntersection intersectHeight(in Ray ray, in float relativeHeight, in bool convex)
47
+ RayShapeIntersection intersectHeight(in Ray ray, in float height, in bool convex)
48
48
  {
49
49
  // Scale the ray by the ellipsoid axes to make it a unit sphere
50
50
  // Note: approximating ellipsoid + height as an ellipsoid
51
- vec3 radiiCorrection = u_ellipsoidRadiiUv / (u_ellipsoidRadiiUv + relativeHeight);
51
+ vec3 radiiCorrection = vec3(1.0) / (u_ellipsoidRadii + height);
52
52
  vec3 position = ray.pos * radiiCorrection;
53
53
  vec3 direction = ray.dir * radiiCorrection;
54
54
 
@@ -74,10 +74,14 @@ RayShapeIntersection intersectHeight(in Ray ray, in float relativeHeight, in boo
74
74
  float tmax = max(t1, t2);
75
75
 
76
76
  float directionScale = convex ? 1.0 : -1.0;
77
- vec3 d1 = directionScale * normalize(position + tmin * direction);
78
- vec3 d2 = directionScale * normalize(position + tmax * direction);
77
+ vec3 d1 = directionScale * (position + tmin * direction);
78
+ vec3 d2 = directionScale * (position + tmax * direction);
79
79
 
80
- return RayShapeIntersection(vec4(d1, tmin), vec4(d2, tmax));
80
+ // Return normals in eye coordinates. Use spherical approximation for the normal.
81
+ vec3 normal1 = normalize(czm_normal * d1);
82
+ vec3 normal2 = normalize(czm_normal * d2);
83
+
84
+ return RayShapeIntersection(vec4(normal1, tmin), vec4(normal2, tmax));
81
85
  }
82
86
 
83
87
  /**
@@ -151,16 +155,13 @@ float getLatitudeConeShift(in float sinLatitude) {
151
155
  // Find prime vertical radius of curvature:
152
156
  // the distance along the ellipsoid normal to the intersection with the z-axis
153
157
  float x2 = u_eccentricitySquared * sinLatitude * sinLatitude;
154
- float primeVerticalRadius = inversesqrt(1.0 - x2);
158
+ float primeVerticalRadius = u_ellipsoidRadii.x * inversesqrt(1.0 - x2);
155
159
 
156
160
  // Compute a shift from the origin to the intersection of the cone with the z-axis
157
161
  return primeVerticalRadius * u_eccentricitySquared * sinLatitude;
158
162
  }
159
163
 
160
164
  void intersectFlippedCone(in Ray ray, in float cosHalfAngle, out RayShapeIntersection intersections[2]) {
161
- // Undo the scaling from ellipsoid to sphere
162
- ray.pos = ray.pos * u_ellipsoidRadiiUv;
163
- ray.dir = ray.dir * u_ellipsoidRadiiUv;
164
165
  // Shift the ray to account for the latitude cone not being centered at the Earth center
165
166
  ray.pos.z += getLatitudeConeShift(cosHalfAngle);
166
167
 
@@ -206,9 +207,6 @@ void intersectFlippedCone(in Ray ray, in float cosHalfAngle, out RayShapeInterse
206
207
  }
207
208
 
208
209
  RayShapeIntersection intersectRegularCone(in Ray ray, in float cosHalfAngle, in bool convex) {
209
- // Undo the scaling from ellipsoid to sphere
210
- ray.pos = ray.pos * u_ellipsoidRadiiUv;
211
- ray.dir = ray.dir * u_ellipsoidRadiiUv;
212
210
  // Shift the ray to account for the latitude cone not being centered at the Earth center
213
211
  ray.pos.z += getLatitudeConeShift(cosHalfAngle);
214
212
 
@@ -245,13 +243,7 @@ RayShapeIntersection intersectRegularCone(in Ray ray, in float cosHalfAngle, in
245
243
  }
246
244
  }
247
245
 
248
- void intersectShape(in Ray ray, inout Intersections ix) {
249
- // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1].
250
- // Direction is scaled as well to be in sync with position.
251
- ray.pos = ray.pos * 2.0 - 1.0;
252
- ray.dir *= 2.0;
253
-
254
- // Outer ellipsoid
246
+ void intersectShape(in Ray ray, in Ray rayEC, inout Intersections ix) { // Outer ellipsoid
255
247
  RayShapeIntersection outerIntersect = intersectHeight(ray, u_clipMinMaxHeight.y, true);
256
248
  setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX, outerIntersect);
257
249
 
@@ -27,7 +27,7 @@ export default "// See IntersectionUtils.glsl for the definitions of Ray, NO_HIT
27
27
  #endif\n\
28
28
  uniform float u_eccentricitySquared;\n\
29
29
  uniform vec2 u_ellipsoidRenderLatitudeSinMinMax;\n\
30
- uniform vec2 u_clipMinMaxHeight;\n\
30
+ uniform vec2 u_clipMinMaxHeight; // Values are negative: clipHeight - maxShapeHeight\n\
31
31
  \n\
32
32
  RayShapeIntersection intersectZPlane(in Ray ray, in float z) {\n\
33
33
  float t = -ray.pos.z / ray.dir.z;\n\
@@ -45,11 +45,11 @@ RayShapeIntersection intersectZPlane(in Ray ray, in float z) {\n\
45
45
  }\n\
46
46
  }\n\
47
47
  \n\
48
- RayShapeIntersection intersectHeight(in Ray ray, in float relativeHeight, in bool convex)\n\
48
+ RayShapeIntersection intersectHeight(in Ray ray, in float height, in bool convex)\n\
49
49
  {\n\
50
50
  // Scale the ray by the ellipsoid axes to make it a unit sphere\n\
51
51
  // Note: approximating ellipsoid + height as an ellipsoid\n\
52
- vec3 radiiCorrection = u_ellipsoidRadiiUv / (u_ellipsoidRadiiUv + relativeHeight);\n\
52
+ vec3 radiiCorrection = vec3(1.0) / (u_ellipsoidRadii + height);\n\
53
53
  vec3 position = ray.pos * radiiCorrection;\n\
54
54
  vec3 direction = ray.dir * radiiCorrection;\n\
55
55
  \n\
@@ -75,10 +75,14 @@ RayShapeIntersection intersectHeight(in Ray ray, in float relativeHeight, in boo
75
75
  float tmax = max(t1, t2);\n\
76
76
  \n\
77
77
  float directionScale = convex ? 1.0 : -1.0;\n\
78
- vec3 d1 = directionScale * normalize(position + tmin * direction);\n\
79
- vec3 d2 = directionScale * normalize(position + tmax * direction);\n\
78
+ vec3 d1 = directionScale * (position + tmin * direction);\n\
79
+ vec3 d2 = directionScale * (position + tmax * direction);\n\
80
80
  \n\
81
- return RayShapeIntersection(vec4(d1, tmin), vec4(d2, tmax));\n\
81
+ // Return normals in eye coordinates. Use spherical approximation for the normal.\n\
82
+ vec3 normal1 = normalize(czm_normal * d1);\n\
83
+ vec3 normal2 = normalize(czm_normal * d2);\n\
84
+ \n\
85
+ return RayShapeIntersection(vec4(normal1, tmin), vec4(normal2, tmax));\n\
82
86
  }\n\
83
87
  \n\
84
88
  /**\n\
@@ -152,16 +156,13 @@ float getLatitudeConeShift(in float sinLatitude) {\n\
152
156
  // Find prime vertical radius of curvature: \n\
153
157
  // the distance along the ellipsoid normal to the intersection with the z-axis\n\
154
158
  float x2 = u_eccentricitySquared * sinLatitude * sinLatitude;\n\
155
- float primeVerticalRadius = inversesqrt(1.0 - x2);\n\
159
+ float primeVerticalRadius = u_ellipsoidRadii.x * inversesqrt(1.0 - x2);\n\
156
160
  \n\
157
161
  // Compute a shift from the origin to the intersection of the cone with the z-axis\n\
158
162
  return primeVerticalRadius * u_eccentricitySquared * sinLatitude;\n\
159
163
  }\n\
160
164
  \n\
161
165
  void intersectFlippedCone(in Ray ray, in float cosHalfAngle, out RayShapeIntersection intersections[2]) {\n\
162
- // Undo the scaling from ellipsoid to sphere\n\
163
- ray.pos = ray.pos * u_ellipsoidRadiiUv;\n\
164
- ray.dir = ray.dir * u_ellipsoidRadiiUv;\n\
165
166
  // Shift the ray to account for the latitude cone not being centered at the Earth center\n\
166
167
  ray.pos.z += getLatitudeConeShift(cosHalfAngle);\n\
167
168
  \n\
@@ -207,9 +208,6 @@ void intersectFlippedCone(in Ray ray, in float cosHalfAngle, out RayShapeInterse
207
208
  }\n\
208
209
  \n\
209
210
  RayShapeIntersection intersectRegularCone(in Ray ray, in float cosHalfAngle, in bool convex) {\n\
210
- // Undo the scaling from ellipsoid to sphere\n\
211
- ray.pos = ray.pos * u_ellipsoidRadiiUv;\n\
212
- ray.dir = ray.dir * u_ellipsoidRadiiUv;\n\
213
211
  // Shift the ray to account for the latitude cone not being centered at the Earth center\n\
214
212
  ray.pos.z += getLatitudeConeShift(cosHalfAngle);\n\
215
213
  \n\
@@ -246,13 +244,7 @@ RayShapeIntersection intersectRegularCone(in Ray ray, in float cosHalfAngle, in
246
244
  }\n\
247
245
  }\n\
248
246
  \n\
249
- void intersectShape(in Ray ray, inout Intersections ix) {\n\
250
- // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1].\n\
251
- // Direction is scaled as well to be in sync with position.\n\
252
- ray.pos = ray.pos * 2.0 - 1.0;\n\
253
- ray.dir *= 2.0;\n\
254
- \n\
255
- // Outer ellipsoid\n\
247
+ void intersectShape(in Ray ray, in Ray rayEC, inout Intersections ix) { // Outer ellipsoid\n\
256
248
  RayShapeIntersection outerIntersect = intersectHeight(ray, u_clipMinMaxHeight.y, true);\n\
257
249
  setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX, outerIntersect);\n\
258
250
  \n\
@@ -1,6 +1,14 @@
1
1
  // See IntersectionUtils.glsl for the definitions of Ray, NO_HIT, INF_HIT,
2
2
  // RayShapeIntersection
3
3
 
4
+ vec4 transformNormalToEC(in vec4 intersection) {
5
+ return vec4(normalize(czm_normal * intersection.xyz), intersection.w);
6
+ }
7
+
8
+ RayShapeIntersection transformNormalsToEC(in RayShapeIntersection ix) {
9
+ return RayShapeIntersection(transformNormalToEC(ix.entry), transformNormalToEC(ix.exit));
10
+ }
11
+
4
12
  vec4 intersectLongitude(in Ray ray, in float angle, in bool positiveNormal) {
5
13
  float normalSign = positiveNormal ? 1.0 : -1.0;
6
14
  vec2 planeNormal = vec2(-sin(angle), cos(angle)) * normalSign;
@@ -32,8 +40,8 @@ RayShapeIntersection intersectHalfSpace(in Ray ray, in float angle, in bool posi
32
40
 
33
41
  void intersectFlippedWedge(in Ray ray, in vec2 minMaxAngle, out RayShapeIntersection intersections[2])
34
42
  {
35
- intersections[0] = intersectHalfSpace(ray, minMaxAngle.x, false);
36
- intersections[1] = intersectHalfSpace(ray, minMaxAngle.y, true);
43
+ intersections[0] = transformNormalsToEC(intersectHalfSpace(ray, minMaxAngle.x, false));
44
+ intersections[1] = transformNormalsToEC(intersectHalfSpace(ray, minMaxAngle.y, true));
37
45
  }
38
46
 
39
47
  bool hitPositiveHalfPlane(in Ray ray, in vec4 intersection, in bool positiveNormal) {
@@ -46,14 +54,18 @@ bool hitPositiveHalfPlane(in Ray ray, in vec4 intersection, in bool positiveNorm
46
54
  void intersectHalfPlane(in Ray ray, in float angle, out RayShapeIntersection intersections[2]) {
47
55
  vec4 intersection = intersectLongitude(ray, angle, true);
48
56
  vec4 farSide = vec4(normalize(ray.dir), INF_HIT);
57
+ bool hitPositiveSide = hitPositiveHalfPlane(ray, intersection, true);
58
+
59
+ farSide = transformNormalToEC(farSide);
49
60
 
50
- if (hitPositiveHalfPlane(ray, intersection, true)) {
61
+ if (hitPositiveSide) {
62
+ intersection = transformNormalToEC(intersection);
51
63
  intersections[0].entry = -1.0 * farSide;
52
- intersections[0].exit = vec4(-1.0 * intersection.xy, 0.0, intersection.w);
64
+ intersections[0].exit = vec4(-1.0 * intersection.xyz, intersection.w);
53
65
  intersections[1].entry = intersection;
54
66
  intersections[1].exit = farSide;
55
67
  } else {
56
- vec4 miss = vec4(normalize(ray.dir), NO_HIT);
68
+ vec4 miss = vec4(normalize(czm_normal * ray.dir), NO_HIT);
57
69
  intersections[0].entry = -1.0 * farSide;
58
70
  intersections[0].exit = farSide;
59
71
  intersections[1].entry = miss;
@@ -88,15 +100,15 @@ RayShapeIntersection intersectRegularWedge(in Ray ray, in vec2 minMaxAngle)
88
100
 
89
101
  if (exitFromInside && enterFromOutside) {
90
102
  // Ray crosses both faces of negative wedge, exiting then entering the positive shape
91
- return RayShapeIntersection(first, last);
103
+ return transformNormalsToEC(RayShapeIntersection(first, last));
92
104
  } else if (!exitFromInside && enterFromOutside) {
93
105
  // Ray starts inside wedge. last is in shadow wedge, and first is actually the entry
94
- return RayShapeIntersection(-1.0 * farSide, first);
106
+ return transformNormalsToEC(RayShapeIntersection(-1.0 * farSide, first));
95
107
  } else if (exitFromInside && !enterFromOutside) {
96
108
  // First intersection was in the shadow wedge, so last is actually the exit
97
- return RayShapeIntersection(last, farSide);
109
+ return transformNormalsToEC(RayShapeIntersection(last, farSide));
98
110
  } else { // !exitFromInside && !enterFromOutside
99
111
  // Both intersections were in the shadow wedge
100
- return RayShapeIntersection(miss, miss);
112
+ return transformNormalsToEC(RayShapeIntersection(miss, miss));
101
113
  }
102
114
  }
@@ -2,6 +2,14 @@
2
2
  export default "// See IntersectionUtils.glsl for the definitions of Ray, NO_HIT, INF_HIT,\n\
3
3
  // RayShapeIntersection\n\
4
4
  \n\
5
+ vec4 transformNormalToEC(in vec4 intersection) {\n\
6
+ return vec4(normalize(czm_normal * intersection.xyz), intersection.w);\n\
7
+ }\n\
8
+ \n\
9
+ RayShapeIntersection transformNormalsToEC(in RayShapeIntersection ix) {\n\
10
+ return RayShapeIntersection(transformNormalToEC(ix.entry), transformNormalToEC(ix.exit));\n\
11
+ }\n\
12
+ \n\
5
13
  vec4 intersectLongitude(in Ray ray, in float angle, in bool positiveNormal) {\n\
6
14
  float normalSign = positiveNormal ? 1.0 : -1.0;\n\
7
15
  vec2 planeNormal = vec2(-sin(angle), cos(angle)) * normalSign;\n\
@@ -33,8 +41,8 @@ RayShapeIntersection intersectHalfSpace(in Ray ray, in float angle, in bool posi
33
41
  \n\
34
42
  void intersectFlippedWedge(in Ray ray, in vec2 minMaxAngle, out RayShapeIntersection intersections[2])\n\
35
43
  {\n\
36
- intersections[0] = intersectHalfSpace(ray, minMaxAngle.x, false);\n\
37
- intersections[1] = intersectHalfSpace(ray, minMaxAngle.y, true);\n\
44
+ intersections[0] = transformNormalsToEC(intersectHalfSpace(ray, minMaxAngle.x, false));\n\
45
+ intersections[1] = transformNormalsToEC(intersectHalfSpace(ray, minMaxAngle.y, true));\n\
38
46
  }\n\
39
47
  \n\
40
48
  bool hitPositiveHalfPlane(in Ray ray, in vec4 intersection, in bool positiveNormal) {\n\
@@ -47,14 +55,18 @@ bool hitPositiveHalfPlane(in Ray ray, in vec4 intersection, in bool positiveNorm
47
55
  void intersectHalfPlane(in Ray ray, in float angle, out RayShapeIntersection intersections[2]) {\n\
48
56
  vec4 intersection = intersectLongitude(ray, angle, true);\n\
49
57
  vec4 farSide = vec4(normalize(ray.dir), INF_HIT);\n\
58
+ bool hitPositiveSide = hitPositiveHalfPlane(ray, intersection, true);\n\
59
+ \n\
60
+ farSide = transformNormalToEC(farSide);\n\
50
61
  \n\
51
- if (hitPositiveHalfPlane(ray, intersection, true)) {\n\
62
+ if (hitPositiveSide) {\n\
63
+ intersection = transformNormalToEC(intersection);\n\
52
64
  intersections[0].entry = -1.0 * farSide;\n\
53
- intersections[0].exit = vec4(-1.0 * intersection.xy, 0.0, intersection.w);\n\
65
+ intersections[0].exit = vec4(-1.0 * intersection.xyz, intersection.w);\n\
54
66
  intersections[1].entry = intersection;\n\
55
67
  intersections[1].exit = farSide;\n\
56
68
  } else {\n\
57
- vec4 miss = vec4(normalize(ray.dir), NO_HIT);\n\
69
+ vec4 miss = vec4(normalize(czm_normal * ray.dir), NO_HIT);\n\
58
70
  intersections[0].entry = -1.0 * farSide;\n\
59
71
  intersections[0].exit = farSide;\n\
60
72
  intersections[1].entry = miss;\n\
@@ -89,16 +101,16 @@ RayShapeIntersection intersectRegularWedge(in Ray ray, in vec2 minMaxAngle)\n\
89
101
  \n\
90
102
  if (exitFromInside && enterFromOutside) {\n\
91
103
  // Ray crosses both faces of negative wedge, exiting then entering the positive shape\n\
92
- return RayShapeIntersection(first, last);\n\
104
+ return transformNormalsToEC(RayShapeIntersection(first, last));\n\
93
105
  } else if (!exitFromInside && enterFromOutside) {\n\
94
106
  // Ray starts inside wedge. last is in shadow wedge, and first is actually the entry\n\
95
- return RayShapeIntersection(-1.0 * farSide, first);\n\
107
+ return transformNormalsToEC(RayShapeIntersection(-1.0 * farSide, first));\n\
96
108
  } else if (exitFromInside && !enterFromOutside) {\n\
97
109
  // First intersection was in the shadow wedge, so last is actually the exit\n\
98
- return RayShapeIntersection(last, farSide);\n\
110
+ return transformNormalsToEC(RayShapeIntersection(last, farSide));\n\
99
111
  } else { // !exitFromInside && !enterFromOutside\n\
100
112
  // Both intersections were in the shadow wedge\n\
101
- return RayShapeIntersection(miss, miss);\n\
113
+ return transformNormalsToEC(RayShapeIntersection(miss, miss));\n\
102
114
  }\n\
103
115
  }\n\
104
116
  ";
@@ -22,6 +22,7 @@ vec4 intersectPlane(in Ray ray, in vec4 plane) {
22
22
  return vec4(n, t);
23
23
  }
24
24
 
25
+ #ifdef CLIPPING_PLANES
25
26
  void intersectClippingPlanes(in Ray ray, inout Intersections ix) {
26
27
  vec4 backSide = vec4(-ray.dir, -INF_HIT);
27
28
  vec4 farSide = vec4(ray.dir, +INF_HIT);
@@ -30,7 +31,7 @@ void intersectClippingPlanes(in Ray ray, inout Intersections ix) {
30
31
  #if (CLIPPING_PLANES_COUNT == 1)
31
32
  // Union and intersection are the same when there's one clipping plane, and the code
32
33
  // is more simplified.
33
- vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, 0, u_clippingPlanesMatrix);
34
+ vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, 0);
34
35
  vec4 intersection = intersectPlane(ray, planeUv);
35
36
  bool reflects = dot(ray.dir, intersection.xyz) < 0.0;
36
37
  clippingVolume.entry = reflects ? backSide : intersection;
@@ -40,7 +41,7 @@ void intersectClippingPlanes(in Ray ray, inout Intersections ix) {
40
41
  vec4 firstTransmission = vec4(ray.dir, +INF_HIT);
41
42
  vec4 lastReflection = vec4(-ray.dir, -INF_HIT);
42
43
  for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) {
43
- vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix);
44
+ vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i);
44
45
  vec4 intersection = intersectPlane(ray, planeUv);
45
46
  if (dot(ray.dir, planeUv.xyz) > 0.0) {
46
47
  firstTransmission = intersection.w <= firstTransmission.w ? intersection : firstTransmission;
@@ -58,7 +59,7 @@ void intersectClippingPlanes(in Ray ray, inout Intersections ix) {
58
59
  vec4 lastTransmission = vec4(ray.dir, -INF_HIT);
59
60
  vec4 firstReflection = vec4(-ray.dir, +INF_HIT);
60
61
  for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) {
61
- vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix);
62
+ vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i);
62
63
  vec4 intersection = intersectPlane(ray, planeUv);
63
64
  if (dot(ray.dir, planeUv.xyz) > 0.0) {
64
65
  lastTransmission = intersection.w > lastTransmission.w ? intersection : lastTransmission;
@@ -76,3 +77,4 @@ void intersectClippingPlanes(in Ray ray, inout Intersections ix) {
76
77
  setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX, clippingVolume);
77
78
  #endif
78
79
  }
80
+ #endif
@@ -23,6 +23,7 @@ vec4 intersectPlane(in Ray ray, in vec4 plane) {\n\
23
23
  return vec4(n, t);\n\
24
24
  }\n\
25
25
  \n\
26
+ #ifdef CLIPPING_PLANES\n\
26
27
  void intersectClippingPlanes(in Ray ray, inout Intersections ix) {\n\
27
28
  vec4 backSide = vec4(-ray.dir, -INF_HIT);\n\
28
29
  vec4 farSide = vec4(ray.dir, +INF_HIT);\n\
@@ -31,7 +32,7 @@ void intersectClippingPlanes(in Ray ray, inout Intersections ix) {\n\
31
32
  #if (CLIPPING_PLANES_COUNT == 1)\n\
32
33
  // Union and intersection are the same when there's one clipping plane, and the code\n\
33
34
  // is more simplified.\n\
34
- vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, 0, u_clippingPlanesMatrix);\n\
35
+ vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, 0);\n\
35
36
  vec4 intersection = intersectPlane(ray, planeUv);\n\
36
37
  bool reflects = dot(ray.dir, intersection.xyz) < 0.0;\n\
37
38
  clippingVolume.entry = reflects ? backSide : intersection;\n\
@@ -41,7 +42,7 @@ void intersectClippingPlanes(in Ray ray, inout Intersections ix) {\n\
41
42
  vec4 firstTransmission = vec4(ray.dir, +INF_HIT);\n\
42
43
  vec4 lastReflection = vec4(-ray.dir, -INF_HIT);\n\
43
44
  for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) {\n\
44
- vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix);\n\
45
+ vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i);\n\
45
46
  vec4 intersection = intersectPlane(ray, planeUv);\n\
46
47
  if (dot(ray.dir, planeUv.xyz) > 0.0) {\n\
47
48
  firstTransmission = intersection.w <= firstTransmission.w ? intersection : firstTransmission;\n\
@@ -59,7 +60,7 @@ void intersectClippingPlanes(in Ray ray, inout Intersections ix) {\n\
59
60
  vec4 lastTransmission = vec4(ray.dir, -INF_HIT);\n\
60
61
  vec4 firstReflection = vec4(-ray.dir, +INF_HIT);\n\
61
62
  for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) {\n\
62
- vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix);\n\
63
+ vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i);\n\
63
64
  vec4 intersection = intersectPlane(ray, planeUv);\n\
64
65
  if (dot(ray.dir, planeUv.xyz) > 0.0) {\n\
65
66
  lastTransmission = intersection.w > lastTransmission.w ? intersection : lastTransmission;\n\
@@ -77,4 +78,5 @@ void intersectClippingPlanes(in Ray ray, inout Intersections ix) {\n\
77
78
  setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX, clippingVolume);\n\
78
79
  #endif\n\
79
80
  }\n\
81
+ #endif\n\
80
82
  ";
@@ -11,9 +11,9 @@
11
11
  #define INTERSECTION_COUNT ###
12
12
  */
13
13
 
14
- RayShapeIntersection intersectScene(in vec2 screenCoord, in Ray ray, out Intersections ix) {
14
+ RayShapeIntersection intersectScene(in vec2 screenCoord, in Ray ray, in Ray rayEC, out Intersections ix) {
15
15
  // Do a ray-shape intersection to find the exact starting and ending points.
16
- intersectShape(ray, ix);
16
+ intersectShape(ray, rayEC, ix);
17
17
 
18
18
  // Exit early if the positive shape was completely missed or behind the ray.
19
19
  RayShapeIntersection intersection = getFirstIntersection(ix);
@@ -28,7 +28,7 @@ RayShapeIntersection intersectScene(in vec2 screenCoord, in Ray ray, out Interse
28
28
  #endif
29
29
 
30
30
  // Depth
31
- intersectDepth(screenCoord, ray, ix);
31
+ intersectDepth(screenCoord, rayEC, ix);
32
32
 
33
33
  // Find the first intersection that's in front of the ray
34
34
  #if (INTERSECTION_COUNT > 1)
@@ -12,9 +12,9 @@ export default "// Main intersection function for Voxel scenes.\n\
12
12
  #define INTERSECTION_COUNT ###\n\
13
13
  */\n\
14
14
  \n\
15
- RayShapeIntersection intersectScene(in vec2 screenCoord, in Ray ray, out Intersections ix) {\n\
15
+ RayShapeIntersection intersectScene(in vec2 screenCoord, in Ray ray, in Ray rayEC, out Intersections ix) {\n\
16
16
  // Do a ray-shape intersection to find the exact starting and ending points.\n\
17
- intersectShape(ray, ix);\n\
17
+ intersectShape(ray, rayEC, ix);\n\
18
18
  \n\
19
19
  // Exit early if the positive shape was completely missed or behind the ray.\n\
20
20
  RayShapeIntersection intersection = getFirstIntersection(ix);\n\
@@ -29,7 +29,7 @@ RayShapeIntersection intersectScene(in vec2 screenCoord, in Ray ray, out Interse
29
29
  #endif\n\
30
30
  \n\
31
31
  // Depth\n\
32
- intersectDepth(screenCoord, ray, ix);\n\
32
+ intersectDepth(screenCoord, rayEC, ix);\n\
33
33
  \n\
34
34
  // Find the first intersection that's in front of the ray\n\
35
35
  #if (INTERSECTION_COUNT > 1)\n\
@@ -29,6 +29,11 @@ struct TraversalData {
29
29
  int parentOctreeIndex;
30
30
  };
31
31
 
32
+ struct TileAndUvCoordinate {
33
+ ivec4 tileCoords;
34
+ vec3 tileUv;
35
+ };
36
+
32
37
  struct SampleData {
33
38
  int megatextureIndex;
34
39
  ivec4 tileCoords;
@@ -79,23 +84,20 @@ int getOctreeParentIndex(in int octreeIndex) {
79
84
  return parentOctreeIndex;
80
85
  }
81
86
 
82
- /**
83
- * Convert a position in the uv-space of the tileset bounding shape
84
- * into the uv-space of a tile within the tileset
85
- */
86
- vec3 getTileUv(in vec3 shapePosition, in ivec4 octreeCoords) {
87
- // PERFORMANCE_IDEA: use bit-shifting (only in WebGL2)
88
- float dimAtLevel = exp2(float(octreeCoords.w));
89
- return shapePosition * dimAtLevel - vec3(octreeCoords.xyz);
87
+ vec3 getTileUv(in TileAndUvCoordinate tileAndUv, in ivec4 octreeCoords) {
88
+ int levelDifference = tileAndUv.tileCoords.w - octreeCoords.w;
89
+ float scalar = exp2(-1.0 * float(levelDifference));
90
+ vec3 originShift = vec3(tileAndUv.tileCoords.xyz - (octreeCoords.xyz << levelDifference)) * scalar;
91
+ return tileAndUv.tileUv * scalar + originShift;
90
92
  }
91
93
 
92
- vec3 getClampedTileUv(in vec3 shapePosition, in ivec4 octreeCoords) {
93
- vec3 tileUv = getTileUv(shapePosition, octreeCoords);
94
+ vec3 getClampedTileUv(in TileAndUvCoordinate tileAndUv, in ivec4 octreeCoords) {
95
+ vec3 tileUv = getTileUv(tileAndUv, octreeCoords);
94
96
  return clamp(tileUv, vec3(0.0), vec3(1.0));
95
97
  }
96
98
 
97
- void addSampleCoordinates(in vec3 shapePosition, inout SampleData sampleData) {
98
- vec3 tileUv = getClampedTileUv(shapePosition, sampleData.tileCoords);
99
+ void addSampleCoordinates(in TileAndUvCoordinate tileAndUv, inout SampleData sampleData) {
100
+ vec3 tileUv = getClampedTileUv(tileAndUv, sampleData.tileCoords);
99
101
 
100
102
  vec3 inputCoordinate = tileUv * vec3(u_dimensions);
101
103
  #if defined(PADDING)
@@ -162,32 +164,25 @@ void getOctreeLeafSampleDatas(in OctreeNodeData data, in ivec4 octreeCoords, out
162
164
  }
163
165
  #endif
164
166
 
165
- OctreeNodeData traverseOctreeDownwards(in vec3 shapePosition, inout TraversalData traversalData) {
166
- float sizeAtLevel = exp2(-1.0 * float(traversalData.octreeCoords.w));
167
- vec3 start = vec3(traversalData.octreeCoords.xyz) * sizeAtLevel;
168
- vec3 end = start + vec3(sizeAtLevel);
167
+ OctreeNodeData traverseOctreeDownwards(in ivec4 tileCoordinate, inout TraversalData traversalData) {
169
168
  OctreeNodeData childData;
170
169
 
171
170
  for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) {
172
- // Find out which octree child contains the position
173
- // 0 if before center, 1 if after
174
- vec3 center = 0.5 * (start + end);
175
- vec3 childCoord = step(center, shapePosition);
176
-
177
- // Get octree coords for the next level down
178
- ivec4 octreeCoords = traversalData.octreeCoords;
179
- traversalData.octreeCoords = ivec4(octreeCoords.xyz * 2 + ivec3(childCoord), octreeCoords.w + 1);
171
+ // tileCoordinate.xyz is defined at the level of detail tileCoordinate.w.
172
+ // Find the corresponding coordinate at the level traversalData.octreeCoords.w
173
+ int level = traversalData.octreeCoords.w + 1;
174
+ int levelDifference = tileCoordinate.w - level;
175
+ ivec3 coordinateAtLevel = tileCoordinate.xyz >> levelDifference;
176
+ traversalData.octreeCoords = ivec4(coordinateAtLevel, level);
180
177
 
181
- childData = getOctreeChildData(traversalData.parentOctreeIndex, ivec3(childCoord));
178
+ ivec3 childCoordinate = coordinateAtLevel & 1;
179
+ childData = getOctreeChildData(traversalData.parentOctreeIndex, childCoordinate);
182
180
 
183
181
  if (childData.flag != OCTREE_FLAG_INTERNAL) {
184
182
  // leaf tile - stop traversing
185
183
  break;
186
184
  }
187
185
 
188
- // interior tile - keep going deeper
189
- start = mix(start, center, childCoord);
190
- end = mix(center, end, childCoord);
191
186
  traversalData.parentOctreeIndex = childData.data;
192
187
  }
193
188
 
@@ -198,50 +193,50 @@ OctreeNodeData traverseOctreeDownwards(in vec3 shapePosition, inout TraversalDat
198
193
  * Transform a given position to an octree tile coordinate and a position within that tile,
199
194
  * and find the corresponding megatexture index and texture coordinates
200
195
  */
201
- void traverseOctreeFromBeginning(in vec3 shapePosition, out TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) {
196
+ void traverseOctreeFromBeginning(in TileAndUvCoordinate tileAndUv, out TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) {
202
197
  traversalData.octreeCoords = ivec4(0);
203
198
  traversalData.parentOctreeIndex = 0;
204
199
 
205
200
  OctreeNodeData nodeData = getOctreeNodeData(vec2(0.0));
206
201
  if (nodeData.flag != OCTREE_FLAG_LEAF) {
207
- nodeData = traverseOctreeDownwards(shapePosition, traversalData);
202
+ nodeData = traverseOctreeDownwards(tileAndUv.tileCoords, traversalData);
208
203
  }
209
204
 
210
205
  #if (SAMPLE_COUNT == 1)
211
206
  getOctreeLeafSampleData(nodeData, traversalData.octreeCoords, sampleDatas[0]);
212
- addSampleCoordinates(shapePosition, sampleDatas[0]);
207
+ addSampleCoordinates(tileAndUv, sampleDatas[0]);
213
208
  #else
214
209
  getOctreeLeafSampleDatas(nodeData, traversalData.octreeCoords, sampleDatas);
215
- addSampleCoordinates(shapePosition, sampleDatas[0]);
216
- addSampleCoordinates(shapePosition, sampleDatas[1]);
210
+ addSampleCoordinates(tileAndUv, sampleDatas[0]);
211
+ addSampleCoordinates(tileAndUv, sampleDatas[1]);
217
212
  #endif
218
213
  }
219
214
 
220
- bool inRange(in vec3 v, in vec3 minVal, in vec3 maxVal) {
221
- return clamp(v, minVal, maxVal) == v;
222
- }
223
-
224
- bool insideTile(in vec3 shapePosition, in ivec4 octreeCoords) {
225
- vec3 tileUv = getTileUv(shapePosition, octreeCoords);
226
- bool inside = inRange(tileUv, vec3(0.0), vec3(1.0));
227
- // Assume (!) the position is always inside the root tile.
228
- return inside || octreeCoords.w == 0;
215
+ bool insideTile(in ivec4 tileCoordinate, in ivec4 octreeCoords) {
216
+ int levelDifference = tileCoordinate.w - octreeCoords.w;
217
+ if (levelDifference < 0) {
218
+ return false;
219
+ }
220
+ ivec3 coordinateAtLevel = tileCoordinate.xyz >> levelDifference;
221
+ return coordinateAtLevel == octreeCoords.xyz;
229
222
  }
230
223
 
231
- void traverseOctreeFromExisting(in vec3 shapePosition, inout TraversalData traversalData, inout SampleData sampleDatas[SAMPLE_COUNT]) {
232
- if (insideTile(shapePosition, traversalData.octreeCoords)) {
224
+ void traverseOctreeFromExisting(in TileAndUvCoordinate tileAndUv, inout TraversalData traversalData, inout SampleData sampleDatas[SAMPLE_COUNT]) {
225
+ ivec4 tileCoords = tileAndUv.tileCoords;
226
+ if (insideTile(tileCoords, traversalData.octreeCoords)) {
233
227
  for (int i = 0; i < SAMPLE_COUNT; i++) {
234
- addSampleCoordinates(shapePosition, sampleDatas[i]);
228
+ addSampleCoordinates(tileAndUv, sampleDatas[i]);
235
229
  }
236
230
  return;
237
231
  }
238
232
 
239
- // Go up tree until we find a parent tile containing shapePosition
233
+ // Go up tree until we find a parent tile containing tileCoords.
234
+ // Assumes all parents are available all they way up to the root.
240
235
  for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) {
241
236
  traversalData.octreeCoords.xyz /= 2;
242
237
  traversalData.octreeCoords.w -= 1;
243
238
 
244
- if (insideTile(shapePosition, traversalData.octreeCoords)) {
239
+ if (insideTile(tileCoords, traversalData.octreeCoords)) {
245
240
  break;
246
241
  }
247
242
 
@@ -249,14 +244,14 @@ void traverseOctreeFromExisting(in vec3 shapePosition, inout TraversalData trave
249
244
  }
250
245
 
251
246
  // Go down tree
252
- OctreeNodeData nodeData = traverseOctreeDownwards(shapePosition, traversalData);
247
+ OctreeNodeData nodeData = traverseOctreeDownwards(tileCoords, traversalData);
253
248
 
254
249
  #if (SAMPLE_COUNT == 1)
255
250
  getOctreeLeafSampleData(nodeData, traversalData.octreeCoords, sampleDatas[0]);
256
- addSampleCoordinates(shapePosition, sampleDatas[0]);
251
+ addSampleCoordinates(tileAndUv, sampleDatas[0]);
257
252
  #else
258
253
  getOctreeLeafSampleDatas(nodeData, traversalData.octreeCoords, sampleDatas);
259
- addSampleCoordinates(shapePosition, sampleDatas[0]);
260
- addSampleCoordinates(shapePosition, sampleDatas[1]);
254
+ addSampleCoordinates(tileAndUv, sampleDatas[0]);
255
+ addSampleCoordinates(tileAndUv, sampleDatas[1]);
261
256
  #endif
262
257
  }