12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- attribute vec3 startEllipsoidNormal;
- attribute vec3 endEllipsoidNormal;
- attribute vec4 startPositionAndHeight;
- attribute vec4 endPositionAndHeight;
- attribute vec4 startFaceNormalAndVertexCorner;
- attribute vec4 endFaceNormalAndHalfWidth;
- attribute float a_batchId;
- uniform mat4 u_modifiedModelView;
- uniform vec2 u_minimumMaximumVectorHeights;
- varying vec4 v_startPlaneEC;
- varying vec4 v_endPlaneEC;
- varying vec4 v_rightPlaneEC;
- varying float v_halfWidth;
- varying vec3 v_volumeUpEC;
- void main()
- {
- // vertex corner IDs
- // 3-----------7
- // /| left /|
- // / | 1 / |
- // 2-----------6 5 end
- // | / | /
- // start |/ right |/
- // 0-----------4
- //
- float isEnd = floor(startFaceNormalAndVertexCorner.w * 0.251); // 0 for front, 1 for end
- float isTop = floor(startFaceNormalAndVertexCorner.w * mix(0.51, 0.19, isEnd)); // 0 for bottom, 1 for top
- vec3 forward = endPositionAndHeight.xyz - startPositionAndHeight.xyz;
- vec3 right = normalize(cross(forward, startEllipsoidNormal));
- vec4 position = vec4(startPositionAndHeight.xyz, 1.0);
- position.xyz += forward * isEnd;
- v_volumeUpEC = czm_normal * normalize(cross(right, forward));
- // Push for volume height
- float offset;
- vec3 ellipsoidNormal = mix(startEllipsoidNormal, endEllipsoidNormal, isEnd);
- // offset height to create volume
- offset = mix(startPositionAndHeight.w, endPositionAndHeight.w, isEnd);
- offset = mix(u_minimumMaximumVectorHeights.y, u_minimumMaximumVectorHeights.x, isTop) - offset;
- position.xyz += offset * ellipsoidNormal;
- // move from RTC to EC
- position = u_modifiedModelView * position;
- right = czm_normal * right;
- // Push for width in a direction that is in the start or end plane and in a plane with right
- // N = normalEC ("right-facing" direction for push)
- // R = right
- // p = angle between N and R
- // w = distance to push along R if R == N
- // d = distance to push along N
- //
- // N R
- // { \ p| } * cos(p) = dot(N, R) = w / d
- // d\ \ | |w * d = w / dot(N, R)
- // { \| }
- // o---------- polyline segment ---->
- //
- vec3 scratchNormal = mix(-startFaceNormalAndVertexCorner.xyz, endFaceNormalAndHalfWidth.xyz, isEnd);
- scratchNormal = cross(scratchNormal, mix(startEllipsoidNormal, endEllipsoidNormal, isEnd));
- vec3 miterPushNormal = czm_normal * normalize(scratchNormal);
- offset = 2.0 * endFaceNormalAndHalfWidth.w * max(0.0, czm_metersPerPixel(position)); // offset = widthEC
- offset = offset / dot(miterPushNormal, right);
- position.xyz += miterPushNormal * (offset * sign(0.5 - mod(startFaceNormalAndVertexCorner.w, 2.0)));
- gl_Position = czm_depthClamp(czm_projection * position);
- position = u_modifiedModelView * vec4(startPositionAndHeight.xyz, 1.0);
- vec3 startNormalEC = czm_normal * startFaceNormalAndVertexCorner.xyz;
- v_startPlaneEC = vec4(startNormalEC, -dot(startNormalEC, position.xyz));
- v_rightPlaneEC = vec4(right, -dot(right, position.xyz));
- position = u_modifiedModelView * vec4(endPositionAndHeight.xyz, 1.0);
- vec3 endNormalEC = czm_normal * endFaceNormalAndHalfWidth.xyz;
- v_endPlaneEC = vec4(endNormalEC, -dot(endNormalEC, position.xyz));
- v_halfWidth = endFaceNormalAndHalfWidth.w;
- }
|