rev: 21c5e6d2f665d0e8b4ff917a51b664c895dab2ed tukan/tukan/csg.sc -rw-r--r-- 8.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
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
using import glm
using import .derivative

# f32 <- (f32 f32 f32)
fn srange (a b r)
    clamp
        r - (abs (a - b))
        0.0
        r

# f32 <- (f32 f32 f32)
fn smin (a b r)
    let e = (srange a b r)
    (min a b) - (e * e * (0.25 / r))

# f32 <- (f32 f32 f32)
fn smax (a b r)
    let e = (srange a b r)
    (max a b) + (e * e * (0.25 / r))

# da3_f32 <- (da3_f32 da3_f32 f32)
fn da_srange (a b r)
    da_min
        da_max
            da_sub r (da_abs (da_sub a b))
            0.0
        r

# da3_f32 <- (da3_f32 da3_f32 f32)
fn da_smin (a b r)
    let e = (da_srange a b r)
    da_sub
        da_min a b
        da_mul (da_pow2 e) (0.25 / r)

# da3_f32 <- (da3_f32 da3_f32 f32)
fn da_smax (a b r)
    let e = (da_srange a b r)
    da_add
        da_max a b
        da_mul (da_pow2 e) (0.25 / r)

fn... sabs
    (a : f32, r : f32)
        let e =
            clamp
                r - (abs (2.0 * a))
                0.0
                r
        (abs a) + (e * e * (0.25 / r))
    (p : vec3, r : f32)
        vec3
            sabs p.x r
            sabs p.y r
            sabs p.z r

# a, b: input distances
    s: -1/1 signs to switch comparison polarity (1: MAX, -1: MIN)
    c.x,c.y: radius & scaling factor, as returned by csg_op_params()
# f32 <- (f32 f32 f32 vec2)
fn csg_op (a b s c)
    let d = (abs (a - b))
    let q = (max (c.x - d) 0.0)
    0.5 * (a + b + s * (d + c.y * q * q))

# f32 <- (f32 f32 vec2)
fn csg_min (a b c)
    let d = (abs (a - b))
    let q = (max (c.x - d) 0.0)
    0.5 * (a + b - d - c.y * q * q)

# f32 <- (f32 f32 vec2)
fn csg_max (a b c)
    let d = (abs (a - b))
    let q = (max (c.x - d) 0.0)
    0.5 * (a + b + d + c.y * q * q)

# vec2 <- f32
fn csg_op_params (r)
    vec2 r
        ? (r > 0.0)
            0.5 / r
            0.0

# vec3 <- (vec3 f32)
fn tri (x phase)
    abs
        ((x + (phase * 0.5)) % phase) - (phase * 0.5)

# vec3 <- (vec3 f32 f32)
fn stri (x phase r)
    sabs
        ((x + (phase * 0.5)) % phase) - (phase * 0.5)
        r

# f32 <- (vec3 f32)
fn sphere (p r)
    (length p) - r

# da3_f32 <- (da3_vec3 f32)
fn da_sphere (p r)
    da_sub (da_length p) r

# f32 <- (vec3 vec4 vec2)
fn superprim (p s r)
    let d = ((abs p) - s.xyz)
    let q =
        -
            abs
                +
                    length (max (r.x + d.xy) 0.0)
                    min (- r.x) (max d.x d.y)
                    s.w
            s.w
    +
        length (max (r.y + (vec2 q d.z)) 0.0)
        min (- r.y) (max q d.z)

# da3_f32 <- (da3_vec3 vec4 vec2)
fn da_superprim (p s r)
    let dx = (da_sub (da_abs p.x) s.x)
    let dy = (da_sub (da_abs p.y) s.y)
    let dz = (da_sub (da_abs p.z) s.z)
    let q =
        da_sub
            da_abs
                da_add
                    da_add
                        da_length
                            da3_vec2
                                da_max (da_add r.x dx) 0.0
                                da_max (da_add r.x dy) 0.0
                        da_min (- r.x) (da_max dx dy)
                    s.w
            s.w
    da_add
        da_length
            da3_vec2
                da_max (da_add r.y q) 0.0
                da_max (da_add r.y dz) 0.0
        da_min (- r.y) (da_max q dz)

# params: radius, half-height
# f32 <- (vec3 vec2)
fn bicone (p s)
    let c =
        normalize
            vec2 s.y s.x
    let z =
        (abs p.z) - s.y
    let q =
        length p.xy
    c.x * q + c.y * z

# da3_f32 <- (da3_vec3 vec2)
fn da_bicone (p s)
    let c =
        normalize
            vec2 s.y s.x
    let z =
        da_sub (da_abs p.z) s.y
    let q =
        da_length (da3_vec2 p.x p.y)
    da_add
        da_mul c.x q
        da_mul c.y z

# f32 <- (vec3 vec3)
fn ellipsoid (p s)
    *
        (length (p / s)) - 1.0
        min s.x s.y s.z

# da3_f32 <- (da3_vec3 vec3)
fn da_ellipsoid (p s)
    da_mul
        da_sub
            da_length
                da3_vec3
                    da_mul p.x (1.0 / s.x)
                    da_mul p.y (1.0 / s.y)
                    da_mul p.z (1.0 / s.z)
            1.0
        min s.x s.y s.z

# f32 <- (vec3 vec3 vec2)
fn subprim (p s r)
    let d = ((abs p) - s.xyz)
    let q =
        +
            length (max (r.x + d.xy) 0.0)
            min (- r.x) (max d.x d.y)
    +
        length (max (r.y + (vec2 q d.z)) 0.0)
        min (- r.y) (max q d.z)

# da3_f32 <- (da3_vec3 vec3 vec2)
fn da_subprim (p s r)
    let dx = (da_sub (da_abs p.x) s.x)
    let dy = (da_sub (da_abs p.y) s.y)
    let dz = (da_sub (da_abs p.z) s.z)
    let q =
        da_add
            da_length
                da3_vec2
                    da_max (da_add r.x dx) 0.0
                    da_max (da_add r.x dy) 0.0
            da_min (- r.x) (da_max dx dy)
    da_add
        da_length
            da3_vec2
                da_max (da_add r.y q) 0.0
                da_max (da_add r.y dz) 0.0
        da_min (- r.y) (da_max q dz)

# uberprim with precomputed constants
# f32 <- (vec3 vec4 vec3 vec2 f32)
fn uberprim_pcc (p s r ba sz2)
    let d = ((abs p) - s.xyz)
    let 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
    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
    -
        *
            sqrt
                min
                    dot diag diag
                    min
                        dot h0 h0
                        dot h1 h1
            sign
                max d.z
                    dot pa
                        vec2 (- ba.y) ba.x
        r.y

# f32 <- (vec3 vec3 vec3 vec2 f32)
fn uberprim_convex_pcc (p s r ba sz2)
    let d = ((abs p) - s.xyz)
    var q =
        +
            length (max d.xy 0.0)
            (min 0.0 (max d.x d.y)) - r.x
    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
    -
        *
            sqrt
                min
                    dot diag diag
                    min
                        dot h0 h0
                        dot h1 h1
            sign
                max d.z
                    dot pa
                        vec2 (- ba.y) ba.x
        r.y

# da3_f32 <- (da3_vec3 vec3 vec3 vec2 f32)
fn da_uberprim_convex_pcc (p s r ba sz2)
    let d = (da_sub (da_abs p) s.xyz)
    let q =
        da_add
            da_length
                da3_vec2
                    da_max d.x 0.0
                    da_max d.y 0.0
            da_sub
                da_min 0.0 (da_max d.x d.y)
                r.x
    let pa =
        da3_vec2 q
            da_sub p.z s.z
    let diag =
        da_sub pa
            da_mul
                vec2 r.z sz2
                da_clamp (da_dot pa ba) 0.0 1.0
    let h0 =
        da3_vec2
            da_max (da_sub q r.z) 0.0
            da_add p.z s.z
    let h1 =
        da3_vec2
            da_max q 0.0
            da_sub p.z s.z
    da_sub
        da_mul
            da_sqrt
                da_min
                    da_dot2 diag
                    da_min
                        da_dot2 h0
                        da_dot2 h1
            da_sign
                da_max d.z
                    da_dot pa
                        vec2 (- ba.y) ba.x
        r.y

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

# s: width, height, depth
# r: xy corner radius, z corner radius, bottom radius offset
# f32 <- (vec3 vec3 vec3)
fn uberprim_convex (p s r)
    # these operations can be precomputed
    let s2 = (vec3 (s.xy - r.x) (s.z - r.y))
    let r2 = (vec3 (r.x - r.y) r.yz)
    let ba = (vec2 r2.z (-2.0 * s2.z))
    uberprim_convex_pcc p s2 r2
        ba / (dot ba ba)
        ba.y

# s: width, height, depth
# r: xy corner radius, z corner radius, bottom radius offset
# da3_f32 <- (da3_vec3 vec3 vec3)
fn da_uberprim_convex (p s r)
    # these operations can be precomputed
    let s2 = (vec3 (s.xy - r.x) (s.z - r.y))
    let r2 = (vec3 (r.x - r.y) r.yz)
    let ba = (vec2 r2.z (-2.0 * s2.z))
    da_uberprim_convex_pcc p s2 r2
        ba / (dot ba ba)
        ba.y

locals;