{"version":3,"file":"segmentDraw.vert.mjs","sources":["../../../../../../../packages/components/overlays/wind/glsl/segmentDraw.vert.ts"],"sourcesContent":["const text = `\nattribute vec2 st;\n// it is not normal itself, but used to control lines drawing\nattribute vec3 normal; // (point to use, offset sign, not used component)\n\nuniform sampler2D previousParticlesPosition;\nuniform sampler2D currentParticlesPosition;\nuniform sampler2D postProcessingPosition;\n\nuniform float particleHeight;\n\nuniform float aspect;\nuniform float pixelSize;\nuniform float lineWidth;\n\nstruct adjacentPoints {\n  vec4 previous;\n  vec4 current;\n  vec4 next;\n};\n\nvec3 convertCoordinate(vec3 lonLatLev) {\n  // WGS84 (lon, lat, lev) -> ECEF (x, y, z)\n  // read https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#From_geodetic_to_ECEF_coordinates for detail\n\n  // WGS 84 geometric constants\n  float a = 6378137.0; // Semi-major axis\n  float b = 6356752.3142; // Semi-minor axis\n  float e2 = 6.69437999014e-3; // First eccentricity squared\n\n  float latitude = radians(lonLatLev.y);\n  float longitude = radians(lonLatLev.x);\n\n  float cosLat = cos(latitude);\n  float sinLat = sin(latitude);\n  float cosLon = cos(longitude);\n  float sinLon = sin(longitude);\n\n  float N_Phi = a / sqrt(1.0 - e2 * sinLat * sinLat);\n  float h = particleHeight; // it should be high enough otherwise the particle may not pass the terrain depth test\n\n  vec3 cartesian = vec3(0.0);\n  cartesian.x = (N_Phi + h) * cosLat * cosLon;\n  cartesian.y = (N_Phi + h) * cosLat * sinLon;\n  cartesian.z = ((b * b) / (a * a) * N_Phi + h) * sinLat;\n  return cartesian;\n}\n\nvec4 calculateProjectedCoordinate(vec3 lonLatLev) {\n  // the range of longitude in Cesium is [-180, 180] but the range of longitude in the NetCDF file is [0, 360]\n  // [0, 180] is corresponding to [0, 180] and [180, 360] is corresponding to [-180, 0]\n  lonLatLev.x = mod(lonLatLev.x + 180.0, 360.0) - 180.0;\n  vec3 particlePosition = convertCoordinate(lonLatLev);\n  vec4 projectedCoordinate = czm_modelViewProjection * vec4(particlePosition, 1.0);\n  return projectedCoordinate;\n}\n\nvec4 calculateOffsetOnNormalDirection(vec4 pointA, vec4 pointB, float offsetSign) {\n  vec2 aspectVec2 = vec2(aspect, 1.0);\n  vec2 pointA_XY = (pointA.xy / pointA.w) * aspectVec2;\n  vec2 pointB_XY = (pointB.xy / pointB.w) * aspectVec2;\n\n  float offsetLength = lineWidth / 2.0;\n  vec2 direction = normalize(pointB_XY - pointA_XY);\n  vec2 normalVector = vec2(-direction.y, direction.x);\n  normalVector.x = normalVector.x / aspect;\n  normalVector = offsetLength * normalVector;\n\n  vec4 offset = vec4(offsetSign * normalVector, 0.0, 0.0);\n  return offset;\n}\n\nvec4 calculateOffsetOnMiterDirection(adjacentPoints projectedCoordinates, float offsetSign) {\n  vec2 aspectVec2 = vec2(aspect, 1.0);\n\n  vec4 PointA = projectedCoordinates.previous;\n  vec4 PointB = projectedCoordinates.current;\n  vec4 PointC = projectedCoordinates.next;\n\n  vec2 pointA_XY = (PointA.xy / PointA.w) * aspectVec2;\n  vec2 pointB_XY = (PointB.xy / PointB.w) * aspectVec2;\n  vec2 pointC_XY = (PointC.xy / PointC.w) * aspectVec2;\n\n  vec2 AB = normalize(pointB_XY - pointA_XY);\n  vec2 BC = normalize(pointC_XY - pointB_XY);\n\n  vec2 normalA = vec2(-AB.y, AB.x);\n  vec2 tangent = normalize(AB + BC);\n  vec2 miter = vec2(-tangent.y, tangent.x);\n\n  float offsetLength = lineWidth / 2.0;\n  float projection = dot(miter, normalA);\n  vec4 offset = vec4(0.0);\n  // avoid to use values that are too small\n  if (projection > 0.1) {\n    float miterLength = offsetLength / projection;\n    offset = vec4(offsetSign * miter * miterLength, 0.0, 0.0);\n    offset.x = offset.x / aspect;\n  } else {\n    offset = calculateOffsetOnNormalDirection(PointB, PointC, offsetSign);\n  }\n\n  return offset;\n}\n\nvoid main() {\n  vec2 particleIndex = st;\n\n  vec3 previousPosition = texture2D(previousParticlesPosition, particleIndex).rgb;\n  vec3 currentPosition = texture2D(currentParticlesPosition, particleIndex).rgb;\n  vec3 nextPosition = texture2D(postProcessingPosition, particleIndex).rgb;\n\n  float isAnyRandomPointUsed = texture2D(postProcessingPosition, particleIndex).a +\n    texture2D(currentParticlesPosition, particleIndex).a +\n    texture2D(previousParticlesPosition, particleIndex).a;\n\n  adjacentPoints projectedCoordinates;\n  if (isAnyRandomPointUsed > 0.0) {\n    projectedCoordinates.previous = calculateProjectedCoordinate(previousPosition);\n    projectedCoordinates.current = projectedCoordinates.previous;\n    projectedCoordinates.next = projectedCoordinates.previous;\n  } else {\n    projectedCoordinates.previous = calculateProjectedCoordinate(previousPosition);\n    projectedCoordinates.current = calculateProjectedCoordinate(currentPosition);\n    projectedCoordinates.next = calculateProjectedCoordinate(nextPosition);\n  }\n\n  int pointToUse = int(normal.x);\n  float offsetSign = normal.y;\n  vec4 offset = vec4(0.0);\n  // render lines with triangles and miter joint\n  // read https://blog.scottlogic.com/2019/11/18/drawing-lines-with-webgl.html for detail\n  if (pointToUse == -1) {\n    offset = pixelSize * calculateOffsetOnNormalDirection(projectedCoordinates.previous, projectedCoordinates.current, offsetSign);\n    gl_Position = projectedCoordinates.previous + offset;\n  } else {\n    if (pointToUse == 0) {\n      offset = pixelSize * calculateOffsetOnMiterDirection(projectedCoordinates, offsetSign);\n      gl_Position = projectedCoordinates.current + offset;\n    } else {\n      if (pointToUse == 1) {\n        offset = pixelSize * calculateOffsetOnNormalDirection(projectedCoordinates.current, projectedCoordinates.next, offsetSign);\n        gl_Position = projectedCoordinates.next + offset;\n      } else {\n\n      }\n    }\n  }\n}\n`\nexport default text\n"],"names":[],"mappings":"AAAK,MAAC,IAAI,GAAG,CAAC;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;"}