dkl9 commited on 2025-172 20:26:01
Showing 5 changed files, with 81 additions and 18 deletions.
| ... | ... |
@@ -26,6 +26,9 @@ void main() {
|
| 26 | 26 |
|
| 27 | 27 |
FPS = 240 |
| 28 | 28 |
|
| 29 |
+def debug_mode(): |
|
| 30 |
+ pass |
|
| 31 |
+ |
|
| 29 | 32 |
def click_mesh(self, button, ind): |
| 30 | 33 |
a, p = self.faces[ind] |
| 31 | 34 |
match button: |
| ... | ... |
@@ -42,7 +45,7 @@ def click_mesh(self, button, ind): |
| 42 | 45 |
|
| 43 | 46 |
def build_scene(): |
| 44 | 47 |
box = WorldRegion() |
| 45 |
- box.gen_perlin(np.random.rand(2, 2, 2, 3)) |
|
| 48 |
+ print(f"map generated with {box.gen_perlin(np.random.rand(2, 2, 2, 3))} voxels")
|
|
| 46 | 49 |
box.remesh() |
| 47 | 50 |
box.onclick = click_mesh |
| 48 | 51 |
return [box] |
| ... | ... |
@@ -69,6 +72,8 @@ def main(): |
| 69 | 72 |
if ev.type == pygame.QUIT or ev.type == pygame.KEYUP and ev.unicode == "q": |
| 70 | 73 |
pygame.quit() |
| 71 | 74 |
return |
| 75 |
+ elif ev.type == pygame.KEYUP and ev.unicode == "d": |
|
| 76 |
+ debug_mode() |
|
| 72 | 77 |
cam.handle_event(ev, scene) |
| 73 | 78 |
cam.update_pos() |
| 74 | 79 |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) |
| ... | ... |
@@ -24,10 +24,12 @@ class Player(camera.Camera): |
| 24 | 24 |
YELLOW, [-1.0, 1.0, 0.0], mode=GL_TRIANGLE_STRIP, hud=True |
| 25 | 25 |
), |
| 26 | 26 |
} |
| 27 |
+ self.viewport = (640, 480) |
|
| 27 | 28 |
|
| 28 | 29 |
def set_focus(self, f): |
| 29 | 30 |
pygame.event.set_grab(f) |
| 30 | 31 |
pygame.mouse.set_visible(not f) |
| 32 |
+ pygame.mouse.set_pos([self.viewport[0] / 2, self.viewport[1] / 2]) |
|
| 31 | 33 |
self.hud["crosshair"].pos[0] = 2 * (not f) |
| 32 | 34 |
|
| 33 | 35 |
def get_focus(self): |
| ... | ... |
@@ -73,3 +75,4 @@ class Player(camera.Camera): |
| 73 | 75 |
t.click(ev.button, n) |
| 74 | 76 |
case pygame.WINDOWSIZECHANGED | pygame.WINDOWRESIZED: |
| 75 | 77 |
self.aspect = reshape(ev.x, ev.y) |
| 78 |
+ self.viewport = (ev.x, ev.y) |
| ... | ... |
@@ -11,6 +11,7 @@ class WorldRegion(mesh.SquareMesh): |
| 11 | 11 |
def __init__(self, size=16): |
| 12 | 12 |
super().__init__() |
| 13 | 13 |
self.grid = np.zeros((size, size, size), dtype=VOXEL_TYPE) |
| 14 |
+ self.r = size |
|
| 14 | 15 |
|
| 15 | 16 |
def add_voxel(self, pos, vt=1): |
| 16 | 17 |
self.grid[*pos] = vt |
| ... | ... |
@@ -20,30 +21,66 @@ class WorldRegion(mesh.SquareMesh): |
| 20 | 21 |
|
| 21 | 22 |
def remesh(self): |
| 22 | 23 |
offset = vec([0.5, 0.0, 0.0]) |
| 23 |
- r = self.grid.shape[0] |
|
| 24 |
- self.verts = np.empty((0, 3), dtype=FLOAT) |
|
| 25 | 24 |
self.faces = [] |
| 26 |
- for i in range(r): |
|
| 27 |
- for j in range(r): |
|
| 28 |
- for k in range(r): |
|
| 29 |
- p = [i, j, k] |
|
| 30 |
- if self.grid[*p]: |
|
| 25 |
+ prev, curr = 0, 0 |
|
| 26 |
+ vl = [] |
|
| 31 | 27 |
for d in range(3): |
| 32 |
- for s in range(2): |
|
| 33 |
- ts = (-1) ** s |
|
| 34 |
- if p[d] == [r - 1, 0][s] or not self.grid[*(p + np.roll([ts, 0, 0], d))]: |
|
| 35 |
- self.add_sq(ts * (d + 1), 1, p + ts * np.roll(offset, d), p) |
|
| 28 |
+ offset = np.array([1, 0, 0]) |
|
| 29 |
+ roll_vec3(offset, d) |
|
| 30 |
+ for i in range(self.r): |
|
| 31 |
+ for j in range(self.r): |
|
| 32 |
+ for k in range(self.r + 1): |
|
| 33 |
+ p = np.array([k, i, j]) |
|
| 34 |
+ roll_vec3(p, d) |
|
| 35 |
+ prev, curr = curr, (self.grid[*p] if k < self.r else 0) |
|
| 36 |
+ bp, bc = bool(prev), bool(curr) |
|
| 37 |
+ if bp ^ bc: |
|
| 38 |
+ sq = vec([ |
|
| 39 |
+ [0, 1, 1], [0, -1, 1], [0, 1, -1], |
|
| 40 |
+ [0, -1, -1], [0, 1, -1], [0, -1, 1] |
|
| 41 |
+ ]) |
|
| 42 |
+ sq /= 2 * (bp - bc) |
|
| 43 |
+ for v in sq: |
|
| 44 |
+ roll_vec3(v, d) |
|
| 45 |
+ sq += p - offset / 2 |
|
| 46 |
+ vl.extend(sq) |
|
| 47 |
+ if bp: |
|
| 48 |
+ p -= offset |
|
| 49 |
+ for _ in range(2): |
|
| 50 |
+ self.faces.append(((bp - bc) * (d + 1), p)) |
|
| 51 |
+ self.verts = vec(vl) |
|
| 52 |
+ |
|
| 53 |
+ def prof_min(self): |
|
| 54 |
+ self.add_voxel((0, 0, 0)) |
|
| 55 |
+ self.remesh() |
|
| 56 |
+ |
|
| 57 |
+ def prof_med(self): |
|
| 58 |
+ for i in range(self.r // 2): |
|
| 59 |
+ for j in range(self.r // 2): |
|
| 60 |
+ for k in range(self.r // 2): |
|
| 61 |
+ self.add_voxel((2 * i, 2 * j, 2 * k)) |
|
| 62 |
+ self.remesh() |
|
| 63 |
+ |
|
| 64 |
+ def prof_max(self): |
|
| 65 |
+ for i in range(self.r): |
|
| 66 |
+ for j in range(self.r): |
|
| 67 |
+ for k in range(self.r): |
|
| 68 |
+ if not (i + j + k) % 2: |
|
| 69 |
+ self.add_voxel((i, j, k)) |
|
| 70 |
+ self.remesh() |
|
| 36 | 71 |
|
| 37 | 72 |
def gen_perlin(self, grads): |
| 38 |
- r = self.grid.shape[0] |
|
| 39 | 73 |
corners = np.array([(i, j, k) for i in range(2) for j in range(2) for k in range(2)]) |
| 40 |
- for i in range(r): |
|
| 41 |
- for j in range(r): |
|
| 42 |
- for k in range(r): |
|
| 43 |
- w = np.array((i, j, k)) / r |
|
| 74 |
+ n = 0 |
|
| 75 |
+ for i in range(self.r): |
|
| 76 |
+ for j in range(self.r): |
|
| 77 |
+ for k in range(self.r): |
|
| 78 |
+ w = np.array((i, j, k)) / self.r |
|
| 44 | 79 |
d = [np.dot(grads[*c], w) for c in corners] |
| 45 | 80 |
d = [interp(d[2 * k:2 * (k + 1)], w[2]) for k in range(4)] |
| 46 | 81 |
d = [interp(d[:2], w[1]), interp(d[2:4], w[1])] |
| 47 | 82 |
p = interp(d, w[0]) |
| 48 |
- if p < 0.6: |
|
| 83 |
+ if p > 2 * w[1] - 0.5: |
|
| 49 | 84 |
self.add_voxel((i, j, k)) |
| 85 |
+ n += 1 |
|
| 86 |
+ return n |
|
| 50 | 87 |