PolylineCommon.glsl 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. void clipLineSegmentToNearPlane(
  2. vec3 p0,
  3. vec3 p1,
  4. out vec4 positionWC,
  5. out bool clipped,
  6. out bool culledByNearPlane)
  7. {
  8. culledByNearPlane = false;
  9. clipped = false;
  10. vec3 p1ToP0 = p1 - p0;
  11. float magnitude = length(p1ToP0);
  12. vec3 direction = normalize(p1ToP0);
  13. float endPoint0Distance = -(czm_currentFrustum.x + p0.z);
  14. float denominator = -direction.z;
  15. if (endPoint0Distance < 0.0 && abs(denominator) < czm_epsilon7)
  16. {
  17. culledByNearPlane = true;
  18. }
  19. else if (endPoint0Distance < 0.0 && abs(denominator) > czm_epsilon7)
  20. {
  21. // t = (-plane distance - dot(plane normal, ray origin)) / dot(plane normal, ray direction)
  22. float t = (czm_currentFrustum.x + p0.z) / denominator;
  23. if (t < 0.0 || t > magnitude)
  24. {
  25. culledByNearPlane = true;
  26. }
  27. else
  28. {
  29. p0 = p0 + t * direction;
  30. clipped = true;
  31. }
  32. }
  33. positionWC = czm_eyeToWindowCoordinates(vec4(p0, 1.0));
  34. }
  35. vec4 getPolylineWindowCoordinatesEC(vec4 positionEC, vec4 prevEC, vec4 nextEC, float expandDirection, float width, bool usePrevious, out float angle)
  36. {
  37. vec4 endPointWC, p0, p1;
  38. bool culledByNearPlane, clipped;
  39. #ifdef POLYLINE_DASH
  40. // Compute the window coordinates of the points.
  41. vec4 positionWindow = czm_eyeToWindowCoordinates(positionEC);
  42. vec4 previousWindow = czm_eyeToWindowCoordinates(prevEC);
  43. vec4 nextWindow = czm_eyeToWindowCoordinates(nextEC);
  44. // Determine the relative screen space direction of the line.
  45. vec2 lineDir;
  46. if (usePrevious) {
  47. lineDir = normalize(positionWindow.xy - previousWindow.xy);
  48. }
  49. else {
  50. lineDir = normalize(nextWindow.xy - positionWindow.xy);
  51. }
  52. angle = atan(lineDir.x, lineDir.y) - 1.570796327; // precomputed atan(1,0)
  53. // Quantize the angle so it doesn't change rapidly between segments.
  54. angle = floor(angle / czm_piOverFour + 0.5) * czm_piOverFour;
  55. #endif
  56. clipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, p0, clipped, culledByNearPlane);
  57. clipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, p1, clipped, culledByNearPlane);
  58. clipLineSegmentToNearPlane(positionEC.xyz, usePrevious ? prevEC.xyz : nextEC.xyz, endPointWC, clipped, culledByNearPlane);
  59. if (culledByNearPlane)
  60. {
  61. return vec4(0.0, 0.0, 0.0, 1.0);
  62. }
  63. vec2 prevWC = normalize(p0.xy - endPointWC.xy);
  64. vec2 nextWC = normalize(p1.xy - endPointWC.xy);
  65. float expandWidth = width * 0.5;
  66. vec2 direction;
  67. #ifdef CLIP_POLYLINE
  68. if (clipped)
  69. {
  70. if (prevEC.z - positionEC.z < 0.0)
  71. {
  72. direction = vec2(prevWC.y, -prevWC.x);
  73. }
  74. else
  75. {
  76. direction = vec2(-prevWC.y, prevWC.x);
  77. }
  78. }
  79. else
  80. #endif
  81. if (czm_equalsEpsilon(prevEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1) || czm_equalsEpsilon(prevWC, -nextWC, czm_epsilon1))
  82. {
  83. direction = vec2(-nextWC.y, nextWC.x);
  84. }
  85. else if (czm_equalsEpsilon(nextEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1))
  86. {
  87. direction = vec2(prevWC.y, -prevWC.x);
  88. }
  89. else
  90. {
  91. vec2 normal = vec2(-nextWC.y, nextWC.x);
  92. direction = normalize((nextWC + prevWC) * 0.5);
  93. if (dot(direction, normal) < 0.0)
  94. {
  95. direction = -direction;
  96. }
  97. // The sine of the angle between the two vectors is given by the formula
  98. // |a x b| = |a||b|sin(theta)
  99. // which is
  100. // float sinAngle = length(cross(vec3(direction, 0.0), vec3(nextWC, 0.0)));
  101. // Because the z components of both vectors are zero, the x and y coordinate will be zero.
  102. // Therefore, the sine of the angle is just the z component of the cross product.
  103. float sinAngle = abs(direction.x * nextWC.y - direction.y * nextWC.x);
  104. expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0);
  105. }
  106. vec2 offset = direction * expandDirection * expandWidth * czm_pixelRatio;
  107. return vec4(endPointWC.xy + offset, -endPointWC.z, 1.0);
  108. }
  109. vec4 getPolylineWindowCoordinates(vec4 position, vec4 previous, vec4 next, float expandDirection, float width, bool usePrevious, out float angle)
  110. {
  111. vec4 positionEC = czm_modelViewRelativeToEye * position;
  112. vec4 prevEC = czm_modelViewRelativeToEye * previous;
  113. vec4 nextEC = czm_modelViewRelativeToEye * next;
  114. return getPolylineWindowCoordinatesEC(positionEC, prevEC, nextEC, expandDirection, width, usePrevious, angle);
  115. }