sourceextensions/scene/demos/Endless.xtl

1⍝# Endless.xtl -- the endless world and its player, shared by the voxel 2⍝# demos that walk or fly in it (voxels-endless, voxels-fly, and those 3⍝# after): columns of 16 by 16 blocks made around the player and dropped 4⍝# behind it, each made over three frames so no frame waits long, and the 5⍝# player -- walking, swimming, flying -- moving against them. 6⍝# Import: "en:" u_se< "Endless" 7 8ᵛˣ⁼u̲se< "Voxels" 9ˢᶜ⁼u̲se< "Scene" 10 11⍝## The state 12 13⍝# The state is a list of boxes of Floats (the boxes of one array share 14⍝# a type): 1 the player (ten numbers: x y z, vx vy vz, yaw, pitch, on 15⍝# the ground, flying), 2 the columns' keys, 3 their numbers (a column's 16⍝# scene objects are 10 * number + block), 4 the settings (the window, 17⍝# the next number, the job's part 0 to 2, the job's column cx cz and 18⍝# number, the start x y z), 5 the job's data, and from 6 on each 19⍝# column's solid mask, in the keys' order. Made by en:n_ew. 20 21⍝# the columns are kept this many (16-block steps) from the player's, 22⍝# each way, and made within it; beyond one more they are dropped 23ˡreach ← 3 24 25⍝# en:p_layer s: the player's ten numbers 26ˡp̲layer ← { s → d̲isclose 1 s̲elect s } 27⍝# en:k_eys s: the columns' keys 28ˡk̲eys ← { s → d̲isclose 2 s̲elect s } 29⍝# en:n_umbers s: the columns' numbers 30ˡn̲umbers ← { s → d̲isclose 3 s̲elect s } 31⍝# en:s_ettings s: the window, the next number, the job, the start 32ˡs̲ettings ← { s → d̲isclose 4 s̲elect s } 33⍝# en:w_indow s: the scene window the world is drawn in 34ˡw̲indow ← { s → 1 s̲elect ˡs̲ettings s } 35 36⍝ a column's key from its coordinates (cx cz), and back 37ʰk̲ey ← { c → f̲loat (10000 × 1000 + 1 s̲elect c) + 1000 + 2 s̲elect c } 38ʰc̲x ← { k → ((f̲loor k) d̲iv 10000) − 1000 } 39ʰc̲z ← { k → ((f̲loor k) m̲od 10000) − 1000 } 40 41⍝ the state with its keys (box 2), numbers (3), settings (4) or the 42⍝ job's data (5) replaced 43ʰw̲ithKeys ← { v s → (1 t̲ake s) c̲at (e̲nclose v) c̲at 2 d̲rop s } 44ʰw̲ithNumbers ← { v s → (2 t̲ake s) c̲at (e̲nclose v) c̲at 3 d̲rop s } 45ʰw̲ithSettings ← { v s → (3 t̲ake s) c̲at (e̲nclose v) c̲at 4 d̲rop s } 46ʰw̲ithJob ← { v s → (4 t̲ake s) c̲at (e̲nclose v) c̲at 5 d̲rop s } 47 48⍝# en:w_ithPlayer p s: the state with the player p 49ˡw̲ithPlayer ← { p s → (e̲nclose p) c̲at 1 d̲rop s } 50 51⍝# en:n_ew w: a world for window w, no columns made yet, the player 52⍝# standing above the highest ground of column (0, 0), facing north 53ˡn̲ew ← { w → 54 hv ← r̲avel ᵛˣh̲eightsAt 0 0 16 55 i ← f̲irst w̲here hv = 'm̲ax r̲/ hv 56 x ← (f̲loat (i − 1) d̲iv 16) + 0.5 57 y ← f̲loat 2 + i s̲elect hv 58 z ← (f̲loat (i − 1) m̲od 16) + 0.5 59 p ← x c̲at y c̲at z c̲at 0.0 0.0 0.0 0.0 0.0 0.0 0.0 60 none ← 0 r̲eshape 0.0 61 set ← (f̲loat w) c̲at 1.0 0.0 0.0 0.0 0.0 c̲at x c̲at y c̲at z 62 (e̲nclose p) c̲at (e̲nclose none) c̲at (e̲nclose none) c̲at (e̲nclose set) c̲at e̲nclose none 63} 64 65⍝# en:s_tart s: where the player started (x y z) 66ˡs̲tart ← { s → 3 t̲ake 6 d̲rop ˡs̲ettings s } 67 68⍝## Making and dropping columns 69 70⍝# the player's column (cx cz) 71ʰh̲ome ← { s → 72 p ← ˡp̲layer s 73 (f̲loor (1 s̲elect p) ÷ 16.0) c̲at f̲loor (3 s̲elect p) ÷ 16.0 74} 75 76⍝ the first column too far away, if any, dropped: its objects out of 77⍝ scene, its key, number and mask out of the state 78ʰt̲rim ← { s → 79 h ← ʰh̲ome s 80 ks ← ˡk̲eys s 81 far ← ((a̲bs (ʰc̲x ks) − 1 s̲elect h) > ˡreach + 1) + (a̲bs (ʰc̲z ks) − 2 s̲elect h) > ˡreach + 1 82 0 = '+ r̲/ far ? s 83 j ← f̲irst w̲here far > 0 84 n ← j s̲elect ˡn̲umbers s 85 w ← ˡw̲indow s 86 gone ← '{ w ˢᶜr̲emove! (10.0 × n) + f̲loat ⍵ } m̲ap r̲ange 7 87 keep ← j ≠ r̲ange t̲ally ks 88 s ← (keep r̲eplicate ks) ʰw̲ithKeys s 89 s ← (keep r̲eplicate ˡn̲umbers s) ʰw̲ithNumbers s 90 ((5 + j) t̲ake s) c̲at (6 + j) d̲rop s 91} 92 93⍝ (n t) s_endOne f: block t's faces of column n, one object of quads 94ʰs̲endOne ← { nt f → 95 w ← 1 s̲elect nt 96 t ← f̲loor 3 s̲elect nt 97 sel ← (5 s̲elect₂ f) = t 98 0 = '+ r̲/ sel ? 0 99 head ← (f̲loat w) c̲at ((10.0 × 2 s̲elect nt) + f̲loat t) c̲at (1 + t) s̲elect ᵛˣcolors 100 head ˢᶜq̲uads! ᵛˣc̲orners sel r̲eplicate f 101} 102 103⍝# en:s_tream s: one frame's work on the world: the first column too far 104⍝# away dropped, then a third of making a column -- the nearest missing 105⍝# one's blocks and solid mask (part 0), its faces (part 1), or sending 106⍝# them to scene (part 2) -- about 12 ms at most 107ˡs̲tream ← { s → 108 s ← ʰt̲rim s 109 set ← ˡs̲ettings s 110 part ← 3 s̲elect set 111 part = 1.0 ? ʰf̲aces s 112 part = 2.0 ? ʰs̲end s 113 ʰb̲locks s 114} 115 116⍝ part 0: the nearest missing column's blocks and mask; the column is 117⍝ known (collision sees it) from now on, drawn two frames later 118ʰb̲locks ← { s → 119 h ← ʰh̲ome s 120 ks ← ˡk̲eys s 121 r ← ˡreach 122 o ← (r̲ange 1 + 2 × r) − 1 + r 123 dx ← r̲avel o '+ t̲able 0 × o 124 dz ← r̲avel (0 × o) '+ t̲able o 125 ws ← f̲loat (10000 × 1000 + dx + 1 s̲elect h) + 1000 + dz + 2 s̲elect h 126 miss ← (0 = ws m̲ember? ks) r̲eplicate (r̲ange t̲ally ws) 127 0 = t̲ally miss ? s 128 d ← (miss s̲elect dx × dx) + miss s̲elect dz × dz 129 i ← f̲irst (d = 'm̲in r̲/ d) r̲eplicate miss 130 c ← ((i s̲elect dx) + 1 s̲elect h) c̲at (i s̲elect dz) + 2 s̲elect h 131 b ← ᵛˣc̲olumnBlocks c 132 set ← ˡs̲ettings s 133 n ← 2 s̲elect set 134 set ← (1 s̲elect set) c̲at (n + 1.0) c̲at 1.0 c̲at (f̲loat c) c̲at n c̲at 6 d̲rop set 135 s ← (ks c̲at i s̲elect ws) ʰw̲ithKeys s 136 s ← ((ˡn̲umbers s) c̲at n) ʰw̲ithNumbers s 137 s ← (set) ʰw̲ithSettings s 138 s ← (f̲loat r̲avel b) ʰw̲ithJob s 139 s c̲at e̲nclose f̲loat ᵛˣc̲olumnMask b 140} 141 142⍝ part 1: the job's faces, from its blocks 143ʰf̲aces ← { s → 144 set ← ˡs̲ettings s 145 c ← f̲loor 4 5 s̲elect set 146 b ← 18 32 18 r̲eshape f̲loor d̲isclose 5 s̲elect s 147 f ← c ᵛˣc̲olumnFaces b 148 s ← ((2 t̲ake set) c̲at 2.0 c̲at 3 d̲rop set) ʰw̲ithSettings s 149 (f̲loat r̲avel f) ʰw̲ithJob s 150} 151 152⍝ part 2: the job's faces to scene, one object for each kind of block 153ʰs̲end ← { s → 154 set ← ˡs̲ettings s 155 v ← d̲isclose 5 s̲elect s 156 f ← (((t̲ally v) d̲iv 5) c̲at 5) r̲eshape f̲loor v 157 n ← 6 s̲elect set 158 w ← 1 s̲elect set 159 sent ← '{ (w c̲at n c̲at f̲loat ⍵) ʰs̲endOne f } m̲ap r̲ange 7 160 s ← ((2 t̲ake set) c̲at 0.0 c̲at 3 d̲rop set) ʰw̲ithSettings s 161 (0 r̲eshape 0.0) ʰw̲ithJob s 162} 163 164⍝## Collision 165 166⍝ s c_ell v: whether any of the cells at column (x z) and heights ys (v 167⍝ is x z then the ys) is solid; a column not made yet is solid 168ʰc̲ell ← { s v → 169 x ← 1 s̲elect v 170 z ← 2 s̲elect v 171 ys ← 2 d̲rop v 172 i ← (ˡk̲eys s) i̲ndexOf ʰk̲ey (x d̲iv 16) c̲at z d̲iv 16 173 i > t̲ally ˡk̲eys s ? 1 174 m ← d̲isclose (5 + i) s̲elect s 175 0 < '+ r̲/ (1 + (z m̲od 16) + 16 × ys + 32 × x m̲od 16) s̲elect m 176} 177 178⍝# s en:h_it q: whether the player's box (0.6 wide, 1.75 tall) with its 179⍝# feet at q (x y z) overlaps a solid block; below the world is solid, 180⍝# above it air 181ˡh̲it ← { s q → 182 x ← 1 s̲elect q 183 y ← 2 s̲elect q 184 z ← 3 s̲elect q 185 cx ← u̲nique f̲loor (x − 0.3) c̲at x + 0.3 186 cy ← u̲nique f̲loor y c̲at (y + 0.9) c̲at y + 1.75 187 cz ← u̲nique f̲loor (z − 0.3) c̲at z + 0.3 188 0 < '+ r̲/ cy < 0 ? 1.0 189 cy ← (cy ≤ 31) r̲eplicate cy 190 0 = t̲ally cy ? 0.0 191 px ← r̲avel cx '{ ⍺ + 0 × ⍵ } t̲able cz 192 pz ← r̲avel cx '{ ⍵ + 0 × ⍺ } t̲able cz 193 hits ← '{ s ʰc̲ell (⍵ s̲elect px) c̲at (⍵ s̲elect pz) c̲at cy } e̲ach r̲ange t̲ally px 194 f̲loat 0 < '+ r̲/ hits 195} 196 197⍝## The player 198 199⍝# a frame: 1/60 s 200ˡdt ← 1.0 ÷ 60.0 201 202⍝ (i v) s_et p: the player with number i replaced by v 203ʰs̲et ← { l p → p + (f̲loat (r̲ange 10) = f̲loor 1 s̲elect l) × (2 s̲elect l) − p } 204 205⍝ v s_nap a: where to stop, moving at v, before the block at a 206ʰs̲nap ← { v a → 207 v > 0.0 ? (f̲loat f̲loor a + 0.3) − 0.3001 208 (f̲loat 1 + f̲loor a − 0.3) + 0.3001 209} 210 211⍝ the three axes of a move against the world s: x and z stop at a wall; 212⍝ y lands (on the ground) or bumps a ceiling 213ʰm̲x ← { s p → 214 a ← (1 s̲elect p) + ˡdt × 4 s̲elect p 215 q ← (1 c̲at a) ʰs̲et p 216 0 = s ˡh̲it q ? q 217 (4 c̲at 0.0) ʰs̲et (1 c̲at (4 s̲elect p) ʰs̲nap a) ʰs̲et p 218} 219ʰm̲z ← { s p → 220 a ← (3 s̲elect p) + ˡdt × 6 s̲elect p 221 q ← (3 c̲at a) ʰs̲et p 222 0 = s ˡh̲it q ? q 223 (6 c̲at 0.0) ʰs̲et (3 c̲at (6 s̲elect p) ʰs̲nap a) ʰs̲et p 224} 225ʰm̲y ← { s p → 226 a ← (2 s̲elect p) + ˡdt × 5 s̲elect p 227 q ← (9 c̲at 0.0) ʰs̲et (2 c̲at a) ʰs̲et p 228 0 = s ˡh̲it q ? q 229 (5 s̲elect p) > 0.0 ? (5 c̲at 0.0) ʰs̲et (2 c̲at (f̲loat f̲loor a + 1.75) − 1.7501) ʰs̲et p 230 (9 c̲at 1.0) ʰs̲et (5 c̲at 0.0) ʰs̲et (2 c̲at f̲loat 1 + f̲loor a) ʰs̲et p 231} 232 233⍝# s en:m_ove k: one frame of the player under the controls k (mouse dx 234⍝# dy, then 1 for each held: w a s d space shift left right up down), 235⍝# walking or flying, the camera set to its eye. Walking: W A S D, Shift 236⍝# runs, Space jumps; in water (all air below the sea at 14) it sinks 237⍝# slowly, Space swims up, and from the surface Space climbs onto a bank 238⍝# one block high. Flying: W A S D level by the heading, Space up, Shift 239⍝# down, 15 blocks a second, no gravity, the blocks still stopping it. 240ˡm̲ove ← { s k → 241 p ← ˡp̲layer s 242 yaw ← (7 s̲elect p) + (0.005 × 1 s̲elect k) + 2.0 × ˡdt × (10 s̲elect k) − 9 s̲elect k 243 pitch ← -1.5 m̲ax 1.5 m̲in (8 s̲elect p) + (-0.005 × 2 s̲elect k) + 1.5 × ˡdt × (11 s̲elect k) − 12 s̲elect k 244 fwd ← (3 s̲elect k) − 5 s̲elect k 245 side ← (6 s̲elect k) − 4 s̲elect k 246 fly ← 10 s̲elect p 247 wet ← (1.0 − fly) × f̲loat 14.0 > 0.9 + 2 s̲elect p 248 speed ← (fly × 15.0) + (1.0 − fly) × (1.0 − 0.4 × wet) × 4.5 × 1.0 + 8 s̲elect k 249 vx ← speed × ((s̲in yaw) × fwd) + (c̲os yaw) × side 250 vz ← speed × ((0.0 − c̲os yaw) × fwd) + (s̲in yaw) × side 251 surface ← (1.0 − fly) × (f̲loat 14.5 > 2 s̲elect p) × f̲loat 13.0 < 2 s̲elect p 252 jump ← (1.0 − fly) × (1.0 m̲in (9 s̲elect p) + surface × 1.0 − wet) × 7 s̲elect k 253 swim ← wet × 7 s̲elect k 254 fall ← -30.0 m̲ax (5 s̲elect p) − 22.0 × ˡdt 255 sink ← -2.0 m̲ax (5 s̲elect p) − 6.0 × ˡdt 256 walkVy ← (7.5 × jump) + (1.0 − jump) × (4.0 × swim) + (1.0 − swim) × (wet × sink) + (1.0 − wet) × fall 257 flyVy ← ((80.0 − 2 s̲elect p) × 60.0) m̲in 15.0 × (7 s̲elect k) − 8 s̲elect k 258 vy ← (fly × flyVy) + (1.0 − fly) × walkVy 259 p ← (7 c̲at yaw) ʰs̲et (8 c̲at pitch) ʰs̲et (4 c̲at vx) ʰs̲et (5 c̲at vy) ʰs̲et (6 c̲at vz) ʰs̲et p 260 p ← s ʰm̲y s ʰm̲z s ʰm̲x p 261 e ← (ˡw̲indow s) ˢᶜe̲ye! (1 s̲elect p) c̲at ((2 s̲elect p) + 1.6) c̲at (3 s̲elect p) c̲at yaw c̲at pitch 262 p ˡw̲ithPlayer s 263} 264 265⍝# en:h_omeAgain s: the player back at the start, standing still, 266⍝# walking 267ˡh̲omeAgain ← { s → ((ˡs̲tart s) c̲at 0.0 0.0 0.0 0.0 0.0 0.0 0.0) ˡw̲ithPlayer s } 268 269⍝# en:t_oggleFly s: flying, or walking again (falling from where it is) 270ˡt̲oggleFly ← { s → 271 p ← ˡp̲layer s 272 ((6 t̲ake p) c̲at (7 8 s̲elect p) c̲at 0.0 c̲at 1.0 − 10 s̲elect p) ˡw̲ithPlayer s 273} 274 275⍝# en:s_top s: the state marked as finished (the next number negative) 276ˡs̲top ← { s → ((1 t̲ake ˡs̲ettings s) c̲at (0.0 − 2 s̲elect ˡs̲ettings s) c̲at 2 d̲rop ˡs̲ettings s) ʰw̲ithSettings s } 277⍝# en:s_topped s: whether the state is marked as finished 278ˡs̲topped ← { s → 0.0 > 2 s̲elect ˡs̲ettings s }