rev: tukan tukan/octree.sc -rw-r--r-- 6.5 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
#!/usr/bin/env scopes

import .liminal.glmain
import .liminal.screen
#import .liminal.imgui
import .liminal.dockgui

let glmain = liminal.glmain
let screen = liminal.screen
let dockgui = liminal.dockgui

using import glm
using import glsl
using import .liminal.gl
using import .liminal.imgui
using import .liminal.sdf
using import .liminal.packing

struct union Color
    rgba : u32
    c : (array u8 4:usize)

struct Leaf
    color : Color

struct Cell

struct union CellData
    leaf : Leaf
    cells : (array (pointer Cell) 8:usize)

struct Cell
    data : CellData

fn Octree (L)


let MAX_CELLS = (1 << 20)

let leaf = (Leaf)

dump
    sizeof Cell

print
    leaf.color.rgba

glmain.init
    title = "Octree"
    width = 960
    height = 540
    resizable = true

let U_TIME = 0
let U_RESOLUTION = 1

let pg = (glCreateProgram)
do
    fn varyings (mode)
        xvar (do mode) uv : vec2 (location = 0)
        xvar (do mode) pos : vec2 (location = 1)
        scopeof
            uv = uv; pos = pos

    let vertex-fn =
        do
            using (varyings 'out)
            fn main ()
                uv =
                    ((screen.set-vertex-position) * 0.5) + 0.5
                return;

    let fragment-fn =
        do
            using (varyings 'in)
            xvar out out_Color : vec4
            xvar uniform time : f32
                location = U_TIME
            xvar uniform resolution : vec2
                location = U_RESOLUTION

            fn cube (org dir near far)
                "bool cube(vec3 org, vec3 dir, out float near, out float far)"
                let p = ((- (vec3 0) org) / dir)
                let q = (1.0 / (abs dir))
                let tmin tmax = (p - q) (p + q)
                near = (max tmin.x tmin.y tmin.z)
                far = (min tmax.x tmax.y tmax.z)
                near < far and far > 0.0

            fn step-cells (ro rd f)
                let p = (floor ro)
                let rdinv = (1.0 / rd)
                let stp = (sign rd)
                let delta =
                    min ((vec3 1.0) / (abs rd)) (vec3 1000000.0)
                let t_max =
                    abs ((p + (max stp (vec3 0.0)) - ro) * rdinv)
                # start at intersection of ray with initial cell
                let loop (p t_max) = p t_max
                f p
                let next_t = (min t_max.x t_max.y)
                if (next_t < 1.0)
                    let cmp =
                        (step t_max.xyz t_max.zxy) * (step t_max.xyz t_max.yzx)
                    loop
                        p + stp * cmp
                        t_max + delta * cmp

            fn rotate (a v)
                let s c = (sin a) (cos a)
                vec2
                    v.x * c + v.y * s
                    v.x * s - v.y * c

            fn map (p)
                let p2 =
                    p - (vec3 0.0 1.0 0.0)
                let p3 =
                    p - (vec3 0.0 -1.0 0.0)
                let p =
                    * 2.0
                        vec3
                            p.x
                            rotate (f32 time) p.yz
                max
                    sdUberprim p
                        # cube
                        vec4 1.0
                        vec3 0.0
                        # torus
                            vec4 1.0 1.0 0.25 0.25
                            vec3 1.0 0.25 0.0
                        #
                            vec4 1.0 1.0 2.0 1.0
                            vec3 1.0 1.0 0.0
                        #
                            vec4 0.0 0.0 1.0 1.0
                            vec3 0.0 0.0 1.0
                        #
                            vec4 (vec3 1.0) 0.25
                            vec3 0.1 0.1 0.0
                    - ((length p2) - 0.8)
                    - ((length p3) - 0.8)
            let R = 64.0
            fn normal (p)
                let D =
                    1.0 / R
                let delta = (vec2 0.0 D)
                let d =
                    vec3
                        (map (p + delta.yxx)) - (map (p - delta.yxx))
                        (map (p + delta.xyx)) - (map (p - delta.xyx))
                        (map (p + delta.xxy)) - (map (p - delta.xxy))
                d / (length d)

            fn main ()
                let ndc =
                    (vec2 uv) * 2.0 - 1.0
                let ndc =
                    vec2
                        ndc.x * resolution.x / resolution.y
                        ndc.y
                let ndc = (ndc * 0.5)
                let a =
                    (f32 time) * 0.3
                let h = -0.5
                fn rotate-hv (v)
                    let v =
                        vec3 v.x (rotate h v.yz)
                    let q =
                        rotate a v.xz
                    vec3 q.x v.y q.y
                let ro =
                    rotate-hv
                        vec3 0.0 0.0 -4.0
                let rd =
                    rotate-hv
                        vec3 ndc 1.0
                var near = 0.0
                var far = 0.0
                if (cube ro rd near far)
                    let pos = (ro + rd * near)
                    let ro =
                        ((ro + rd * near) + 0.5) * R
                    let rd =
                        (rd / (length rd)) * (far - near) * R
                    var hit = 0.0
                    var hitpos = (vec3 0.0)
                    step-cells ro rd
                        fn (p)
                            let p =
                                ((p + 0.5) / R) - 0.5
                            if ((map p) < 0.0)
                                if (hit < 0.5)
                                    hit = 1.0
                                    hitpos = p
                    out_Color = (vec4 (hit * ((normal (hitpos as immutable)) * 0.5 + 0.5)) 1)
                else
                    out_Color = (vec4 0 0 0.2 1)
                return;

    let link =
        attach-shaders pg
            vertex = vertex-fn
            fragment = fragment-fn
    link;

global time = 0.0
'append glmain.on-draw
    fn (s size)
        glBindFramebuffer GL_FRAMEBUFFER 0
        glViewport 0 0 size.x size.y
        glClearColor 0 0 1 1
        glClear
            |
                GL_COLOR_BUFFER_BIT
                GL_DEPTH_BUFFER_BIT
                GL_STENCIL_BUFFER_BIT

        glUseProgram pg
        glUniform1f U_TIME time
        glUniform2f U_RESOLUTION (f32 size.x) (f32 size.y)
        time = (time + (/ 60))
        screen.draw;
        glUseProgram 0

glmain.loop;

glmain.shutdown;

print "done."