sourceextensions/scene/demos/Voxels.xtl

1⍝# Voxels.xtl -- voxel chunks as arrays, shared by the voxels-* demos 2⍝# (docs/voxels.md). A chunk is a 16 by 16 by 16 array of block numbers, 3⍝# indexed x (east), y (up), z (south); 0 is air. 4⍝# Import: "vx:" u_se< "Voxels" 5⍝# (Not voxels.xtl: on a case-insensitive file system a demo of that name 6⍝# would be this file -- ask E8.) 7 8⍝## Chunks 9 10⍝# the side of a chunk 11ˡn ← 16 12⍝# the cells of a chunk, 16 cubed 13ˡcells ← 4096 14 15⍝# block 0: air 16ˡair ← 0 17⍝# block 1: stone, below the dirt 18ˡstone ← 1 19⍝# block 2: dirt, three below the grass 20ˡdirt ← 2 21⍝# block 3: grass, on top 22ˡgrass ← 3 23⍝# block 4: sand, where grass would be at or below the water 24ˡsand ← 4 25⍝# block 5: water, filling air below its level (not solid) 26ˡwater ← 5 27⍝# block 6: wood, a tree's trunk 28ˡwood ← 6 29⍝# block 7: leaves, a tree's crown 30ˡleaves ← 7 31⍝# the blocks' names, in their order 32⍝# >> "vx:" u_se< "Voxels" 33⍝# >> vx:names 34⍝# air stone dirt grass sand water wood leaves 35ˡnames ← "air stone dirt grass sand water wood leaves" 36⍝# a character for each block when a chunk is printed, air first: 37⍝# stone #, dirt %, grass ", sand :, water ~, wood |, leaves * 38ˡglyphs ← " #%\":~|*" 39 40i ← (r̲ange 4096) − 1 41⍝# every cell's x (east), as a vector in the chunk's order (x slowest) 42⍝# >> "vx:" u_se< "Voxels" 43⍝# >> 18 t_ake vx:xs 44⍝# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 45ˡxs ← i d̲iv 256 46⍝# every cell's y (up), in the chunk's order 47ˡys ← (i d̲iv 16) m̲od 16 48⍝# every cell's z (south), in the chunk's order (z fastest) 49⍝# >> "vx:" u_se< "Voxels" 50⍝# >> 18 t_ake vx:zs 51⍝# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 52ˡzs ← i m̲od 16 53 54⍝# vx:h_ills phase: a 16 by 16 height field (x by z), rolling hills of 55⍝# heights 3 to 12; the phase shifts them 56ˡh̲ills ← { p → 57 x ← f̲loat (r̲ange 16) − 1 58 a ← 2.5 × s̲in p + x ÷ 2.5 59 b ← 2.0 × c̲os p + x ÷ 3.0 60 f̲loor 7.5 + a '+ t̲able b 61} 62 63⍝# vx:c_hunk h: the chunk on a height field h (x by z): grass on top, 64⍝# three of dirt, stone below; water fills air below 7, and sand 65⍝# replaces grass at or below it; one tree on the hill at (4, 4) when it 66⍝# stands above the water 67ˡc̲hunk ← { h → 68 top ← (1 + ˡzs + 16 × ˡxs) s̲elect r̲avel h 69 d ← top − ˡys 70 b ← (d = 1) × 3 71 b ← b + (d > 1) × (d < 5) × 2 72 b ← b + (d ≥ 5) × 1 73 b ← b + (b = 3) × (ˡys ≤ 7) × 1 74 b ← b + (b = 0) × (ˡys < 7) × 5 75 ⍝ the tree: a trunk of 3 at (4, 4), leaves around its top 76 t ← (1 + 4 + 16 × 4) s̲elect r̲avel h 77 up ← t > 7 78 ax ← a̲bs ˡxs − 4 79 az ← a̲bs ˡzs − 4 80 trunk ← up × (ax = 0) × (az = 0) × (ˡys ≥ t) × ˡys < t + 3 81 crown ← up × (ax ≤ 1) × (az ≤ 1) × (ˡys ≥ t + 2) × (ˡys ≤ t + 3) × 1 − trunk 82 b ← b + trunk × 6 − b 83 b ← b + crown × (b = 0) × 7 84 16 16 16 r̲eshape b 85} 86 87⍝# vx:c_ounts b: how many of each block, air first 88ˡc̲ounts ← { b → '+ r̲/₂ ((r̲ange 8) − 1) '= t̲able r̲avel b } 89 90⍝# x vx:s_ide b: the slice at x, as characters, up at the top 91ˡs̲ide ← { x b → r̲ev (1 + (x + 1) s̲elect b) s̲elect ˡglyphs } 92 93⍝# a column value (x by z) at every cell of its column 94ˡc̲olumn ← { m → 16 16 16 r̲eshape (1 + ˡzs + 16 × ˡxs) s̲elect r̲avel m } 95 96⍝# vx:t_op b: what is seen from above: the highest non-air block of each 97⍝# column (x by z) -- the top's height by a max-reduction down each 98⍝# column, then the block there picked by comparing heights 99ˡt̲op ← { b → 100 y1 ← 16 16 16 r̲eshape ˡys + 1 101 hi ← 'm̲ax r̲/₂ y1 × b > 0 102 '+ r̲/₂ b × y1 = ˡc̲olumn hi 103} 104 105⍝## Faces 106 107⍝# the cells' coordinates as 16 by 16 by 16 arrays 108X ← 16 16 16 r̲eshape ˡxs 109Y ← 16 16 16 r̲eshape ˡys 110Z ← 16 16 16 r̲eshape ˡzs 111 112⍝# a solid block is any but air and water 113ˡs̲olid ← { b → (b > 0) × b ≠ 5 } 114 115⍝# the exposed faces in the six directions -- west, east, down, up, 116⍝# north, south: numbered 0 to 5 -- as a 6 by 4096 Boolean array: a 117⍝# solid cell whose neighbor that way is not solid. The neighbor is a 118⍝# rotation along the axis (the six rotations of the Life idiom) with 119⍝# the plane that wrapped around made air: beyond the border is air. 120ˡe̲xposed ← { b → 121 s ← ˡs̲olid b 122 w ← s > (-1 o̲-₁ s) × X > 0 123 e ← s > (1 o̲-₁ s) × X < 15 124 d ← s > (-1 o̲-₂ s) × Y > 0 125 u ← s > (1 o̲-₂ s) × Y < 15 126 n ← s > (-1 o̲-₃ s) × Z > 0 127 so ← s > (1 o̲-₃ s) × Z < 15 128 6 4096 r̲eshape (r̲avel w) c̲at (r̲avel e) c̲at (r̲avel d) c̲at (r̲avel u) c̲at (r̲avel n) c̲at r̲avel so 129} 130 131⍝# water's surface: water with air above it, facing up 132ˡs̲urface ← { b → (b = 5) > (1 o̲-₂ b > 0) × Y < 15 } 133 134⍝# d r_ows mb: the faces of one direction as 5 rows -- x, y, z of the 135⍝# cell, the direction, the block -- from mb, the mask times 1 + the 136⍝# block (so one array carries both) 137ʰr̲ows ← { d mb → 138 k ← w̲here mb > 0 139 (5 c̲at t̲ally k) r̲eshape (k s̲elect ˡxs) c̲at (k s̲elect ˡys) c̲at (k s̲elect ˡzs) c̲at ((t̲ally k) r̲eshape d) c̲at (k s̲elect mb) − 1 140} 141 142⍝# vx:f_aces b: every face to draw, one row each -- x y z direction 143⍝# block -- the six directions' exposed faces, then water's surface 144ˡf̲aces ← { b → 145 m ← ˡe̲xposed b 146 bb ← 1 + r̲avel b 147 r ← (0 ʰr̲ows bb × 1 s̲elect m) c̲at₂ (1 ʰr̲ows bb × 2 s̲elect m) c̲at₂ (2 ʰr̲ows bb × 3 s̲elect m) 148 r ← r c̲at₂ (3 ʰr̲ows bb × 4 s̲elect m) c̲at₂ (4 ʰr̲ows bb × 5 s̲elect m) c̲at₂ (5 ʰr̲ows bb × 6 s̲elect m) 149 2 1 t̲ranspose r c̲at₂ 3 ʰr̲ows bb × r̲avel ˡs̲urface b 150} 151 152⍝# vx:c_ount f: how many faces in each direction (west east down up 153⍝# north south); a single block shows one face each way: 154⍝# >> "vx:" u_se< "Voxels" 155⍝# >> one := 16 16 16 r_eshape (vx:xs = 8) * (vx:ys = 8) * vx:zs = 8 156⍝# >> vx:c_ount vx:f_aces one 157⍝# 1 1 1 1 1 1 158ˡc̲ount ← { f → '+ r̲/₂ (r̲ange 6) '= t̲able 1 + 4 s̲elect₂ f } 159 160⍝## Drawing 161 162⍝# the corners of each direction's face, from its cell's corner, taken 163⍝# in pairs round the square (1 2, 2 3, 3 4, 4 1): x, y, z, 6 by 8 each 164ox ← 6 8 r̲eshape (8 r̲eshape 0) c̲at (8 r̲eshape 1) c̲at (0 1 1 1 1 0 0 0) c̲at (0 1 1 1 1 0 0 0) c̲at (0 1 1 1 1 0 0 0) c̲at 0 1 1 1 1 0 0 0 165oy ← 6 8 r̲eshape (0 1 1 1 1 0 0 0) c̲at (0 1 1 1 1 0 0 0) c̲at (8 r̲eshape 0) c̲at (8 r̲eshape 1) c̲at (0 0 0 1 1 1 1 0) c̲at 0 0 0 1 1 1 1 0 166oz ← 6 8 r̲eshape (0 0 0 1 1 1 1 0) c̲at (0 0 0 1 1 1 1 0) c̲at (0 0 0 1 1 1 1 0) c̲at (0 0 0 1 1 1 1 0) c̲at (8 r̲eshape 0) c̲at 8 r̲eshape 1 167 168⍝# vx:e_dges f: the faces' outlines as segments for scene: 8 points a 169⍝# face (4 edges, 2 points each), n*8 by 3, the chunk centered on the 170⍝# origin and scaled to -1..1 171ˡe̲dges ← { f → 172 d ← 1 + 4 s̲elect₂ f 173 z8 ← 8 r̲eshape 0 174 px ← (d s̲elect ox) + (1 s̲elect₂ f) '+ t̲able z8 175 py ← (d s̲elect oy) + (2 s̲elect₂ f) '+ t̲able z8 176 pz ← (d s̲elect oz) + (3 s̲elect₂ f) '+ t̲able z8 177 p ← 2 1 t̲ranspose (3 c̲at 8 × t̲ally f) r̲eshape (r̲avel px) c̲at (r̲avel py) c̲at r̲avel pz 178 ((f̲loat p) − 8.0) ÷ 8.0 179} 180 181⍝# each block's color, red green blue (air first) 182ˡcolors ← 8 3 r̲eshape 0 0 0 0.55 0.55 0.58 0.55 0.38 0.22 0.35 0.7 0.25 0.9 0.82 0.55 0.25 0.45 0.9 0.45 0.3 0.15 0.2 0.5 0.2 183 184⍝ the corners of each direction's face in order round it: the 185⍝ outlines' corners 1 3 5 7 186cx ← 1 3 5 7 s̲elect₂ ox 187cy ← 1 3 5 7 s̲elect₂ oy 188cz ← 1 3 5 7 s̲elect₂ oz 189⍝# vx:c_orners f: each face's four corners in order round it, n*4 by 3, 190⍝# in blocks -- the quads scene draws for the faces 191ˡc̲orners ← { f → 192 d ← 1 + 4 s̲elect₂ f 193 z4 ← 4 r̲eshape 0 194 px ← (d s̲elect cx) + (1 s̲elect₂ f) '+ t̲able z4 195 py ← (d s̲elect cy) + (2 s̲elect₂ f) '+ t̲able z4 196 pz ← (d s̲elect cz) + (3 s̲elect₂ f) '+ t̲able z4 197 f̲loat 2 1 t̲ranspose (3 c̲at 4 × t̲ally f) r̲eshape (r̲avel px) c̲at (r̲avel py) c̲at r̲avel pz 198} 199 200⍝# vx:q_uads f: the faces as filled quads for scene, a chunk centered 201⍝# on the origin and scaled to -1..1, like vx:e_dges 202ˡq̲uads ← { f → ((ˡc̲orners f) − 8.0) ÷ 8.0 } 203 204⍝## Worlds: many chunks 205 206⍝ A world is one array, x by 32 by z, made of 16-cubes; its exposed 207⍝ faces are found over the whole of it at once (so faces between 208⍝ chunks hide each other), then grouped by chunk for scene's ids. 209 210⍝# value noise, made by linear algebra: random heights on a grid every s 211⍝# blocks, interpolated to n by n -- M G M', M the n by k hat-function 212⍝# weights of each grid line 213ʰw̲eights ← { s n → 214 k ← 1 + n d̲iv s 215 t ← (f̲loat (r̲ange n) − 1) ÷ f̲loat s 216 0.0 m̲ax 1.0 − a̲bs t '− t̲able f̲loat (r̲ange k) − 1 217} 218ʰn̲oise ← { s n → 219 m ← s ʰw̲eights n 220 k ← 1 + n d̲iv s 221 g ← (f̲loat r̲oll! (k × k) r̲eshape 1000) ÷ 1000.0 222 m '+ '× i̲nner ((k c̲at k) r̲eshape g) '+ '× i̲nner 2 1 t̲ranspose m 223} 224 225⍝# vx:h_eights n: an n by n height field (x by z), three octaves of 226⍝# value noise -- every 16, 8 and 4 blocks -- from 4 to 29 (seeded) 227ˡh̲eights ← { n → 228 v ← (16.0 × 16 ʰn̲oise n) + (7.0 × 8 ʰn̲oise n) + 3.0 × 4 ʰn̲oise n 229 4 m̲ax 29 m̲in f̲loor 4.0 + v 230} 231 232⍝# a world's cells' coordinates, for a shape nx ny nz (x slowest) 233ʰc̲oords ← { sh → 234 j ← (r̲ange '× r̲/ sh) − 1 235 yz ← (2 s̲elect sh) × 3 s̲elect sh 236 (3 c̲at t̲ally j) r̲eshape (j d̲iv yz) c̲at ((j d̲iv 3 s̲elect sh) m̲od 2 s̲elect sh) c̲at j m̲od 3 s̲elect sh 237} 238 239⍝# vx:t_errain h: the world on a height field h (nx by nz), 32 tall: 240⍝# grass, dirt, stone, water filling air below 14, sand at the shore -- 241⍝# the chunk's rules, over the whole world 242ˡt̲errain ← { h → 243 nx ← 1 s̲elect s̲hape h 244 nz ← 2 s̲elect s̲hape h 245 c ← ʰc̲oords nx c̲at 32 c̲at nz 246 xs ← 1 s̲elect c 247 ys ← 2 s̲elect c 248 zs ← 3 s̲elect c 249 d ← ((1 + zs + nz × xs) s̲elect r̲avel h) − ys 250 b ← (d = 1) × 3 251 b ← b + (d > 1) × (d < 5) × 2 252 b ← b + (d ≥ 5) × 1 253 b ← b + (b = 3) × (ys ≤ 14) × 1 254 b ← b + (b = 0) × (ys < 14) × 5 255 (nx c̲at 32 c̲at nz) r̲eshape b 256} 257 258⍝# t vx:t_ree b: a tree at column t (x z) when it stands on grass: a 259⍝# trunk of 4 and a crown of leaves, placed into b -- only the tree's 260⍝# own cells are worked out (their indexes into b), then set by a 261⍝# membership mask, so a tree costs little in a big block 262ˡt̲ree ← { t b → 263 sh ← s̲hape b 264 ny ← 2 s̲elect sh 265 nz ← 3 s̲elect sh 266 tx ← 1 s̲elect t 267 tz ← 2 s̲elect t 268 v ← r̲avel b 269 col ← (1 + tz + nz × ((r̲ange ny) − 1) + ny × tx) s̲elect v 270 0 = '+ r̲/ col = 3 ? b 271 y0 ← 1 + '+ r̲/ (col = 3) × (r̲ange ny) − 1 272 ty ← y0 + (r̲ange 4) − 1 273 ty ← (ty < ny) r̲eplicate ty 274 trunk ← 1 + tz + nz × ty + ny × tx 275 d5 ← (r̲ange 5) − 3 276 dx ← r̲avel d5 '{ ⍺ + 0 × ⍵ } t̲able d5 277 dz ← r̲avel d5 '{ ⍵ + 0 × ⍺ } t̲able d5 278 wide ← ((a̲bs dx) + a̲bs dz) < 4 279 small ← ((a̲bs dx) ≤ 1) × (a̲bs dz) ≤ 1 280 u̲p ← { y m → 281 y ≥ ny ? 0 r̲eshape 0 282 1 + (tz + m r̲eplicate dz) + nz × y + ny × tx + m r̲eplicate dx 283 } 284 crown ← ((y0 + 3) u̲p wide) c̲at ((y0 + 4) u̲p wide) c̲at (y0 + 5) u̲p small 285 n ← t̲ally v 286 v ← v + ((r̲ange n) m̲ember? trunk) × 6 − v 287 v ← v + ((r̲ange n) m̲ember? crown) × (v = 0) × 7 288 sh r̲eshape v 289} 290 291⍝# vx:w_orldFaces b: every face of a world, one row each -- x y z 292⍝# direction block -- as vx:f_aces does for a chunk, the borders of the 293⍝# world air 294ˡw̲orldFaces ← { b → 295 sh ← s̲hape b 296 c ← ʰc̲oords sh 297 s ← ˡs̲olid b 298 xs ← sh r̲eshape 1 s̲elect c 299 ys ← sh r̲eshape 2 s̲elect c 300 zs ← sh r̲eshape 3 s̲elect c 301 mx ← (1 s̲elect sh) − 1 302 my ← (2 s̲elect sh) − 1 303 mz ← (3 s̲elect sh) − 1 304 w ← s > (-1 o̲-₁ s) × xs > 0 305 e ← s > (1 o̲-₁ s) × xs < mx 306 d ← s > (-1 o̲-₂ s) × ys > 0 307 u ← s > (1 o̲-₂ s) × ys < my 308 n ← s > (-1 o̲-₃ s) × zs > 0 309 so ← s > (1 o̲-₃ s) × zs < mz 310 top ← (b = 5) > (1 o̲-₂ b > 0) × ys < my 311 bb ← 1 + r̲avel b 312 r̲w ← { d m → 313 k ← w̲here m > 0 314 (5 c̲at t̲ally k) r̲eshape (k s̲elect 1 s̲elect c) c̲at (k s̲elect 2 s̲elect c) c̲at (k s̲elect 3 s̲elect c) c̲at ((t̲ally k) r̲eshape d) c̲at (k s̲elect m) − 1 315 } 316 r ← (0 r̲w bb × r̲avel w) c̲at₂ (1 r̲w bb × r̲avel e) c̲at₂ (2 r̲w bb × r̲avel d) c̲at₂ (3 r̲w bb × r̲avel u) 317 r ← r c̲at₂ (4 r̲w bb × r̲avel n) c̲at₂ (5 r̲w bb × r̲avel so) c̲at₂ 3 r̲w bb × r̲avel top 318 2 1 t̲ranspose r 319} 320 321⍝# vx:c_hunkOf f: the chunk of each face (1 up): x, z and y in 16s 322ˡc̲hunkOf ← { f → 1 + ((1 s̲elect₂ f) d̲iv 16) + (4 × (3 s̲elect₂ f) d̲iv 16) + 16 × (2 s̲elect₂ f) d̲iv 16 } 323 324⍝# ts vx:f_orest b: trees at the columns ts (n by 2: x z), each where it 325⍝# stands on grass -- vx:t_ree folded over them 326ˡf̲orest ← { ts b → 327 boxes ← ('{ ⍵ s̲elect ts } m̲ap r̲ange t̲ally ts) c̲at e̲nclose b 328 d̲isclose '{ e̲nclose (d̲isclose ⍺) ˡt̲ree d̲isclose ⍵ } r̲/ boxes 329} 330 331⍝## Endless worlds 332 333⍝# a grid point's random value, 0 to 1, from its coordinates alone (i 334⍝# by j, any integers): the same point always gets the same value, so 335⍝# any part of an endless world can be made by itself and fits its 336⍝# neighbors 337⍝# >> "vx:" u_se< "Voxels" 338⍝# >> (3 vx:h_ash 4) = 3 vx:h_ash 4 339⍝# 1 340ˡh̲ash ← { i j → 341 v ← 43758.5453 × s̲in (12.9898 × f̲loat i) '+ t̲able 78.233 × f̲loat j 342 v − f̲loat f̲loor v 343} 344 345⍝ the smooth weight of grid line k for the coordinates t (in grid 346⍝ units): smoothstep of 1 - |t - k|, 0 beyond a grid step 347ʰw̲eight ← { t k → 348 d ← 0.0 m̲ax 1.0 − a̲bs t '− t̲able f̲loat k 349 d × d × 3.0 − 2.0 × d 350} 351 352⍝ s n_oiseOf c: value noise every s blocks over the n by n blocks from 353⍝ c (x0 z0): grid values hashed from their coordinates, interpolated as 354⍝ M G M' 355ʰn̲oiseOf ← { s c → 356 x0 ← 1 s̲elect c 357 z0 ← 2 s̲elect c 358 n ← 3 s̲elect c 359 tx ← (f̲loat x0 + (r̲ange n) − 1) ÷ f̲loat s 360 tz ← (f̲loat z0 + (r̲ange n) − 1) ÷ f̲loat s 361 gx ← (f̲loor 'm̲in r̲/ tx) + (r̲ange 2 + (f̲loor 'm̲ax r̲/ tx) − f̲loor 'm̲in r̲/ tx) − 1 362 gz ← (f̲loor 'm̲in r̲/ tz) + (r̲ange 2 + (f̲loor 'm̲ax r̲/ tz) − f̲loor 'm̲in r̲/ tz) − 1 363 (tx ʰw̲eight gx) '+ '× i̲nner (gx ˡh̲ash gz) '+ '× i̲nner 2 1 t̲ranspose tz ʰw̲eight gz 364} 365 366⍝# vx:h_eightsAt x0 z0 n: the heights of the n by n columns from block 367⍝# (x0, z0), x by z, of the endless world: three octaves of value noise 368⍝# (every 32, 16 and 8 blocks), 3 to 29, the sea at 14 -- any square 369⍝# anywhere, always the same 370ˡh̲eightsAt ← { c → 371 v ← (18.0 × 32 ʰn̲oiseOf c) + (8.0 × 16 ʰn̲oiseOf c) + 3.0 × 8 ʰn̲oiseOf c 372 3 m̲ax 29 m̲in f̲loor 2.0 + v 373} 374 375⍝ the cells of a 16 by 32 by 16 column inside its 18 by 32 by 18 block 376⍝ (a border of one from the neighbors), as indexes into the bigger one 377cell ← (r̲ange 8192) − 1 378inner ← 1 + (1 + cell m̲od 16) + 18 × ((cell d̲iv 16) m̲od 32) + 32 × 1 + cell d̲iv 512 379 380⍝# vx:p_atch c: column c (cx cz) of the endless world, 16 by 32 by 16 381⍝# blocks: made with a border of one block from its neighbors' heights, 382⍝# so its faces at the border hide where a neighbor is solid; trees (two 383⍝# places hashed from the column, kept inside it). A box of its faces 384⍝# (world coordinates, one row each: x y z direction block) and a box of 385⍝# its solid mask (16 by 32 by 16, flat, x slowest) 386ˡp̲atch ← { c → 387 x0 ← (16 × 1 s̲elect c) − 1 388 z0 ← (16 × 2 s̲elect c) − 1 389 h ← ˡh̲eightsAt x0 c̲at z0 c̲at 18 390 b ← ˡt̲errain h 391 r ← (1 s̲elect c) ˡh̲ash 2 s̲elect c 392 q ← (2 s̲elect c) ˡh̲ash 1 s̲elect c 393 t ← 4 + f̲loor 10.0 × (r̲avel r) c̲at (r̲avel q) c̲at (r̲avel r × q) c̲at r̲avel 1.0 − r × q 394 b ← (2 2 r̲eshape t) ˡf̲orest b 395 f ← ˡw̲orldFaces b 396 keep ← ((1 s̲elect₂ f) ≥ 1) × ((1 s̲elect₂ f) ≤ 16) × ((3 s̲elect₂ f) ≥ 1) × (3 s̲elect₂ f) ≤ 16 397 f ← keep r̲eplicate f 398 f ← f + ((t̲ally f) c̲at 5) r̲eshape x0 c̲at 0 c̲at z0 c̲at 0 0 399 (e̲nclose f) c̲at e̲nclose inner s̲elect r̲avel ˡs̲olid b 400} 401 402⍝## Columns, quickly 403 404⍝ the 18 by 32 by 18 block of a column with its border: its cells' 405⍝ coordinates, made once (flat, x slowest, and as arrays), and which 406⍝ cells are the column's own (x and z from 1 to 16) 407cc ← ʰc̲oords 18 32 18 408cx18 ← 1 s̲elect cc 409cy18 ← 2 s̲elect cc 410cz18 ← 3 s̲elect cc 411X18 ← 18 32 18 r̲eshape cx18 412Y18 ← 18 32 18 r̲eshape cy18 413Z18 ← 18 32 18 r̲eshape cz18 414own ← (cx18 ≥ 1) × (cx18 ≤ 16) × (cz18 ≥ 1) × cz18 ≤ 16 415 416⍝# vx:c_olumnBlocks c: the blocks of column c (cx cz) of the endless 417⍝# world with a border of one from its neighbors, 18 by 32 by 18: the 418⍝# heights, the terrain's rules, two trees placed by hash -- the first 419⍝# of the three parts of making a column (about 12 ms) 420ˡc̲olumnBlocks ← { c → 421 x0 ← (16 × 1 s̲elect c) − 1 422 z0 ← (16 × 2 s̲elect c) − 1 423 h ← ˡh̲eightsAt x0 c̲at z0 c̲at 18 424 d ← ((1 + cz18 + 18 × cx18) s̲elect r̲avel h) − cy18 425 b ← (d = 1) × 3 426 b ← b + (d > 1) × (d < 5) × 2 427 b ← b + (d ≥ 5) × 1 428 b ← b + (b = 3) × (cy18 ≤ 14) × 1 429 b ← b + (b = 0) × (cy18 < 14) × 5 430 b ← 18 32 18 r̲eshape b 431 r ← (1 s̲elect c) ˡh̲ash 2 s̲elect c 432 q ← (2 s̲elect c) ˡh̲ash 1 s̲elect c 433 t ← 4 + f̲loor 10.0 × (r̲avel r) c̲at (r̲avel q) c̲at (r̲avel r × q) c̲at r̲avel 1.0 − r × q 434 (2 2 r̲eshape t) ˡf̲orest b 435} 436 437⍝# vx:c_olumnMask b: the solid mask of a column's own cells (16 by 32 438⍝# by 16, flat, x slowest), from its blocks 439ˡc̲olumnMask ← { b → inner s̲elect r̲avel ˡs̲olid b } 440 441⍝# c vx:c_olumnFaces b: the faces of column c's own cells, in world 442⍝# coordinates, one row each (x y z direction block) -- found over the 443⍝# block with its border, so faces against a solid neighbor hide; the 444⍝# second part of making a column 445ˡc̲olumnFaces ← { c b → 446 s ← ˡs̲olid b 447 w ← s > (-1 o̲-₁ s) × X18 > 0 448 e ← s > (1 o̲-₁ s) × X18 < 17 449 d ← s > (-1 o̲-₂ s) × Y18 > 0 450 u ← s > (1 o̲-₂ s) × Y18 < 31 451 n ← s > (-1 o̲-₃ s) × Z18 > 0 452 so ← s > (1 o̲-₃ s) × Z18 < 17 453 top ← (b = 5) > (1 o̲-₂ b > 0) × Y18 < 31 454 bb ← own × 1 + r̲avel b 455 x0 ← (16 × 1 s̲elect c) − 1 456 z0 ← (16 × 2 s̲elect c) − 1 457 r̲w ← { d m → 458 k ← w̲here m > 0 459 (5 c̲at t̲ally k) r̲eshape (x0 + k s̲elect cx18) c̲at (k s̲elect cy18) c̲at (z0 + k s̲elect cz18) c̲at ((t̲ally k) r̲eshape d) c̲at (k s̲elect m) − 1 460 } 461 r ← (0 r̲w bb × r̲avel w) c̲at₂ (1 r̲w bb × r̲avel e) c̲at₂ (2 r̲w bb × r̲avel d) c̲at₂ (3 r̲w bb × r̲avel u) 462 r ← r c̲at₂ (4 r̲w bb × r̲avel n) c̲at₂ (5 r̲w bb × r̲avel so) c̲at₂ 3 r̲w bb × r̲avel top 463 2 1 t̲ranspose r 464}