Files
pymol-open-source/data/shaders/connector.shared
2018-07-03 20:19:12 +02:00

181 lines
8.7 KiB
Plaintext

#include webgl_header.vs
/* computeConnectorOffset : this function takes the drawVector and returns the offset of the
* endpoint for the connector in the label's bbx coordinates
*/
//computeFinalCornerOrCenterOffset
vec2 computeConnectorOffset_0(vec2 drawVector){
// this puts the endpoint at either the corners of the label, or in the center, based on the target relative to the label.
// if target is closer than half label size, set to midpoint (in both directions)
float hmid = step(abs(drawVector.x), .5);
float vmid = step(abs(drawVector.y), .5);
// if not midpoint (hmid=0., vmid=0.),
// set these variables to which side to draw based on the draw vector (in both directions)
float right = (1.-hmid) * step(0., drawVector.x) + hmid * .5;
float top = (1.-vmid) * step(0., drawVector.y) + vmid * .5;
// normalize the offsets (either -1 or 1)
float xoff = 2. * (right - .5), yoff = 2. * (top - .5);
return vec2(xoff, yoff);
}
//computeFinalBBXOffset
vec2 computeConnectorOffset_1(vec2 drawVector){
vec2 drawVectorN = normalize(drawVector);
// \ notabsyx /
// \ /
// \ /
// absyx \ absyx
// / \
// / notabsyx \
// absyx/notabsyx - specifies which area above in label coordinates
float absyx = step(abs(drawVectorN.y), abs(drawVectorN.x));
float notabsyx = 1. - absyx;
// hdir/vdir : specifies which direction (in both axes), (-.5 or .5)
float hdir = 2. * (step(0., drawVectorN.x) - .5);
float vdir = 2. * (step(0., drawVectorN.y) - .5);
float dvxy = drawVector.x / drawVector.y;
float dvyx = drawVector.y / drawVector.x;
// depending on which quadrant, the connector point is calculated
return vec2(((absyx * hdir) + (notabsyx * vdir * dvxy)),
((notabsyx * vdir) + (absyx * hdir * dvyx)));
}
vec2 computeConnectorOffset_2(vec2 drawVector, out vec2 eoff, vec2 textSize, float extLength){
// this puts the endpoint at either the corners of the label, or in the center, based on the target relative to the label.
// set these variables to which side to draw based on the draw vector (in both directions)
float rightorig = step(0., drawVector.x);
float ratio = abs(textSize.y/textSize.x);
float right = rightorig + (rightorig - .5) * clamp(abs(drawVector.x)-1., 0., 2. * min(1., extLength * ratio));
float top = step(0., drawVector.y);
// normalize the offsets (either -1 or 1)
float xofforig = 2. * (rightorig - .5), xoff = 2. * (right - .5), yoff = 2. * (top - .5);
eoff = vec2(xoff, yoff);
return vec2(xofforig, yoff);
}
vec2 computeConnectorOffset_3(vec2 drawVector){
// this puts the endpoint at either the corners of the label, or in the center, based on the target relative to the label.
// if target is inside label size, then set to drawVector value
float hmid = step(abs(drawVector.x), 1.);
float vmid = step(abs(drawVector.y), 1.);
// if not midpoint (hmid=0., vmid=0.),
// set these variables to which side to draw based on the draw vector (in both directions)
float right = (1.-hmid) * step(0., drawVector.x) + hmid * ((1. + drawVector.x) / 2.);
float top = (1.-vmid) * step(0., drawVector.y) + vmid * ((1. + drawVector.y) / 2.);
// normalize the offsets (either -1 or 1)
float xoff = 2. * (right - .5), yoff = 2. * (top - .5);
return vec2(xoff, yoff);
}
vec2 computeConnectorOffset_4(vec2 drawVector, out vec2 eoff, vec2 textSize, float extLength){
// this puts the endpoint at either the corners of the label, or in the center, based on the target relative to the label.
// set these variables to which side to draw based on the draw vector (in both directions)
float hmid = step(abs(drawVector.x), 1.);
float vmid = step(abs(drawVector.y), 1.);
float rightorig = (1.-hmid) * step(0., drawVector.x) + hmid * ((1. + drawVector.x) / 2.);
float ratio = abs(textSize.y/textSize.x);
float right = rightorig + (1.-hmid) * (rightorig - .5) * clamp(abs(drawVector.x)-1., 0., 2. * min(1., extLength * ratio));
float top = (1.-vmid) * step(0., drawVector.y) +
vmid * ((1. + drawVector.y) / 2.);
// normalize the offsets (either -1 or 1)
float xofforig = 2. * (rightorig - .5), xoff = 2. * (right - .5), yoff = 2. * (top - .5);
eoff = vec2(xoff, yoff);
return vec2(xofforig, yoff);
}
vec2 computeCenterOffsetFromProjectedPoint(vec2 indentFactor, vec2 textSizeInScreen, vec2 screenWorldOffset){
return (indentFactor * textSizeInScreen + screenWorldOffset/(screenSize*screenOriginVertexScale));
}
vec4 normalizeVec4(vec4 point){
vec4 retPt = vec4(point.xyz/point.w, 1.);
retPt.xy = ( floor(retPt.xy * screenSize + .5 ) + .5 ) / screenSize; // to match label rounding to middle of pixel
return retPt;
}
float convertNormalZToScreenZ(float normalz){
float a_centerN = (normalz + 1.) / 2.;
float ptInPreProjectionZ = -(front + clipRange * a_centerN);
vec4 ptInPreProjection = vec4(0., 0., ptInPreProjectionZ, 1.);
vec4 projVect = g_ProjectionMatrix * ptInPreProjection;
return projVect.z / projVect.w;
}
void calculatePreConnectorInfo(vec4 a_center, vec4 a_target, vec2 textSize, vec2 indentFactor, vec3 screenWorldOffset, out vec4 tCenter, out vec4 tTarget, out vec2 tsScreen, out vec2 offset, out vec2 dVector, out float doNotDraw, float a_relative_mode, out float isProjected, out float zValue, in float lineWidth, out float zTarget){
vec3 viewVector = vec3(vec4(0., 0., -1., 0.) * g_ModelViewMatrix);
tCenter = normalizeVec4(g_ProjectionMatrix * g_ModelViewMatrix * a_center);
tTarget = normalizeVec4(g_ProjectionMatrix * g_ModelViewMatrix * a_target);
vec4 a_centerp = (a_center + screenWorldOffset.z * vec4(viewVector, 0.));
vec4 transformedPositionZ = normalizeVec4(g_ProjectionMatrix * g_ModelViewMatrix * a_centerp); // use projected center point for z
float isScreenCoord = step(2., mod(a_relative_mode, 4.));
float isPixelCoord = step(4., mod(a_relative_mode, 8.));
isProjected = step(isPixelCoord + isScreenCoord, 0.5);
zTarget = step(8., mod(a_relative_mode, 16.));
zValue = (1.-zTarget) * ((isProjected * transformedPositionZ.z) + (1.-isProjected) * convertNormalZToScreenZ(a_center.z) ) + zTarget * tTarget.z;
// workaround for label and label_bg being at same z
zValue += 1e-4;
vec2 pixOffset = ((2. * a_center.xy / screenSize) - 1.);
tCenter = isProjected * tCenter + isScreenCoord * a_center + isPixelCoord * vec4(pixOffset.x, pixOffset.y, -0.5, 0.); // only xy are used from tCenter
tCenter.w = 1.;
tsScreen = textSize / screenSize;
offset = computeCenterOffsetFromProjectedPoint(indentFactor, tsScreen, screenWorldOffset.xy);
dVector = (tTarget.xy - tCenter.xy - offset) / tsScreen;
vec2 limit = 1.0 + .5 * lineWidth/textSize;
doNotDraw = (1.-step(limit.x, abs(dVector.x))) * (1.-step(limit.y, abs(dVector.y)));
}
void getDrawFlags(float drawFlags, out float connector_mode_0, out float connector_mode_1, out float connector_mode_2, out float connector_mode_3, out float connector_mode_4, out float drawBackgroundOutline, out float drawBackground, out float drawConnector){
connector_mode_4 = step(64., mod(drawFlags, 128.));
connector_mode_3 = step(32., mod(drawFlags, 64.));
connector_mode_2 = step(16., mod(drawFlags, 32.));
connector_mode_1 = step(8., mod(drawFlags, 16.));
drawBackgroundOutline = step(4., mod(drawFlags, 8.));
drawBackground = step(2., mod(drawFlags, 4.));
drawConnector = step(1., mod(drawFlags, 2.));
connector_mode_0 = 1. - step(0.5, connector_mode_1 + connector_mode_2 + connector_mode_3 + connector_mode_4);
}
void calculateConnectorInfo(vec4 a_center, vec2 tsScreen, vec2 textSize, vec2 dVector, vec2 offset, out float fog, in vec4 tCenter, in vec4 tTarget, out vec4 endpointOnBBX, out vec4 endpointExtendedOffBBX, float connector_mode_0, float connector_mode_1, float connector_mode_2, float connector_mode_3, float connector_mode_4, float extLength, float isProjected, float zValue){
vec3 eye_pos = vec3(isProjected * (g_ModelViewMatrix * a_center) + ((1.-isProjected) * a_center));
fog = (g_Fog_end - abs(eye_pos.z)) * g_Fog_scale;
vec2 eoff;
vec2 conOff;
if (connector_mode_0 > 0.)
conOff = computeConnectorOffset_0(dVector);
else if (connector_mode_1 > 0.)
conOff = computeConnectorOffset_1(dVector);
else if (connector_mode_2 > 0.)
conOff = computeConnectorOffset_2(dVector, eoff, textSize, extLength);
else if (connector_mode_3 > 0.)
conOff = computeConnectorOffset_3(dVector);
else if (connector_mode_4 > 0.)
conOff = computeConnectorOffset_4(dVector, eoff, textSize, extLength);
vec2 addXY = offset + tsScreen * conOff;
endpointOnBBX = tCenter;
endpointOnBBX.xy = endpointOnBBX.xy + addXY;
endpointOnBBX.z = zValue;
endpointExtendedOffBBX = tCenter;
endpointExtendedOffBBX.xy = endpointExtendedOffBBX.xy + offset + tsScreen * eoff;
endpointExtendedOffBBX.z = zValue;
}