vue-cesium
Version:
Vue 3.x components for CesiumJS.
159 lines (128 loc) • 5.67 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
"use strict";
const text = `
in vec2 st;
// it is not normal itself, but used to control lines drawing
in vec3 normal; // (point to use, offset sign, not used component)
uniform sampler2D previousParticlesPosition;
uniform sampler2D currentParticlesPosition;
uniform sampler2D postProcessingPosition;
uniform float particleHeight;
uniform float aspect;
uniform float pixelSize;
uniform float lineWidth;
struct adjacentPoints {
vec4 previous;
vec4 current;
vec4 next;
};
vec3 convertCoordinate(vec3 lonLatLev) {
// WGS84 (lon, lat, lev) -> ECEF (x, y, z)
// read https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#From_geodetic_to_ECEF_coordinates for detail
// WGS 84 geometric constants
float a = 6378137.0; // Semi-major axis
float b = 6356752.3142; // Semi-minor axis
float e2 = 6.69437999014e-3; // First eccentricity squared
float latitude = radians(lonLatLev.y);
float longitude = radians(lonLatLev.x);
float cosLat = cos(latitude);
float sinLat = sin(latitude);
float cosLon = cos(longitude);
float sinLon = sin(longitude);
float N_Phi = a / sqrt(1.0 - e2 * sinLat * sinLat);
float h = particleHeight; // it should be high enough otherwise the particle may not pass the terrain depth test
vec3 cartesian = vec3(0.0);
cartesian.x = (N_Phi + h) * cosLat * cosLon;
cartesian.y = (N_Phi + h) * cosLat * sinLon;
cartesian.z = ((b * b) / (a * a) * N_Phi + h) * sinLat;
return cartesian;
}
vec4 calculateProjectedCoordinate(vec3 lonLatLev) {
// the range of longitude in Cesium is [-180, 180] but the range of longitude in the NetCDF file is [0, 360]
// [0, 180] is corresponding to [0, 180] and [180, 360] is corresponding to [-180, 0]
lonLatLev.x = mod(lonLatLev.x + 180.0, 360.0) - 180.0;
vec3 particlePosition = convertCoordinate(lonLatLev);
vec4 projectedCoordinate = czm_modelViewProjection * vec4(particlePosition, 1.0);
return projectedCoordinate;
}
vec4 calculateOffsetOnNormalDirection(vec4 pointA, vec4 pointB, float offsetSign) {
vec2 aspectVec2 = vec2(aspect, 1.0);
vec2 pointA_XY = (pointA.xy / pointA.w) * aspectVec2;
vec2 pointB_XY = (pointB.xy / pointB.w) * aspectVec2;
float offsetLength = lineWidth / 2.0;
vec2 direction = normalize(pointB_XY - pointA_XY);
vec2 normalVector = vec2(-direction.y, direction.x);
normalVector.x = normalVector.x / aspect;
normalVector = offsetLength * normalVector;
vec4 offset = vec4(offsetSign * normalVector, 0.0, 0.0);
return offset;
}
vec4 calculateOffsetOnMiterDirection(adjacentPoints projectedCoordinates, float offsetSign) {
vec2 aspectVec2 = vec2(aspect, 1.0);
vec4 PointA = projectedCoordinates.previous;
vec4 PointB = projectedCoordinates.current;
vec4 PointC = projectedCoordinates.next;
vec2 pointA_XY = (PointA.xy / PointA.w) * aspectVec2;
vec2 pointB_XY = (PointB.xy / PointB.w) * aspectVec2;
vec2 pointC_XY = (PointC.xy / PointC.w) * aspectVec2;
vec2 AB = normalize(pointB_XY - pointA_XY);
vec2 BC = normalize(pointC_XY - pointB_XY);
vec2 normalA = vec2(-AB.y, AB.x);
vec2 tangent = normalize(AB + BC);
vec2 miter = vec2(-tangent.y, tangent.x);
float offsetLength = lineWidth / 2.0;
float projection = dot(miter, normalA);
vec4 offset = vec4(0.0);
// avoid to use values that are too small
if (projection > 0.1) {
float miterLength = offsetLength / projection;
offset = vec4(offsetSign * miter * miterLength, 0.0, 0.0);
offset.x = offset.x / aspect;
} else {
offset = calculateOffsetOnNormalDirection(PointB, PointC, offsetSign);
}
return offset;
}
void main() {
vec2 particleIndex = st;
vec3 previousPosition = texture(previousParticlesPosition, particleIndex).rgb;
vec3 currentPosition = texture(currentParticlesPosition, particleIndex).rgb;
vec3 nextPosition = texture(postProcessingPosition, particleIndex).rgb;
float isAnyRandomPointUsed = texture(postProcessingPosition, particleIndex).a +
texture(currentParticlesPosition, particleIndex).a +
texture(previousParticlesPosition, particleIndex).a;
adjacentPoints projectedCoordinates;
if (isAnyRandomPointUsed > 0.0) {
projectedCoordinates.previous = calculateProjectedCoordinate(previousPosition);
projectedCoordinates.current = projectedCoordinates.previous;
projectedCoordinates.next = projectedCoordinates.previous;
} else {
projectedCoordinates.previous = calculateProjectedCoordinate(previousPosition);
projectedCoordinates.current = calculateProjectedCoordinate(currentPosition);
projectedCoordinates.next = calculateProjectedCoordinate(nextPosition);
}
int pointToUse = int(normal.x);
float offsetSign = normal.y;
vec4 offset = vec4(0.0);
// render lines with triangles and miter joint
// read https://blog.scottlogic.com/2019/11/18/drawing-lines-with-webgl.html for detail
if (pointToUse == -1) {
offset = pixelSize * calculateOffsetOnNormalDirection(projectedCoordinates.previous, projectedCoordinates.current, offsetSign);
gl_Position = projectedCoordinates.previous + offset;
} else {
if (pointToUse == 0) {
offset = pixelSize * calculateOffsetOnMiterDirection(projectedCoordinates, offsetSign);
gl_Position = projectedCoordinates.current + offset;
} else {
if (pointToUse == 1) {
offset = pixelSize * calculateOffsetOnNormalDirection(projectedCoordinates.current, projectedCoordinates.next, offsetSign);
gl_Position = projectedCoordinates.next + offset;
} else {
}
}
}
}
`;
exports["default"] = text;
//# sourceMappingURL=segmentDraw.vert.js.map