File: connector.gs

package info (click to toggle)
pymol 2.4.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 43,312 kB
  • sloc: cpp: 480,106; python: 79,860; ansic: 28,343; javascript: 6,792; sh: 47; makefile: 30; csh: 8
file content (387 lines) | stat: -rw-r--r-- 15,162 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
#version 120
#extension GL_EXT_geometry_shader4 : require
#extension GL_EXT_gpu_shader4 : require

varying out vec3 NORMAL ;
varying out vec4 COLOR ;
varying out float fog;
varying out vec2 bgTextureLookup;
varying out float lineEdge;
varying out float aaCutoff;

varying in vec4 a_center[];
varying in vec4 a_target[];
varying in vec4 COLORIn[];
varying in vec2 a_textSizeIn[];
varying in vec3 a_screenWorldOffsetIn[];
varying in vec2 a_indentFactorIn[];
varying in float a_relative_modeIn[];
varying in float a_draw_flagsIn[];
varying in vec4 a_bkgrd_colorIn[];
varying in float a_rel_ext_lengthIn[];
varying in float a_con_widthIn[];

uniform vec2 screenSize;
uniform float screenOriginVertexScale;
uniform float antialiasedLines;
uniform float textureToLabelSize;
uniform float front;
uniform float clipRange;

float PI = 3.14159265358979323846264;

float mysmoothstep(float edge0, float edge1, float x){
  float rets = step(edge0, edge1) * step(edge1, edge0);
  return rets * step(edge0, x) + (1.-rets) * smoothstep(edge0, edge1, x);
}

#include connector.shared

struct lineSeg_t {
  vec2 p1;
  vec2 p2;
};
bool lineSegIntersection(vec2 p1,  vec2 p2, vec2 p3, vec2 p4, out vec2 po) {
	float  distAB, theCos, theSin, newX, abpos;
	vec2 p2i, p3i, p4i;
	if ((p1.x==p2.x && p1.y==p2.y) || (p3.x==p4.x && p3.y==p4.y)) return false;
	if ((p1.x==p3.x && p1.y==p3.y) || (p2.x==p3.x && p2.y==p3.y)
	||  (p1.x==p4.x && p1.y==p4.y) || (p2.x==p4.x && p2.y==p4.y)) {
	return false; }
	p2i.x = p2.x; p2i.y = p2.y;
	p3i.x = p3.x; p3i.y = p3.y;
	p4i.x = p4.x; p4i.y = p4.y;
	p2i.x -= p1.x; p2i.y -= p1.y;
	p3i.x -= p1.x; p3i.y -= p1.y;
	p4i.x -= p1.x; p4i.y -= p1.y;
	distAB = sqrt(p2i.x * p2i.x + p2i.y * p2i.y);
	theCos = p2i.x / distAB;
	theSin = p2i.y / distAB;
	newX = p3i.x * theCos + p3i.y * theSin;
	p3i.y = p3i.y * theCos - p3i.x * theSin;
	p3i.x = newX;
	newX = p4i.x * theCos + p4i.y * theSin;
	p4i.y = p4i.y * theCos - p4i.x * theSin;
	p4i.x = newX;
	if ((p3i.y < 0. && p4i.y<0.) || (p3i.y >= 0. && p4i.y >= 0.)) return false;
	abpos = p4i.x + (p3i.x - p4i.x) * p4i.y / (p4i.y - p3i.y);
	if (abpos<0. || abpos>distAB) return false;
	po.x = p1.x + abpos * theCos;
	po.y = p1.y + abpos * theSin;
	return true;
}

void setBG(){
	bgTextureLookup = (gl_Position.xy/gl_Position.w) / 2.0 + 0.5;
}

void drawLineAsGeometryClipped(vec4 pt1, vec4 pt2, lineSeg_t labelTop, lineSeg_t labelBottom, lineSeg_t labelLeft, lineSeg_t labelRight, out vec2 dirv, float lineWidth, float aa){
	vec4 pt1E = pt1;
	vec4 pt2E = pt2;
	pt1E.xy = floor(pt1.xy * screenSize) / screenSize;
	pt2E.xy = floor(pt2.xy * screenSize) / screenSize;
	vec3 diffV = pt1E.xyz - pt2E.xyz;
	vec2 dirvPnorm = vec2(normalize(cross(diffV, vec3(0.,0.,1.))).xy);
	vec2 dirvP = lineWidth*dirvPnorm;
	dirv = dirvP/screenSize;
        int l1V = 0 , l2V = 0;
        lineSeg_t l1, l2;
        vec2 isec1, isec2;
        l1.p1 = pt1.xy + dirv;
        l1.p2 = pt2.xy + dirv;
        l2.p1 = pt1.xy - dirv;
        l2.p2 = pt2.xy - dirv;

        if (lineSegIntersection(labelTop.p1, labelTop.p2, l1.p1, l1.p2, isec1)) {
              l1V = 1;
        } else if (lineSegIntersection(labelRight.p1, labelRight.p2, l1.p1, l1.p2, isec1)) {
              l1V = 2;
        } else if (lineSegIntersection(labelBottom.p1, labelBottom.p2, l1.p1, l1.p2, isec1)) {
              l1V = 3;
        } else if (lineSegIntersection(labelLeft.p1, labelLeft.p2, l1.p1, l1.p2, isec1)) {
              l1V = 4;
        } 

        if (lineSegIntersection(labelTop.p1, labelTop.p2, l2.p1, l2.p2, isec2)) {
              l2V = 1;
        } else if (lineSegIntersection(labelRight.p1, labelRight.p2, l2.p1, l2.p2, isec2)) {
              l2V = 2;
        } else if (lineSegIntersection(labelBottom.p1, labelBottom.p2, l2.p1, l2.p2, isec2)) {
              l2V = 3;
        } else if (lineSegIntersection(labelLeft.p1, labelLeft.p2, l2.p1, l2.p2, isec2)) {
              l2V = 4;
        } 

        // Both lines run through one side
        if ( (l1V > 0 && l2V > 0) && (l1V == l2V) ) {
              pt1E.xy = pt1.xy + dirv; pt1E.z = pt1.z;
              gl_Position = pt1E;
              lineEdge = 1.; aaCutoff = aa;
              setBG(); EmitVertex();

              pt1E.xy = pt1.xy - dirv; pt1E.z = pt1.z;
              gl_Position = pt1E;
              lineEdge = -1.;
              setBG(); EmitVertex();
              
              pt2E.xy = isec1;  pt2E.z = pt2.z;
              gl_Position = pt2E;
              lineEdge = 1.;
              setBG(); EmitVertex();

              pt2E.xy = isec2;  pt2E.z = pt2.z;
              gl_Position = pt2E;
              lineEdge = -1.;
              setBG(); EmitVertex();
              EndPrimitive();
              lineEdge = 0.;
              aaCutoff = 0.; 

        } else if ( (l1V > 0 && l2V > 0) && (l1V != l2V) ) { // Find the corner 
              vec2 isecc;
              if ( (l1V == 1 && l2V == 2) || (l1V == 2 && l2V == 1) ) { // UR
                      isecc = labelTop.p1;
              } else if ( (l1V == 2 && l2V == 3) || (l1V == 3 && l2V == 2) ) { // LR
                      isecc = labelBottom.p2;
              } else if ( (l1V == 3 && l2V == 4) || (l1V == 4 && l2V == 3) ) { // LL
                      isecc = labelBottom.p1;
              } else if ( (l1V == 4 && l2V == 1) || (l1V == 1 && l2V == 4) ) { // UL
                      isecc = labelTop.p2;
              }
              
              pt2E.xy = isec1.xy; pt2E.z = pt2.z;
              gl_Position = pt2E;
              lineEdge = 1.; aaCutoff = aa;
              setBG(); EmitVertex();

              pt1E.xy = pt1.xy + dirv; pt1E.z = pt1.z;
              gl_Position = pt1E;
              lineEdge = 1.;
              setBG(); EmitVertex();

              pt2E.xy = isecc.xy; pt2E.z = pt2.z;
              gl_Position = pt2E;


              /* since we are adding a corner vertex, we also need to 
                 account for anti-aliasing by setting lineEdge for that 
                 vertex. */              
              float len1 = length(screenSize* (isecc.xy - isec1.xy)); // length between corner and first intersection
              float len2 = length(screenSize* (isecc.xy - isec2.xy)); // length between corner and second intersection
              float lenc = length(screenSize* (isec2.xy - isec1.xy)); // length between intersections, i.e., line width
              float ang = atan(len2 / len1);  // angle between perpendicular vector and first edge
              float n2 = sin(ang) * len2;     // second edge projected onto perpendicular vector
              float lenr = (n2 / lenc) * 2. - 1.;  // figure out ratio and normalize it between -1 and 1
              float lenrsign = 2. * (step(0., lenr) - .5);  // sign for lenr used below
              lineEdge = lenrsign * (1. - mysmoothstep(0., aa, 1 - abs(lenr))); // take into account aa for corner vertex lineEdge

              setBG(); EmitVertex();

              pt1E.xy = pt1.xy - dirv; pt1E.z = pt1.z;
              gl_Position = pt1E;
              lineEdge = -1.;
              setBG(); EmitVertex();

              pt2E.xy = isec2.xy; pt2E.z = pt2.z;
              gl_Position = pt2E;
              lineEdge = -1.;
              setBG(); EmitVertex();
              EndPrimitive();
              
         
        } 
}

void drawLineAsGeometry(vec4 pt1, vec4 pt2, out vec2 dirv, float lineWidth, float aa){
	vec4 pt1E = pt1;
	vec4 pt2E = pt2;
	pt1E.xy = floor(pt1.xy * screenSize) / screenSize;
	pt2E.xy = floor(pt2.xy * screenSize) / screenSize;
	vec3 diffV = pt1E.xyz - pt2E.xyz;
	vec2 dirvPnorm = vec2(normalize(cross(diffV, vec3(0.,0.,1.))).xy);
	vec2 dirvP = lineWidth*dirvPnorm;
	dirv = dirvP/screenSize;

	pt1E.xy = pt1.xy + dirv;
	gl_Position = pt1E;
	lineEdge = -1.; aaCutoff = aa;
	setBG(); EmitVertex();

	pt2E.xy = pt2.xy + dirv;
	gl_Position = pt2E;
	lineEdge = -1.;
	setBG(); EmitVertex();

	pt1E.xy = pt1.xy - dirv;
	gl_Position = pt1E;
	lineEdge = 1.;
	setBG(); EmitVertex();

	pt2E.xy = pt2.xy - dirv;
	gl_Position = pt2E;
	lineEdge = 1.;
	setBG(); EmitVertex();
	EndPrimitive();
	lineEdge = 0.;
	aaCutoff = 0.; 
}

void drawLineAsGeometryWithOffsets(vec4 pt1, vec4 pt2, float topext, float bottomext){
	vec4 pt1E = pt1;
	vec4 pt2E = pt2;
	vec3 diffV = pt1E.xyz - pt2E.xyz;
	vec2 linev = vec2(a_con_widthIn[0] * normalize(diffV).xy) / screenSize;
	vec2 dirv = vec2((a_con_widthIn[0]*normalize(cross(diffV, vec3(0.,0.,1.)).xy)))/screenSize;
	pt1E.xy = pt1.xy + dirv + topext * linev;
	gl_Position = pt1E;
	setBG(); EmitVertex();

	pt2E.xy = pt2.xy + dirv - topext * linev;
	gl_Position = pt2E;
	setBG(); EmitVertex();

	pt1E.xy = pt1.xy - dirv + bottomext * linev;
	gl_Position = pt1E;
	setBG(); EmitVertex();

	pt2E.xy = pt2.xy - dirv - bottomext * linev;
	gl_Position = pt2E;
	setBG(); EmitVertex();
	EndPrimitive();
}

void main()
{
	vec4 transformedCenter, transformedTarget;
	vec2 textSizeInScreen, offset, drawVector;
	float doNotDraw;
	float connector_mode_0, connector_mode_1, connector_mode_2, connector_mode_3, connector_mode_4, connector_mode_2_4, drawBackgroundOutline, drawBackground, drawConnector, isProjected, zValue, zTarget;
	lineEdge = 0.;
	aaCutoff = 0.;
	getDrawFlags(a_draw_flagsIn[0], connector_mode_0, connector_mode_1, connector_mode_2, connector_mode_3, connector_mode_4, drawBackgroundOutline, drawBackground, drawConnector);

	float negLabelSize = step(textureToLabelSize, 0.);
	float textureToLabelSizeA = abs(textureToLabelSize);
	float extLength = (1.-negLabelSize) * a_rel_ext_lengthIn[0] + negLabelSize * (-a_rel_ext_lengthIn[0]/(screenOriginVertexScale*2.) );
	vec2 textSize = a_textSizeIn[0] / textureToLabelSizeA;
	connector_mode_2_4 = connector_mode_2 + connector_mode_4;
	calculatePreConnectorInfo(a_center[0], a_target[0], textSize, a_indentFactorIn[0], a_screenWorldOffsetIn[0], transformedCenter, transformedTarget, textSizeInScreen, offset, drawVector, doNotDraw, a_relative_modeIn[0], isProjected, zValue, a_con_widthIn[0], zTarget);
	vec4 endpointOnBBX, endpointExtendedOffBBX;
	calculateConnectorInfo(a_center[0], textSizeInScreen, textSize, drawVector, offset, fog, transformedCenter, transformedTarget, endpointOnBBX, endpointExtendedOffBBX, connector_mode_0, connector_mode_1, connector_mode_2, connector_mode_3, connector_mode_4, extLength, isProjected, zValue);
	NORMAL = vec3(0.,0.,1.);

        // if the zValue is not within the clipping planes, then set the transformedTarget z
        // to the zValue as well, to make sure that the connector doesn't get drawn
        float withinView = step(zValue, 1.) * step(-1., zValue);
        float ttz = (1.-zTarget) * (1.-isProjected); // not zTarget and not projected, then keep same, otherwise zValue
        transformedTarget.z =  ttz * transformedTarget.z + (1.-ttz) * zValue;

	vec4 transformedPosition3 = transformedCenter;
	transformedPosition3.xy += offset;
	transformedPosition3.z = zValue;
	// bbx of the label
	vec4 upperLeft = transformedPosition3;
	upperLeft.xy += textSizeInScreen * vec2(-1.,1.);
	vec4 upperRight = transformedPosition3;
	upperRight.xy += textSizeInScreen * vec2(1.,1.);
	vec4 lowerLeft = transformedPosition3;
	lowerLeft.xy +=  textSizeInScreen * vec2(-1.,-1.);
	vec4 lowerRight = transformedPosition3;
	lowerRight.xy += textSizeInScreen * vec2(1.,-1.);

        lineSeg_t labelTop, labelBottom, labelLeft, labelRight;

        labelTop.p1 = upperRight.xy;
        labelTop.p2 = upperLeft.xy;
        labelBottom.p1 = lowerLeft.xy;
        labelBottom.p2 = lowerRight.xy;
        labelRight.p1 = upperRight.xy;
        labelRight.p2 = lowerRight.xy;
        labelLeft.p1 = upperLeft.xy;
        labelLeft.p2 = lowerLeft.xy;

	if (drawBackgroundOutline + drawBackground > 0.){
		if (drawBackground > 0.){
                   if (drawBackgroundOutline > 0.){
			vec2 lineWidth = a_con_widthIn[0] / (screenSize);
			vec4 upperLeftM = upperLeft + vec4(lineWidth.x, -lineWidth.y, 0., 0.),
			upperRightM = upperRight + vec4(-lineWidth.x, -lineWidth.y, 0., 0.),
			lowerLeftM = lowerLeft + vec4(lineWidth.x, lineWidth.y, 0., 0.),
			lowerRightM = lowerRight + vec4(-lineWidth.x, lineWidth.y, 0., 0.);

			COLOR = a_bkgrd_colorIn[0];
			gl_Position = upperLeftM; setBG(); EmitVertex();
			gl_Position = upperRightM; setBG(); EmitVertex();
			gl_Position = lowerLeftM;  setBG(); EmitVertex();
			gl_Position = lowerRightM; setBG(); EmitVertex();
			EndPrimitive();
                   } else {
			COLOR = a_bkgrd_colorIn[0];
			gl_Position = upperLeft; setBG(); EmitVertex();
			gl_Position = upperRight; setBG(); EmitVertex();
			gl_Position = lowerLeft;  setBG(); EmitVertex();
			gl_Position = lowerRight; setBG(); EmitVertex();
			EndPrimitive();
                   }
		}
		if (drawBackgroundOutline > 0.){
			COLOR = COLORIn[0];
			drawLineAsGeometryWithOffsets(upperLeft, upperRight, 1., 0.);
			drawLineAsGeometryWithOffsets(lowerRight, upperRight, 0., 1.);
			drawLineAsGeometryWithOffsets(lowerLeft, lowerRight, 0., 1.);
			drawLineAsGeometryWithOffsets(lowerLeft, upperLeft, 1., 0.);
		}
	}
	if (drawConnector > 0 && doNotDraw == 0.){
		COLOR = COLORIn[0];
		float aa = min(1., 2./a_con_widthIn[0]);
		float widthAdjustment = aa * a_con_widthIn[0];
		float adjLineWidth = antialiasedLines * widthAdjustment + a_con_widthIn[0];
		if (connector_mode_2_4 > 0.){
			// create 2 lines, between transformedTarget -> endpointExtendedOffBBX, and endpointExtendedOffBBX -> endpointOnBBX
			vec2 dirv1, dirv2;
			drawLineAsGeometry(endpointExtendedOffBBX, endpointOnBBX, dirv2, a_con_widthIn[0], 0);
			drawLineAsGeometry(transformedTarget, endpointExtendedOffBBX, dirv1, adjLineWidth, aa);
			float norder = step(0., cross(vec3(dirv1.x, dirv1.y, 0.), vec3(dirv2.x, dirv2.y, 0.)).z);
			// need to draw 'fan' that creates a curved elbow between the lines

			lineEdge = 0.; aaCutoff = 0.;
			gl_Position = endpointExtendedOffBBX;
			setBG(); EmitVertex();
			lineEdge = -1.; aaCutoff = aa;
			if (norder < .5){
				vec4 pt = endpointExtendedOffBBX;
				pt.xy = endpointExtendedOffBBX.xy + dirv1;
				gl_Position = pt;
				setBG(); EmitVertex();
				pt.xy = endpointExtendedOffBBX.xy + dirv2;
				gl_Position = pt;
				aaCutoff = 0.;
				setBG(); EmitVertex();
			} else {
				vec4 pt = endpointExtendedOffBBX;
				pt.xy = endpointExtendedOffBBX.xy - dirv2;
				gl_Position = pt;
				aaCutoff = 0.;
				setBG(); EmitVertex();
				pt.xy = endpointExtendedOffBBX.xy - dirv1;
				gl_Position = pt;
				aaCutoff = aa;
				setBG(); EmitVertex();
			}
			EndPrimitive();
			lineEdge = 0.; aaCutoff = 0.;
		} else if (connector_mode_1 > 0. && drawBackground > 0.){
			// create 1 lines, between transformedTarget -> endpointOnBBX
			// replace endpointOnBBX with midpoint of midpoints 
			vec4 midULUR = (upperLeft + upperRight) / 2.0;
			vec4 midLLLR = (lowerLeft + lowerRight) / 2.0;
			vec4 midMid = (midULUR + midLLLR) / 2.0;
			vec2 dirv;
                        drawLineAsGeometryClipped(transformedTarget, midMid, labelTop, labelBottom, labelLeft, labelRight, dirv, adjLineWidth, aa);
		} else { //connector_mode 0 or 3, or connector_mode 1 without the background
			vec2 dirv;
			drawLineAsGeometry(transformedTarget, endpointOnBBX, dirv, adjLineWidth, aa);
		}
	}
}