# height_file_test.ludic - the terrain's questions over a tiles file written here (no device): heights and # the photograph are the file's texels to the bit, resident or not, and a sweep of the whole map by the # questions and by a ground layer's fill leaves the page cache - its slots, what they hold, the clock - as it was import "ludic.render3d/r3d.ludic" program HeightFileTest { numbers float import "fakes/tiles_file.ludic" # never called: naming Input links the engine's runtime, which render3d's textures stand on function links_runtime() -> bool { return Input.key_pressed(0) } function hf_open(render3d_st: mut Render3dState, tag: string) -> bool { let path = Os.temp_dir() + "/r3d_height_file_" + tag + ".ltt2" if not hf_write(path) { return false } render3d_st.TERRAIN_HALF = 4096 render3d_st.ter_ox = 0.0 render3d_st.ter_oz = 0.0 render3d_st.ter_h_scale = 0.0 render3d_st.ter_o_scale = 0.0 return tt_open_ltt2(render3d_st, path, 0) } test "heights and the photograph are the file's texels, whether their tile is resident or not" (render3d_st: mut Render3dState) { expect(hf_open(render3d_st, "same")) terrain_tiles_prefetch(render3d_st, 1000.0, -500.0, 200.0, 100) var off = 0 for j in 0 .. 160 { for i in 0 .. 160 { let x = -3000.0 + float(i) * 37.3 let z = -3100.0 + float(j) * 41.7 if terrain_height(render3d_st, x, z) != hf_expect(x, z) { off += 1 } if terrain_height_file(render3d_st, x, z) != hf_expect(x, z) { off += 1 } let px = min(max(int(Math.floor((x + 4096.0) * 256.0 / 8192.0)), 0), 255) let pz = min(max(int(Math.floor((z + 4096.0) * 256.0 / 8192.0)), 0), 255) if terrain_ortho(render3d_st, x, z) != hf_rgb(px, pz) { off += 1 } } } expect_eq(off, 0) for c in 0 .. 5 { let x = -4096.0 + 64.0 * float(c * 13 + 1) - 1.0 # a texel square across a tile corner let z = -4096.0 + 64.0 * float(c * 7 + 2) - 0.5 expect_eq(terrain_height(render3d_st, x, z), hf_expect(x, z)) } expect_eq(terrain_height(render3d_st, -5000.0, 5000.0), hf_expect(-5000.0, 5000.0)) } test "a sweep of the whole map by the questions leaves every slot, what it holds and the clock as they were" (render3d_st: mut Render3dState) { expect(hf_open(render3d_st, "sweep")) terrain_tiles_prefetch(render3d_st, -200.0, 300.0, 300.0, 200) let was = hf_snap(render3d_st) var sum = 0.0 var ortho = 0 var z = -4096.0 while z <= 4096.0 { var x = -4096.0 while x <= 4096.0 { sum = sum + terrain_height(render3d_st, x, z) + terrain_height_file(render3d_st, x, z) + terrain_height_smooth(render3d_st, x, z) ortho = ortho ^ terrain_ortho(render3d_st, x, z) x = x + 16.0 } z = z + 16.0 } expect(sum != 0.0) expect(ortho != 0) expect_eq(hf_moved(render3d_st, was), 0) } test "a ground layer's fill over the whole map leaves the slots as they were" (render3d_st: mut Render3dState) { expect(hf_open(render3d_st, "fill")) expect(hf_density(render3d_st, Os.temp_dir() + "/r3d_height_file_fill.lgd2")) terrain_tiles_prefetch(render3d_st, 0.0, 0.0, 250.0, 200) let was = hf_snap(render3d_st) if render3d_st.stream_scratch == null { render3d_st.stream_scratch = floats(4096 * INST_FLOATS) } let s = new Stream s.size = 64.0 s.ox = -4096.0 s.oz = -4096.0 s.cur = new Chunk let g = new GroundFill g.step0 = 8.0 g.trample = false var n = 0 var bad = 0 for cz in 0 .. 32 { for cx in 0 .. 32 { s.cur.count = 0 ground_fill(render3d_st, s, cx * 4, cz * 4, 0, g) n += s.cur.count for k in 0 .. s.cur.count { let x = render3d_st.stream_scratch[k * INST_FLOATS] let z = render3d_st.stream_scratch[k * INST_FLOATS + 2] if render3d_st.stream_scratch[k * INST_FLOATS + 1] != hf_expect(x, z) - g.sink { bad += 1 } } } } expect(n > 32 * 32 * 32) expect_eq(bad, 0) expect_eq(hf_moved(render3d_st, was), 0) } test "with the whole copy kept it is terrain_height" (render3d_st: mut Render3dState) { render3d_st.TERRAIN_HALF = 4096 render3d_st.ter_heights = floats(TERRAIN_RES * TERRAIN_RES) for i in 0 .. TERRAIN_RES * TERRAIN_RES { render3d_st.ter_heights[i] = float(i % 997) * 0.25 + float(i / 4096) * 0.01 } for k in 0 .. 400 { let x = -4000.0 + float(k) * 19.91 let z = 3900.0 - float(k) * 17.13 expect_eq(terrain_height_file(render3d_st, x, z), terrain_height(render3d_st, x, z)) } } # one layer, every tile one value (a word in the index): full density everywhere function hf_density(render3d_st: mut Render3dState, path: string) -> bool { let n = TERRAIN_RES / TT_TEX let size = GD_HEADW * 4 + n * n * 8 let b = buffer(size) for k in 0 .. size { b[k] = 0 } hf_put(b, 0, GD_MAGIC) hf_put(b, 4, GD_VERSION) hf_put(b, 8, n) hf_put(b, 12, GD_SIDE) hf_put(b, 16, 1) hf_put(b, 32, 1) hf_put(b, 36, GD_HEADW * 4) for t in 0 .. n * n { hf_put(b, GD_HEADW * 4 + t * 8, 1) hf_put(b, GD_HEADW * 4 + t * 8 + 4, 255) } return Fs.write_bytes(path, b, size) and gd_open_at(render3d_st, path, 0) } }