File: agg-path.vert

package info (click to toggle)
python-vispy 0.6.6-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 21,344 kB
  • sloc: python: 57,412; javascript: 6,810; makefile: 63; sh: 5
file content (166 lines) | stat: -rw-r--r-- 4,987 bytes parent folder | download | duplicates (5)
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
// ----------------------------------------------------------------------------
// Copyright (c) 2014, Nicolas P. Rougier. All Rights Reserved.
// Distributed under the (new) BSD License.
// ----------------------------------------------------------------------------
// Hooks:
//  <transform> : vec4 function(position, ...)
//
// ----------------------------------------------------------------------------
#include "misc/viewport-NDC.glsl"
#include "math/point-to-line-distance.glsl"
#include "math/point-to-line-projection.glsl"

// Externs
// ------------------------------------
// extern vec3  p0;
// extern vec3  p1;
// extern vec3  p2;
// extern vec3  p3;
// extern vec2  uv;
// extern vec2  caps;
// extern vec4  color;
// extern float antialias;
// extern float linewidth;
// extern float miter_limit;
// extern vec4 viewport;
// vec4 transform(vec3 position);


// Varyings
// ------------------------------------
varying vec2  v_caps;
varying vec4  v_color;

varying float v_antialias;
varying float v_linewidth;

varying float v_length;
varying vec2  v_texcoord;
varying float v_miter_limit;
varying vec2  v_bevel_distance;


// Main
// ------------------------------------
void main (void)
{
    // This function is externally generated
    fetch_uniforms();

    v_color = color;
    v_caps = caps;
    v_linewidth = linewidth;
    v_antialias = antialias;
    v_miter_limit = miter_limit;

    // transform prev/curr/next
    vec4 p0_ = $transform(vec4(p0, 1));
    vec4 p1_ = $transform(vec4(p1, 1));
    vec4 p2_ = $transform(vec4(p2, 1));
    vec4 p3_ = $transform(vec4(p3, 1));

    // prev/curr/next in viewport coordinates
    vec2 _p0 = NDC_to_viewport(p0_, viewport.zw);
    vec2 _p1 = NDC_to_viewport(p1_, viewport.zw);
    vec2 _p2 = NDC_to_viewport(p2_, viewport.zw);
    vec2 _p3 = NDC_to_viewport(p3_, viewport.zw);

    v_antialias = antialias;
    v_linewidth = linewidth;
    v_miter_limit = miter_limit;

    // Determine the direction of each of the 3 segments (previous, current, next)
    vec2 v0 = normalize(_p1 - _p0);
    vec2 v1 = normalize(_p2 - _p1);
    vec2 v2 = normalize(_p3 - _p2);


    // Determine the normal of each of the 3 segments (previous, current, next)
    vec2 n0 = vec2(-v0.y, v0.x);
    vec2 n1 = vec2(-v1.y, v1.x);
    vec2 n2 = vec2(-v2.y, v2.x);

    // Determine miter lines by averaging the normals of the 2 segments
    vec2 miter_a;
    vec2 miter_b;
    const float epsilon = 0.1;

    // WARN: Here we test if v0 = -v1 relatively to epsilon
    if( length(v0+v1) < epsilon ) {
        miter_a = n1;
    } else {
        miter_a = normalize(n0 + n1); // miter at start of current segment
    }

    // WARN: Here we test if v1 = -v2 relatively to epsilon
    if( length(v1+v2) < epsilon ) {
        miter_b = n1;
    } else {
        miter_b = normalize(n1 + n2); // miter at end of current segment
    }

    // Determine the length of the miter by projecting it onto normal
    vec2 p,v;
    float d, z;
    float w = linewidth/2.0 + 1.5*antialias;
    v_length = length(_p2-_p1);
    float m = miter_limit*linewidth/2.0;
    float length_a = w / dot(miter_a, n1);
    float length_b = w / dot(miter_b, n1);


    // Angle between prev and current segment (sign only)
    float d0 = +1.0;
    if( (v0.x*v1.y - v0.y*v1.x) > 0. ) { d0 = -1.0;}

    // Angle between current and next segment (sign only)
    float d1 = +1.0;
    if( (v1.x*v2.y - v1.y*v2.x) > 0. ) { d1 = -1.0; }

    // Adjust vertex position
    if (uv.x == -1.) {
        z = p1_.z / p1_.w;

        // Cap at start
        if( p0 == p1 ) {
            p = _p1 - w*v1 + uv.y* w*n1;
            v_texcoord = vec2(-w, uv.y*w);
            v_caps.x = v_texcoord.x;
            // Regular join
        } else {
            p = _p1 + uv.y * length_a * miter_a;
            v_texcoord = vec2(point_to_line_projection(_p1,_p2,p), uv.y*w);
            v_caps.x = 1.0;
        }
        if( p2 == p3 ) {
            v_caps.y = v_texcoord.x;
        } else {
            v_caps.y = 1.0;
        }
        v_bevel_distance.x = uv.y*d0*point_to_line_distance(_p1+d0*n0*w, _p1+d0*n1*w, p);
        v_bevel_distance.y =        -point_to_line_distance(_p2+d1*n1*w, _p2+d1*n2*w, p);
    } else {
        z = p2_.z / p2_.w;

        // Cap at end
        if( p2 == p3 ) {
            p = _p2 + w*v1 + uv.y*w*n1;
            v_texcoord = vec2(v_length+w, uv.y*w);
            v_caps.y = v_texcoord.x;
        // Regular join
        } else {
            p = _p2 + uv.y*length_b * miter_b;
            v_texcoord = vec2(point_to_line_projection(_p1,_p2,p), uv.y*w);
            v_caps.y = 1.0;
        }
        if( p0 == p1 ) {
            v_caps.x = v_texcoord.x;
        } else {
            v_caps.x = 1.0;
        }
        v_bevel_distance.x =        -point_to_line_distance(_p1+d0*n0*w, _p1+d0*n1*w, p);
        v_bevel_distance.y = uv.y*d1*point_to_line_distance(_p2+d1*n1*w, _p2+d1*n2*w, p);
    }

    gl_Position = viewport_to_NDC(vec3(p,z), viewport.zw);
}