rev: 21c5e6d2f665d0e8b4ff917a51b664c895dab2ed tukan/tukan/sdf.sc -rw-r--r-- 3.6 KiB View raw Log this file
21c5e6d2f665 — Leonard Ritter * renamed project from Liminal to Tukan 2 years ago
                                                                                
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
using import glm

#
    // sdUberprim with precomputed constants
    float sdUnterprim(vec3 p, vec4 s, vec3 r, vec2 ba, float sz2) {
        vec3 d = abs(p) - s.xyz;
        float q = length(max(d.xy, 0.0)) + min(0.0,max(d.x,d.y)) - r.x;
        // hole support: without this line, all results are convex
    #ifndef CONVEX
        q = abs(q) - s.w;
    #endif

        vec2 pa = vec2(q, p.z - s.z);
        vec2 diag = pa - vec2(r.z,sz2) * clamp(dot(pa,ba), 0.0, 1.0);
        vec2 h0 = vec2(max(q - r.z,0.0),p.z + s.z);
        vec2 h1 = vec2(max(q,0.0),p.z - s.z);

        return sqrt(min(dot(diag,diag),min(dot(h0,h0),dot(h1,h1))))
            * sign(max(dot(pa,vec2(-ba.y, ba.x)), d.z)) - r.y;
    }

fn sdUnterprim (p s r ba sz2)
    "sdUberprim with precomputed constants.

     p: vec3
     s: vec4
     ba: vec2
     sz2: f32"
    let d =
        (abs p) - s.xyz
    let q =
        +
            length
                #vec2
                    max d.x 0.0
                    max d.y 0.0
                max d.xy (vec2 0.0)
            min 0.0
                max d.x d.y
            - r.x
    # hole support: without this line, all results are convex
    let q =
        (abs q) - s.w

    let pa =
        vec2 q
            p.z - s.z
    let diag =
        pa -
            *
                vec2 r.z sz2
                clamp
                    dot pa ba
                    \ 0.0 1.0
    let h0 =
        vec2
            max
                q - r.z
                0.0
            p.z + s.z
    let h1 =
        vec2
            max q 0.0
            p.z - s.z
    let q =
        dot pa
            vec2
                - ba.y
                ba.x
    -
        *
            sqrt
                min
                    dot diag diag
                    dot h0 h0
                    dot h1 h1
            sign
                max
                    dot pa
                        vec2
                            - ba.y
                            ba.x
                    d.z
        r.y
#
    // s: width, height, depth, thickness
    // r: xy corner radius, z corner radius, bottom radius offset
    float sdUberprim(vec3 p, vec4 s, vec3 r) {
        // these operations can be precomputed
        s.xy -= r.x;
    #ifdef CONVEX
        r.x -= r.y;
    #else
        r.x -= s.w;
        s.w -= r.y;
    #endif
        s.z -= r.y;
        vec2 ba = vec2(r.z, -2.0*s.z);
        return sdUnterprim(p, s, r, ba/dot(ba,ba), ba.y);
    }

#
    if (i == 0) { // cube
    s = vec4(1.0);
    r = vec3(0.0);
    } else if (i == 1) { // cylinder
    s = vec4(1.0);
    r = vec3(1.0,0.0,0.0);
    } else if (i == 2) { // cone
    s = vec4(0.0,0.0,1.0,1.0);
    r = vec3(0.0,0.0,1.0);
    } else if (i == 3) { // pill
    s = vec4(1.0,1.0,2.0,1.0);
    r = vec3(1.0,1.0,0.0);
    } else if (i == 4) { // sphere
    s = vec4(1.0);
    r = vec3(1.0,1.0,0.0);
    } else if (i == 5) { // pellet
    s = vec4(1.0,1.0,0.25,1.0);
    r = vec3(1.0,0.25,0.0);
    } else if (i == 6) { // torus
    s = vec4(1.0,1.0,0.25,0.25);
    r = vec3(1.0,0.25,0.0);
    } else if (i == 7) { // pipe
    s = vec4(vec3(1.0),0.25);
    r = vec3(1.0,0.1,0.0);
    } else if (i == 8) { // corridor
    s = vec4(vec3(1.0),0.25);
    r = vec3(0.1,0.1,0.0);
    }

fn sdUberprim (p s r)
    "vec3 p
     vec4 s: width, height, depth, thickness
     vec3 r: xy corner radius, z corner radius, bottom radius offset"
    # these operations can be precomputed
    let s = (vec4 (s.xy - r.x) s.zw)
    let r = (vec3 (r.x - s.w) r.yz)
    let s = (vec4 s.xy (s.zw - r.y))
    let ba = (vec2 r.z (-2.0 * s.z))
    sdUnterprim p s r
        ba / (dot ba ba)
        ba.y

# TODO: export
do
    let sdUberprim

    locals;