PolylineCommon.glsl 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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 getPolylineWindowCoordinates(vec4 position, vec4 previous, vec4 next, float expandDirection, float width, bool usePrevious) {
  36. vec4 endPointWC, p0, p1;
  37. bool culledByNearPlane, clipped;
  38. vec4 positionEC = czm_modelViewRelativeToEye * position;
  39. vec4 prevEC = czm_modelViewRelativeToEye * previous;
  40. vec4 nextEC = czm_modelViewRelativeToEye * next;
  41. clipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, p0, clipped, culledByNearPlane);
  42. clipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, p1, clipped, culledByNearPlane);
  43. clipLineSegmentToNearPlane(positionEC.xyz, usePrevious ? prevEC.xyz : nextEC.xyz, endPointWC, clipped, culledByNearPlane);
  44. if (culledByNearPlane)
  45. {
  46. return vec4(0.0, 0.0, 0.0, 1.0);
  47. }
  48. vec2 prevWC = normalize(p0.xy - endPointWC.xy);
  49. vec2 nextWC = normalize(p1.xy - endPointWC.xy);
  50. float expandWidth = width * 0.5;
  51. vec2 direction;
  52. if (czm_equalsEpsilon(normalize(previous.xyz - position.xyz), vec3(0.0), czm_epsilon1) || czm_equalsEpsilon(prevWC, -nextWC, czm_epsilon1))
  53. {
  54. direction = vec2(-nextWC.y, nextWC.x);
  55. }
  56. else if (czm_equalsEpsilon(normalize(next.xyz - position.xyz), vec3(0.0), czm_epsilon1) || clipped)
  57. {
  58. direction = vec2(prevWC.y, -prevWC.x);
  59. }
  60. else
  61. {
  62. vec2 normal = vec2(-nextWC.y, nextWC.x);
  63. direction = normalize((nextWC + prevWC) * 0.5);
  64. if (dot(direction, normal) < 0.0)
  65. {
  66. direction = -direction;
  67. }
  68. // The sine of the angle between the two vectors is given by the formula
  69. // |a x b| = |a||b|sin(theta)
  70. // which is
  71. // float sinAngle = length(cross(vec3(direction, 0.0), vec3(nextWC, 0.0)));
  72. // Because the z components of both vectors are zero, the x and y coordinate will be zero.
  73. // Therefore, the sine of the angle is just the z component of the cross product.
  74. float sinAngle = abs(direction.x * nextWC.y - direction.y * nextWC.x);
  75. expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0);
  76. }
  77. vec2 offset = direction * expandDirection * expandWidth * czm_resolutionScale;
  78. return vec4(endPointWC.xy + offset, -endPointWC.z, 1.0);
  79. }