-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtest.js
More file actions
70 lines (61 loc) · 2.9 KB
/
test.js
File metadata and controls
70 lines (61 loc) · 2.9 KB
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
import assert from 'node:assert/strict'
const F2 = 0.5 * (Math.sqrt(3) - 1), G2 = (3 - Math.sqrt(3)) / 6
const GRAD2 = [[1,1],[-1,1],[1,-1],[-1,-1],[1,0],[-1,0],[0,1],[0,-1]]
function buildPermTable(seed) {
const p = new Uint8Array(256); for (let i = 0; i < 256; i++) p[i] = i
let s = seed | 0
for (let i = 255; i > 0; i--) { s=(s*1664525+1013904223)>>>0; const j=s%(i+1); const tmp=p[i]; p[i]=p[j]; p[j]=tmp }
const perm = new Uint8Array(512); for (let i=0;i<512;i++) perm[i]=p[i&255]; return perm
}
function simplex2(perm, x, y) {
const s=(x+y)*F2, i=Math.floor(x+s), j=Math.floor(y+s), t=(i+j)*G2
const x0=x-(i-t),y0=y-(j-t),i1=x0>y0?1:0,j1=x0>y0?0:1
const x1=x0-i1+G2,y1=y0-j1+G2,x2=x0-1+2*G2,y2=y0-1+2*G2
const ii=i&255,jj=j&255; let n=0
for (const [dx,dy,ddx,ddy] of [[x0,y0,ii,jj],[x1,y1,ii+i1,jj+j1],[x2,y2,ii+1,jj+1]]) {
const t2=0.5-dx*dx-dy*dy
if (t2>=0) { const g=GRAD2[perm[ddx+perm[ddy&255]]&7]; n+=(t2*t2)*(t2*t2)*(g[0]*dx+g[1]*dy) }
}
return n*70
}
function fbm({seed,octaves,frequency,amplitude,gain,lacunarity,offset=0}) {
const perms=Array.from({length:octaves},(_,i)=>buildPermTable((seed+i*73856093)>>>0))
return (x,y)=>{ let v=0,amp=amplitude,freq=frequency; for (let i=0;i<octaves;i++){v+=amp*simplex2(perms[i],freq*x,freq*y);amp*=gain;freq*=lacunarity}; return v+offset }
}
let pass = 0, fail = 0
const _tests = []
function test(name, fn) { _tests.push({ name, fn }) }
test('FBM noise is deterministic', () => {
const n = fbm({seed:42,octaves:4,frequency:0.1,amplitude:1,gain:0.5,lacunarity:2})
assert.equal(n(1,2).toFixed(6), n(1,2).toFixed(6))
assert.notEqual(n(1,2).toFixed(4), n(3,4).toFixed(4))
})
test('FBM seed isolation', () => {
const n1 = fbm({seed:0,octaves:4,frequency:0.1,amplitude:1,gain:0.5,lacunarity:2})
const n2 = fbm({seed:999,octaves:4,frequency:0.1,amplitude:1,gain:0.5,lacunarity:2})
assert.notEqual(n1(1,1).toFixed(4), n2(1,1).toFixed(4))
})
test('FBM offset applied', () => {
const n = fbm({seed:0,octaves:1,frequency:0.01,amplitude:0.001,gain:0.5,lacunarity:2,offset:5})
assert(Math.abs(n(0,0) - 5) < 0.1, `expected ~5, got ${n(0,0)}`)
})
test('simplex2 output in expected range', () => {
const perm = buildPermTable(0)
for (let i = 0; i < 20; i++) {
const v = simplex2(perm, i*0.3, i*0.7)
assert(v >= -1 && v <= 1, `simplex2 out of range: ${v}`)
}
})
test('world config aim_sillos scale is [1,1,1]', async () => {
const src = await import('file:///C:/dev/devbox/spawnpoint/apps/world/index.js')
const wd = src.default
const sillos = wd.entities.find(e => e.id === 'env-sillos')
assert(sillos, 'env-sillos not found')
assert.deepEqual(sillos.scale, [1,1,1], `scale was ${JSON.stringify(sillos.scale)}`)
})
for (const { name, fn } of _tests) {
try { await fn(); console.log('PASS', name); pass++ }
catch(e) { console.error('FAIL', name, e.message); fail++ }
}
console.log(`\n${pass} passed, ${fail} failed`)
if (fail > 0) process.exit(1)