Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | //This file is automatically rebuilt by the Cesium build process.
export default "// See IntersectionUtils.glsl for the definitions of Ray, NO_HIT, INF_HIT, Intersections,\n\
// RayShapeIntersection, setSurfaceIntersection, setShapeIntersection\n\
// See IntersectLongitude.glsl for the definitions of intersectHalfPlane,\n\
// intersectFlippedWedge, intersectRegularWedge\n\
\n\
/* Ellipsoid defines (set in Scene/VoxelEllipsoidShape.js)\n\
#define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE\n\
#define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO\n\
#define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF\n\
#define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF\n\
#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF\n\
#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF\n\
#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF\n\
#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF\n\
#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF\n\
#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF\n\
#define ELLIPSOID_INTERSECTION_INDEX_LONGITUDE\n\
#define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX\n\
#define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN\n\
#define ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX\n\
#define ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN\n\
*/\n\
\n\
#if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE)\n\
uniform vec2 u_ellipsoidRenderLongitudeMinMax;\n\
#endif\n\
uniform float u_eccentricitySquared;\n\
uniform vec2 u_ellipsoidRenderLatitudeSinMinMax;\n\
uniform vec2 u_clipMinMaxHeight; // Values are negative: clipHeight - maxShapeHeight\n\
\n\
RayShapeIntersection intersectZPlane(in Ray ray, in float z) {\n\
float t = -ray.pos.z / ray.dir.z;\n\
\n\
bool startsOutside = sign(ray.pos.z) == sign(z);\n\
bool entry = (t >= 0.0) != startsOutside;\n\
\n\
vec4 intersect = vec4(0.0, 0.0, z, t);\n\
vec4 farSide = vec4(normalize(ray.dir), INF_HIT);\n\
\n\
if (entry) {\n\
return RayShapeIntersection(intersect, farSide);\n\
} else {\n\
return RayShapeIntersection(-1.0 * farSide, intersect);\n\
}\n\
}\n\
\n\
RayShapeIntersection intersectHeight(in Ray ray, in float height, in bool convex)\n\
{\n\
// Scale the ray by the ellipsoid axes to make it a unit sphere\n\
// Note: approximating ellipsoid + height as an ellipsoid\n\
vec3 radiiCorrection = vec3(1.0) / (u_ellipsoidRadii + height);\n\
vec3 position = ray.pos * radiiCorrection;\n\
vec3 direction = ray.dir * radiiCorrection;\n\
\n\
float a = dot(direction, direction); // ~ 1.0 (or maybe 4.0 if ray is scaled)\n\
float b = dot(direction, position); // roughly inside [-1.0, 1.0] when zoomed in\n\
float c = dot(position, position) - 1.0; // ~ 0.0 when zoomed in.\n\
float determinant = b * b - a * c; // ~ b * b when zoomed in\n\
\n\
if (determinant < 0.0) {\n\
vec4 miss = vec4(normalize(direction), NO_HIT);\n\
return RayShapeIntersection(miss, miss);\n\
}\n\
\n\
determinant = sqrt(determinant);\n\
\n\
// Compute larger root using standard formula\n\
float signB = b < 0.0 ? -1.0 : 1.0;\n\
// The other root may suffer from subtractive cancellation in the standard formula.\n\
// Compute it from the first root instead.\n\
float t1 = (-b - signB * determinant) / a;\n\
float t2 = c / (a * t1);\n\
float tmin = min(t1, t2);\n\
float tmax = max(t1, t2);\n\
\n\
float directionScale = convex ? 1.0 : -1.0;\n\
vec3 d1 = directionScale * (position + tmin * direction);\n\
vec3 d2 = directionScale * (position + tmax * direction);\n\
\n\
// Return normals in eye coordinates. Use spherical approximation for the normal.\n\
vec3 normal1 = normalize(czm_normal * d1);\n\
vec3 normal2 = normalize(czm_normal * d2);\n\
\n\
return RayShapeIntersection(vec4(normal1, tmin), vec4(normal2, tmax));\n\
}\n\
\n\
/**\n\
* Given a circular cone around the z-axis, with apex at the origin,\n\
* find the parametric distance(s) along a ray where that ray intersects\n\
* the cone.\n\
* The cone opening angle is described by the squared cosine of\n\
* its half-angle (the angle between the Z-axis and the surface)\n\
*/\n\
vec2 intersectDoubleEndedCone(in Ray ray, in float cosSqrHalfAngle)\n\
{\n\
vec3 o = ray.pos;\n\
vec3 d = ray.dir;\n\
float sinSqrHalfAngle = 1.0 - cosSqrHalfAngle;\n\
\n\
float aSin = d.z * d.z * sinSqrHalfAngle;\n\
float aCos = -dot(d.xy, d.xy) * cosSqrHalfAngle;\n\
float a = aSin + aCos;\n\
\n\
float bSin = d.z * o.z * sinSqrHalfAngle;\n\
float bCos = -dot(o.xy, d.xy) * cosSqrHalfAngle;\n\
float b = bSin + bCos;\n\
\n\
float cSin = o.z * o.z * sinSqrHalfAngle;\n\
float cCos = -dot(o.xy, o.xy) * cosSqrHalfAngle;\n\
float c = cSin + cCos;\n\
// determinant = b * b - a * c. But bSin * bSin = aSin * cSin.\n\
// Avoid subtractive cancellation by expanding to eliminate these terms\n\
float determinant = 2.0 * bSin * bCos + bCos * bCos - aSin * cCos - aCos * cSin - aCos * cCos;\n\
\n\
if (determinant < 0.0) {\n\
return vec2(NO_HIT);\n\
} else if (a == 0.0) {\n\
// Ray is parallel to cone surface\n\
return (b == 0.0)\n\
? vec2(NO_HIT) // Ray is on cone surface\n\
: vec2(-0.5 * c / b, NO_HIT);\n\
}\n\
\n\
determinant = sqrt(determinant);\n\
\n\
// Compute larger root using standard formula\n\
float signB = b < 0.0 ? -1.0 : 1.0;\n\
float t1 = (-b - signB * determinant) / a;\n\
// The other root may suffer from subtractive cancellation in the standard formula.\n\
// Compute it from the first root instead.\n\
float t2 = c / (a * t1);\n\
float tmin = min(t1, t2);\n\
float tmax = max(t1, t2);\n\
return vec2(tmin, tmax);\n\
}\n\
\n\
/**\n\
* Given a point on a conical surface, find the surface normal at that point.\n\
*/\n\
vec3 getConeNormal(in vec3 p, in bool convex) {\n\
// Start with radial component pointing toward z-axis\n\
vec2 radial = -abs(p.z) * normalize(p.xy);\n\
// Z component points toward opening of cone\n\
float zSign = (p.z < 0.0) ? -1.0 : 1.0;\n\
float z = length(p.xy) * zSign;\n\
// Flip normal if shape is convex\n\
float flip = (convex) ? -1.0 : 1.0;\n\
return normalize(vec3(radial, z) * flip);\n\
}\n\
\n\
/**\n\
* Compute the shift between the ellipsoid origin and the apex of a cone of latitude\n\
*/\n\
float getLatitudeConeShift(in float sinLatitude) {\n\
// Find prime vertical radius of curvature: \n\
// the distance along the ellipsoid normal to the intersection with the z-axis\n\
float x2 = u_eccentricitySquared * sinLatitude * sinLatitude;\n\
float primeVerticalRadius = u_ellipsoidRadii.x * inversesqrt(1.0 - x2);\n\
\n\
// Compute a shift from the origin to the intersection of the cone with the z-axis\n\
return primeVerticalRadius * u_eccentricitySquared * sinLatitude;\n\
}\n\
\n\
void intersectFlippedCone(in Ray ray, in float cosHalfAngle, out RayShapeIntersection intersections[2]) {\n\
// Shift the ray to account for the latitude cone not being centered at the Earth center\n\
ray.pos.z += getLatitudeConeShift(cosHalfAngle);\n\
\n\
float cosSqrHalfAngle = cosHalfAngle * cosHalfAngle;\n\
vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle);\n\
\n\
vec4 miss = vec4(normalize(ray.dir), NO_HIT);\n\
vec4 farSide = vec4(normalize(ray.dir), INF_HIT);\n\
\n\
// Initialize output with no intersections\n\
intersections[0].entry = -1.0 * farSide;\n\
intersections[0].exit = farSide;\n\
intersections[1].entry = miss;\n\
intersections[1].exit = miss;\n\
\n\
if (intersect.x == NO_HIT) {\n\
return;\n\
}\n\
\n\
// Find the points of intersection\n\
float tmin = intersect.x;\n\
float tmax = intersect.y;\n\
vec3 p0 = ray.pos + tmin * ray.dir;\n\
vec3 p1 = ray.pos + tmax * ray.dir;\n\
\n\
vec4 intersect0 = vec4(getConeNormal(p0, true), tmin);\n\
vec4 intersect1 = vec4(getConeNormal(p1, true), tmax);\n\
\n\
bool p0InShadowCone = sign(p0.z) != sign(cosHalfAngle);\n\
bool p1InShadowCone = sign(p1.z) != sign(cosHalfAngle);\n\
\n\
if (p0InShadowCone && p1InShadowCone) {\n\
// no valid intersections\n\
} else if (p0InShadowCone) {\n\
intersections[0].exit = intersect1;\n\
} else if (p1InShadowCone) {\n\
intersections[0].entry = intersect0;\n\
} else {\n\
intersections[0].exit = intersect0;\n\
intersections[1].entry = intersect1;\n\
intersections[1].exit = farSide;\n\
}\n\
}\n\
\n\
RayShapeIntersection intersectRegularCone(in Ray ray, in float cosHalfAngle, in bool convex) {\n\
// Shift the ray to account for the latitude cone not being centered at the Earth center\n\
ray.pos.z += getLatitudeConeShift(cosHalfAngle);\n\
\n\
float cosSqrHalfAngle = cosHalfAngle * cosHalfAngle;\n\
vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle);\n\
\n\
vec4 miss = vec4(normalize(ray.dir), NO_HIT);\n\
vec4 farSide = vec4(normalize(ray.dir), INF_HIT);\n\
\n\
if (intersect.x == NO_HIT) {\n\
return RayShapeIntersection(miss, miss);\n\
}\n\
\n\
// Find the points of intersection\n\
float tmin = intersect.x;\n\
float tmax = intersect.y;\n\
vec3 p0 = ray.pos + tmin * ray.dir;\n\
vec3 p1 = ray.pos + tmax * ray.dir;\n\
\n\
vec4 intersect0 = vec4(getConeNormal(p0, convex), tmin);\n\
vec4 intersect1 = vec4(getConeNormal(p1, convex), tmax);\n\
\n\
bool p0InShadowCone = sign(p0.z) != sign(cosHalfAngle);\n\
bool p1InShadowCone = sign(p1.z) != sign(cosHalfAngle);\n\
\n\
if (p0InShadowCone && p1InShadowCone) {\n\
return RayShapeIntersection(miss, miss);\n\
} else if (p0InShadowCone) {\n\
return RayShapeIntersection(intersect1, farSide);\n\
} else if (p1InShadowCone) {\n\
return RayShapeIntersection(-1.0 * farSide, intersect0);\n\
} else {\n\
return RayShapeIntersection(intersect0, intersect1);\n\
}\n\
}\n\
\n\
void intersectShape(in Ray ray, in Ray rayEC, inout Intersections ix) { // Outer ellipsoid\n\
RayShapeIntersection outerIntersect = intersectHeight(ray, u_clipMinMaxHeight.y, true);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX, outerIntersect);\n\
\n\
// Exit early if the outer ellipsoid was missed.\n\
if (outerIntersect.entry.w == NO_HIT) {\n\
return;\n\
}\n\
\n\
// Inner ellipsoid\n\
RayShapeIntersection innerIntersect = intersectHeight(ray, u_clipMinMaxHeight.x, false);\n\
\n\
if (innerIntersect.entry.w == NO_HIT) {\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN, innerIntersect);\n\
} else {\n\
// When the ellipsoid is large and thin it's possible for floating point math\n\
// to cause the ray to intersect the inner ellipsoid before the outer ellipsoid. \n\
// To prevent this from happening, clamp innerIntersect to outerIntersect and\n\
// sandwich the inner ellipsoid intersection inside the outer ellipsoid intersection.\n\
\n\
// Without this special case,\n\
// [outerMin, outerMax, innerMin, innerMax] will bubble sort to\n\
// [outerMin, innerMin, outerMax, innerMax] which will cause the back\n\
// side of the ellipsoid to be invisible because it will think the ray\n\
// is still inside the inner (negative) ellipsoid after exiting the\n\
// outer (positive) ellipsoid.\n\
\n\
// With this special case,\n\
// [outerMin, innerMin, innerMax, outerMax] will bubble sort to\n\
// [outerMin, innerMin, innerMax, outerMax] which will work correctly.\n\
\n\
// Note: If initializeIntersections() changes its sorting function\n\
// from bubble sort to something else, this code may need to change.\n\
innerIntersect.entry.w = max(innerIntersect.entry.w, outerIntersect.entry.w);\n\
innerIntersect.exit.w = min(innerIntersect.exit.w, outerIntersect.exit.w);\n\
setSurfaceIntersection(ix, 0, outerIntersect.entry, true, true); // positive, enter\n\
setSurfaceIntersection(ix, 1, innerIntersect.entry, false, true); // negative, enter\n\
setSurfaceIntersection(ix, 2, innerIntersect.exit, false, false); // negative, exit\n\
setSurfaceIntersection(ix, 3, outerIntersect.exit, true, false); // positive, exit\n\
}\n\
\n\
// Bottom cone\n\
#if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF)\n\
RayShapeIntersection bottomConeIntersection = intersectRegularCone(ray, u_ellipsoidRenderLatitudeSinMinMax.x, false);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN, bottomConeIntersection);\n\
#elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF)\n\
RayShapeIntersection bottomConeIntersection = intersectZPlane(ray, -1.0);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN, bottomConeIntersection);\n\
#elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF)\n\
RayShapeIntersection bottomConeIntersections[2];\n\
intersectFlippedCone(ray, u_ellipsoidRenderLatitudeSinMinMax.x, bottomConeIntersections);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 0, bottomConeIntersections[0]);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 1, bottomConeIntersections[1]);\n\
#endif\n\
\n\
// Top cone\n\
#if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF)\n\
RayShapeIntersection topConeIntersections[2];\n\
intersectFlippedCone(ray, u_ellipsoidRenderLatitudeSinMinMax.y, topConeIntersections);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 0, topConeIntersections[0]);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 1, topConeIntersections[1]);\n\
#elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF)\n\
RayShapeIntersection topConeIntersection = intersectZPlane(ray, 1.0);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX, topConeIntersection);\n\
#elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF)\n\
RayShapeIntersection topConeIntersection = intersectRegularCone(ray, u_ellipsoidRenderLatitudeSinMinMax.y, false);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX, topConeIntersection);\n\
#endif\n\
\n\
// Wedge\n\
#if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO)\n\
RayShapeIntersection wedgeIntersects[2];\n\
intersectHalfPlane(ray, u_ellipsoidRenderLongitudeMinMax.x, wedgeIntersects);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 0, wedgeIntersects[0]);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 1, wedgeIntersects[1]);\n\
#elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF)\n\
RayShapeIntersection wedgeIntersect = intersectRegularWedge(ray, u_ellipsoidRenderLongitudeMinMax);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE, wedgeIntersect);\n\
#elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF)\n\
RayShapeIntersection wedgeIntersects[2];\n\
intersectFlippedWedge(ray, u_ellipsoidRenderLongitudeMinMax, wedgeIntersects);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 0, wedgeIntersects[0]);\n\
setShapeIntersection(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 1, wedgeIntersects[1]);\n\
#endif\n\
}\n\
";
|