dkl9 commited on 2025-172 08:49:54
Showing 3 changed files, with 43 additions and 15 deletions.
| ... | ... |
@@ -36,15 +36,14 @@ def click_mesh(self, button, ind): |
| 36 | 36 |
case 3: |
| 37 | 37 |
self.add_voxel(p + np.sign(a) * np.roll([0, 0, 1], abs(a))) |
| 38 | 38 |
if button % 2 == 1: |
| 39 |
+ self.remesh() |
|
| 39 | 40 |
self.update_attr(0) |
| 40 | 41 |
self.update_attr(1) |
| 41 | 42 |
|
| 42 | 43 |
def build_scene(): |
| 43 | 44 |
box = WorldRegion() |
| 44 |
- for i in range(2): |
|
| 45 |
- for j in range(2): |
|
| 46 |
- for k in range(2): |
|
| 47 |
- box.add_voxel((-i % 16, -j % 16, -k % 16)) |
|
| 45 |
+ box.gen_perlin(np.random.rand(2, 2, 2, 3)) |
|
| 46 |
+ box.remesh() |
|
| 48 | 47 |
box.onclick = click_mesh |
| 49 | 48 |
return [box] |
| 50 | 49 |
|
| ... | ... |
@@ -63,6 +62,7 @@ def main(): |
| 63 | 62 |
scene = build_scene() |
| 64 | 63 |
clock = pygame.time.Clock() |
| 65 | 64 |
cam = Player() |
| 65 |
+ cam.pos = [8, 16, 8] |
|
| 66 | 66 |
cam.set_focus(True) |
| 67 | 67 |
while True: |
| 68 | 68 |
for ev in pygame.event.get(): |
| ... | ... |
@@ -1,22 +1,49 @@ |
| 1 | 1 |
from libs import * |
| 2 | 2 |
import mesh |
| 3 | 3 |
|
| 4 |
+def smoothstep(x): |
|
| 5 |
+ return x ** 2 * (3 - 2 * x) |
|
| 6 |
+ |
|
| 7 |
+def interp(ab, t): |
|
| 8 |
+ return ab[0] + smoothstep(t) * (ab[1] - ab[0]) |
|
| 9 |
+ |
|
| 4 | 10 |
class WorldRegion(mesh.SquareMesh): |
| 5 | 11 |
def __init__(self, size=16): |
| 6 | 12 |
super().__init__() |
| 7 | 13 |
self.grid = np.zeros((size, size, size), dtype=VOXEL_TYPE) |
| 8 | 14 |
|
| 9 | 15 |
def add_voxel(self, pos, vt=1): |
| 10 |
- offset = vec([0.5, 0.0, 0.0]) |
|
| 11 |
- for a in range(1, 4): |
|
| 12 |
- self.add_sq(a, 1, pos + offset, pos) |
|
| 13 |
- self.add_sq(-a, 1, pos - offset, pos) |
|
| 14 |
- offset = np.roll(offset, 1, 0) |
|
| 15 |
- self.grid[pos] = vt |
|
| 16 |
- return len(self.faces) - 12 |
|
| 16 |
+ self.grid[*pos] = vt |
|
| 17 | 17 |
|
| 18 | 18 |
def del_voxel(self, ind): |
| 19 |
- b = (ind // 12) * 12 |
|
| 20 |
- self.grid[self.faces[ind][1]] = 0 |
|
| 21 |
- for i in range(6): |
|
| 22 |
- self.del_sq(b) |
|
| 19 |
+ self.grid[*self.faces[ind][1]] = 0 |
|
| 20 |
+ |
|
| 21 |
+ def remesh(self): |
|
| 22 |
+ offset = vec([0.5, 0.0, 0.0]) |
|
| 23 |
+ r = self.grid.shape[0] |
|
| 24 |
+ self.verts = np.empty((0, 3), dtype=FLOAT) |
|
| 25 |
+ 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]: |
|
| 31 |
+ 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) |
|
| 36 |
+ |
|
| 37 |
+ def gen_perlin(self, grads): |
|
| 38 |
+ r = self.grid.shape[0] |
|
| 39 |
+ 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 |
|
| 44 |
+ d = [np.dot(grads[*c], w) for c in corners] |
|
| 45 |
+ d = [interp(d[2 * k:2 * (k + 1)], w[2]) for k in range(4)] |
|
| 46 |
+ d = [interp(d[:2], w[1]), interp(d[2:4], w[1])] |
|
| 47 |
+ p = interp(d, w[0]) |
|
| 48 |
+ if p < 0.6: |
|
| 49 |
+ self.add_voxel((i, j, k)) |
|
| 23 | 50 |