programextensions/scene/demos/voxels-walk.xtl

Voxels, 5: walking. The island of voxels-world, seen from inside it. The player is nine numbers -- x y z (feet), vx vy vz, yaw, pitch, on the ground -- and every frame X_eTaL reads the keys and the mouse, turns, falls, jumps, and moves one axis at a time against the solid blocks the player's box would overlap, stopping at the face of the block it hits (a swept box per axis, as the APL game collides); then it sets scene's first-person camera. It also tests the 32 chunks against the planes of the view, as the APL game culls (key c). Run: just demo scene voxels-walk (a new island each run; --seed 1) W A S D walk, Shift run, Space jump (in water: swim up; at the surface: climb out onto a bank one block high), drag the mouse or the arrows to look, c: the chunks in view, H: back to the start, q or close: quit

source · imports vx: extensions/scene/demos/Voxels.xtl; sc: extensions/scene/lib/Scene.xtl

h : Int

value · line 18
h ← ᵛˣh̲eights 64
Used in: b, hv

b : Int

value · line 19
b ← ᵛˣt̲errain h
Used in: b, f, sv

ts : Int

value · line 20
ts ← 12 2 r̲eshape 3 + r̲oll! 24 r̲eshape 58
Used in: b

b : Int

value · line 21
b ← ts ᵛˣf̲orest b

f : Int

value · line 22
f ← ᵛˣw̲orldFaces b

sv : Int

value · line 23
sv ← r̲avel ᵛˣs̲olid b

w : Int

value · line 27
w ← "Voxels 5: walking -- X_eTaL" ˢᶜo̲pen! 640 400

g : Int

value · line 28
g ← w ˢᶜf̲og! 24.0 56.0

c : Int

value · line 29
c ← ᵛˣc̲hunkOf f
Used in: keys, ᵘp̲ut

keys : Int

value · line 30
keys ← u̲nique (10 × c) + 5 s̲elect₂ f
Used in: ᵘp̲ut, put

ᵘp̲ut : Int -> Int

function · line 31
ᵘp̲ut ← { i →
  key ← i s̲elect keys
  sel ← key = (10 × c) + 5 s̲elect₂ f
  head ← (f̲loat w c̲at key) c̲at (1 + key m̲od 10) s̲elect ᵛˣcolors
  x ← head ˢᶜq̲uads! ᵛˣc̲orners sel r̲eplicate f
  i + 1
}
Used in: put

put : Int

value · line 38
put ← (t̲ally keys) 'ᵘp̲ut p̲ower 1

The player

dt : Float

value · line 43

a box 0.6 wide and 1.75 tall, the eye 1.6 up; a frame is 1/60 s

dt ← 1.0 ÷ 60.0

ᵘs̲et : Float -> Float -> Float

function · line 46

(i c_at v) u:s_et p: the state with element i replaced by v

ᵘs̲et ← { l p → p + (f̲loat (r̲ange 9) = f̲loor 1 s̲elect l) × (2 s̲elect l) − p }

ᵘh̲it : Float -> Float

function · line 50

whether the box with its feet at (x y z) overlaps a solid block: beyond the island's sides and below it is solid, above it is air

ᵘh̲it ← { q →
  x ← 1 s̲elect q
  y ← 2 s̲elect q
  z ← 3 s̲elect q
  cx ← u̲nique f̲loor (x − 0.3) c̲at x + 0.3
  cy ← u̲nique f̲loor y c̲at (y + 0.9) c̲at y + 1.75
  cz ← u̲nique f̲loor (z − 0.3) c̲at z + 0.3
  out ← ('+ r̲/ (cx < 0) + cx > 63) + ('+ r̲/ (cz < 0) + cz > 63) + '+ r̲/ cy < 0
  out > 0 ? 1
  cy ← (cy ≤ 31) r̲eplicate cy
  0 = t̲ally cy ? 0
  i ← 1 + (2048 × cx) '+ t̲able (64 × cy) '+ t̲able cz
  f̲loat 0 < '+ r̲/ (r̲avel i) s̲elect sv
}

ᵘs̲nap : Float -> Float -> Float

function · line 67

v u:s_nap a: where to stop, moving at v, before the block at a (the box reaches 0.3 to each side)

ᵘs̲nap ← { v a →
  v > 0.0 ? (f̲loat f̲loor a + 0.3) − 0.3001
  (f̲loat 1 + f̲loor a − 0.3) + 0.3001
}
Used in: ᵘm̲x, ᵘm̲z

ᵘm̲x : Float -> Float

function · line 74

the three axes of a move: x and z stop at a wall; y lands (on the ground) or bumps a ceiling

ᵘm̲x ← { p →
  a ← (1 s̲elect p) + dt × 4 s̲elect p
  q ← (1 c̲at a) ᵘs̲et p
  0 = ᵘh̲it q ? q
  (4 c̲at 0.0) ᵘs̲et (1 c̲at (4 s̲elect p) ᵘs̲nap a) ᵘs̲et p
}
Used in: ᵘs̲tep

ᵘm̲z : Float -> Float

function · line 80
ᵘm̲z ← { p →
  a ← (3 s̲elect p) + dt × 6 s̲elect p
  q ← (3 c̲at a) ᵘs̲et p
  0 = ᵘh̲it q ? q
  (6 c̲at 0.0) ᵘs̲et (3 c̲at (6 s̲elect p) ᵘs̲nap a) ᵘs̲et p
}
Used in: ᵘs̲tep

ᵘm̲y : Float -> Float

function · line 86
ᵘm̲y ← { p →
  a ← (2 s̲elect p) + dt × 5 s̲elect p
  q ← (9 c̲at 0.0) ᵘs̲et (2 c̲at a) ᵘs̲et p
  0 = ᵘh̲it q ? q
  (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
  (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
}
Used in: ᵘs̲tep

ᵘs̲tep : Float -> Float

function · line 96

one frame of the player: the controls are mouse dx dy, then w a s d space shift left right up down (1 held)

ᵘs̲tep ← { p →
  k ← ˢᶜc̲ontrols w
  yaw ← (7 s̲elect p) + (0.005 × 1 s̲elect k) + 2.0 × dt × (10 s̲elect k) − 9 s̲elect k
  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
  fwd ← (3 s̲elect k) − 5 s̲elect k
  side ← (6 s̲elect k) − 4 s̲elect k
  ⍝ in water: all the air below the sea (14) is water; the body is in
  ⍝ it when its middle is below the surface
  wet ← f̲loat 14.0 > 0.9 + 2 s̲elect p
  speed ← (1.0 − 0.4 × wet) × 4.5 × 1.0 + 8 s̲elect k
  vx ← speed × ((s̲in yaw) × fwd) + (c̲os yaw) × side
  vz ← speed × ((0.0 − c̲os yaw) × fwd) + (s̲in yaw) × side
  ⍝ a jump from the ground, or from the surface of the water (feet
  ⍝ within half a block above it, not deeper): onto a bank one block high
  surface ← (f̲loat 14.5 > 2 s̲elect p) × f̲loat 13.0 < 2 s̲elect p
  jump ← (1.0 m̲in (9 s̲elect p) + surface × 1.0 − wet) × 7 s̲elect k
  ⍝ swimming: Space rises; otherwise a slow sink
  swim ← wet × 7 s̲elect k
  fall ← -30.0 m̲ax (5 s̲elect p) − 22.0 × dt
  sink ← -2.0 m̲ax (5 s̲elect p) − 6.0 × dt
  vy ← (7.5 × jump) + (1.0 − jump) × (4.0 × swim) + (1.0 − swim) × (wet × sink) + (1.0 − wet) × fall
  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
  p ← ᵘm̲y ᵘm̲z ᵘm̲x p
  e ← w ˢᶜ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
  p
}
Used in: ᵘf̲rame

The chunks in view

ᵘi̲nView : Truthy a => Float -> a

function · line 129

each chunk's box against the planes of the view (left, right, bottom, top, and the plane of the eye): a chunk is out when its box is wholly behind one of them. The planes' normals are made in the camera's frame and turned into the world's by an inner product with the frame.

ᵘi̲nView ← { p →
  yaw ← 7 s̲elect p
  pt ← 8 s̲elect p
  right ← (c̲os yaw) c̲at 0.0 c̲at s̲in yaw
  up ← (0.0 − (s̲in yaw) × s̲in pt) c̲at (c̲os pt) c̲at (c̲os yaw) × s̲in pt
  ahead ← ((s̲in yaw) × c̲os pt) c̲at (s̲in pt) c̲at 0.0 − (c̲os yaw) × c̲os pt
  v ← 0.6109
  hh ← a̲tan 1.6 × (s̲in v) ÷ c̲os v
  nc ← 5 3 r̲eshape (c̲os hh) c̲at 0.0 c̲at (s̲in hh) c̲at (0.0 − c̲os hh) c̲at 0.0 c̲at (s̲in hh) c̲at 0.0 c̲at (c̲os v) c̲at (s̲in v) c̲at 0.0 c̲at (0.0 − c̲os v) c̲at (s̲in v) c̲at 0.0 0.0 1.0
  nw ← nc '+ '× i̲nner 3 3 r̲eshape right c̲at up c̲at ahead
  j ← (r̲ange 32) − 1
  centers ← 2 1 t̲ranspose 3 32 r̲eshape (8.0 + 16.0 × f̲loat j m̲od 4) c̲at (8.0 + 16.0 × f̲loat j d̲iv 16) c̲at 8.0 + 16.0 × f̲loat (j d̲iv 4) m̲od 4
  eye ← (1 s̲elect p) c̲at ((2 s̲elect p) + 1.6) c̲at 3 s̲elect p
  rel ← centers − 32 3 r̲eshape eye
  d ← rel '+ '× i̲nner 2 1 t̲ranspose nw
  r ← (a̲bs nw) '+ '× i̲nner 8.0 8.0 8.0
  '∧ r̲/₂ d ≥ 32 5 r̲eshape 0.0 − r
}
Used in: ᵘc̲hunks

ᵘc̲hunks : Float -> Float

function · line 147
ᵘc̲hunks ← { p →
  m ← ᵘi̲nView p
  a ← p̲rint! "chunks in view (of 32), and by layer (bottom, top; rows north to south):"
  a ← p̲rint! '+ r̲/ m
  a ← p̲rint! 2 4 4 r̲eshape m
  p
}
Used in: s, ᵘf̲rame

The loop

j : Int

value · line 160

start above the island's highest inner column, dropping onto it, facing north when the middle is north of it, else south (the highest of the columns at least 8 from the island's sides)

j ← (r̲ange 4096) − 1
Used in: inner

inner : Int

value · line 161
inner ← ((j d̲iv 64) ≥ 8) × ((j d̲iv 64) < 56) × ((j m̲od 64) ≥ 8) × (j m̲od 64) < 56
Used in: i

hv : Int

value · line 162
hv ← r̲avel h
Used in: i, start, e

i : Int

value · line 163
i ← f̲irst w̲here inner × hv = 'm̲ax r̲/ inner × hv
Used in: sx, sz, start, e

sx : Float

value · line 164
sx ← (f̲loat (i − 1) d̲iv 64) + 0.5
Used in: start, e

sz : Float

value · line 165
sz ← (f̲loat (i − 1) m̲od 64) + 0.5
Used in: yaw0, start, e

yaw0 : Float

value · line 166
yaw0 ← 3.14159 × f̲loat sz < 32.0
Used in: start, e

start : Float

value · line 167
start ← sx c̲at (f̲loat 3 + i s̲elect hv) c̲at sz c̲at 0.0 0.0 0.0 c̲at yaw0 c̲at 0.0 0.0
Used in: s, ᵘf̲rame, last

s : Float

value · line 168
s ← ᵘc̲hunks start

e : Int

value · line 169
e ← w ˢᶜe̲ye! sx c̲at (f̲loat 5 + i s̲elect hv) c̲at sz c̲at yaw0 c̲at 0.0

ᵘq̲uit : Any a => a -> Float

function · line 171
ᵘq̲uit ← { p →
  z ← ˢᶜc̲lose! w
  0 r̲eshape 0.0
}
Used in: ᵘf̲rame

ᵘf̲rame : Float -> Float

function · line 175
ᵘf̲rame ← { p →
  0 = t̲ally p ? p
  v ← ˢᶜn̲ext! w
  ((v m̲atch "close") + (v m̲atch "key q") + v m̲atch "key Escape") > 0 ? ᵘq̲uit p
  (v m̲atch "key c") ? ᵘs̲tep ᵘc̲hunks p
  (v m̲atch "key h") ? ᵘs̲tep start
  ᵘs̲tep p
}
Used in: last

last : Float

value · line 183
last ← 100000 'ᵘf̲rame p̲ower start