dkl9 commited on 2025-170 19:41:48
Showing 5 changed files, with 99 additions and 13 deletions.
| ... | ... |
@@ -65,16 +65,16 @@ class Camera: |
| 65 | 65 |
|
| 66 | 66 |
def target(self, scene): |
| 67 | 67 |
l = self.looking() |
| 68 |
- d, c = None, None |
|
| 68 |
+ d, c, n = None, None, None |
|
| 69 | 69 |
for ent in scene: |
| 70 | 70 |
if ent.draw_mode == GL_TRIANGLE_STRIP: |
| 71 |
- tl = (ent.verts[i:i + 3] for i in range(len(ent.verts) - 2)) |
|
| 71 |
+ tl = ((i, ent.verts[i:i + 3]) for i in range(len(ent.verts) - 2)) |
|
| 72 | 72 |
elif ent.draw_mode == GL_TRIANGLES: |
| 73 |
- tl = (ent.verts[3 * i:3 * (i + 1)] for i in range(len(ent.verts) // 3)) |
|
| 73 |
+ tl = ((i, ent.verts[3 * i:3 * (i + 1)]) for i in range(len(ent.verts) // 3)) |
|
| 74 | 74 |
else: |
| 75 | 75 |
raise NotImplementedError |
| 76 |
- for t in tl: |
|
| 76 |
+ for (i, t) in tl: |
|
| 77 | 77 |
r = intersect_tri(self.pos, l, np.dot(t, ent.orient[:3, :3].T) + ent.pos) |
| 78 | 78 |
if r and (d is None or r < d): |
| 79 |
- d, c = r, ent |
|
| 80 |
- return c |
|
| 79 |
+ d, c, n = r, ent, i |
|
| 80 |
+ return c, n |
| ... | ... |
@@ -7,7 +7,7 @@ class Entity: |
| 7 | 7 |
self.pos = vec(pos) |
| 8 | 8 |
self.draw_mode = mode |
| 9 | 9 |
self.orient = np.identity(4, dtype=FLOAT) |
| 10 |
- self.onclick = lambda s, b: print(f"clicked {s} with button {b}")
|
|
| 10 |
+ self.onclick = lambda s, b, n: print(f"clicked {s}:{n} with button {b}")
|
|
| 11 | 11 |
self.vao = None |
| 12 | 12 |
self.vbos = [[None, 0], [None, 0]] |
| 13 | 13 |
|
| ... | ... |
@@ -19,7 +19,7 @@ class Entity: |
| 19 | 19 |
l = self.verts if i == 0 else self.col_list() |
| 20 | 20 |
if self.vao: |
| 21 | 21 |
glBindBuffer(GL_ARRAY_BUFFER, self.vbos[i][0]) |
| 22 |
- if l.shape[0] > self.vbos[i][1]: |
|
| 22 |
+ if l.shape[0] != self.vbos[i][1]: |
|
| 23 | 23 |
glBufferData(GL_ARRAY_BUFFER, l.nbytes, l, GL_DYNAMIC_DRAW) |
| 24 | 24 |
self.vbos[i][1] = l.shape[0] |
| 25 | 25 |
else: |
| ... | ... |
@@ -50,5 +50,5 @@ class Entity: |
| 50 | 50 |
[0, 0, 0, 1] |
| 51 | 51 |
]) @ self.orient |
| 52 | 52 |
|
| 53 |
- def click(self, button): |
|
| 54 |
- self.onclick(self, button) |
|
| 53 |
+ def click(self, button, face): |
|
| 54 |
+ self.onclick(self, button, face) |
| ... | ... |
@@ -24,9 +24,45 @@ void main() {
|
| 24 | 24 |
} |
| 25 | 25 |
""" |
| 26 | 26 |
|
| 27 |
+WORLD_SIZE = 8 |
|
| 28 |
+ |
|
| 29 |
+world = np.zeros((WORLD_SIZE, WORLD_SIZE, WORLD_SIZE), dtype=np.uint8) |
|
| 30 |
+for i in range(2): |
|
| 31 |
+ for j in range(2): |
|
| 32 |
+ for k in range(2): |
|
| 33 |
+ world[-i % WORLD_SIZE, -j % WORLD_SIZE, -k % WORLD_SIZE] = 1 |
|
| 34 |
+cubes = [] |
|
| 35 |
+ |
|
| 36 |
+def place_voxel(mesh, ind): |
|
| 37 |
+ a = mesh.faces[ind][0] |
|
| 38 |
+ p = cubes[ind // 12] + np.sign(a) * np.roll([0, 0, 1], abs(a)) |
|
| 39 |
+ world[p] = 1 |
|
| 40 |
+ mesh.add_cube(1, p) |
|
| 41 |
+ cubes.append(p) |
|
| 42 |
+ mesh.update_attr(0) |
|
| 43 |
+ mesh.update_attr(1) |
|
| 44 |
+ |
|
| 45 |
+def break_voxel(mesh, ind): |
|
| 46 |
+ p = cubes[ind // 12] |
|
| 47 |
+ world[p] = 0 |
|
| 48 |
+ mesh.del_cube((ind // 12) * 12) |
|
| 49 |
+ del cubes[ind // 12] |
|
| 50 |
+ |
|
| 51 |
+def click_mesh(self, button, ind): |
|
| 52 |
+ if button == 1: |
|
| 53 |
+ break_voxel(self, ind) |
|
| 54 |
+ elif button == 3: |
|
| 55 |
+ place_voxel(self, ind) |
|
| 56 |
+ |
|
| 27 | 57 |
def build_scene(): |
| 28 | 58 |
box = SquareMesh() |
| 29 |
- box.add_cube(2, [0, 0, 0]) |
|
| 59 |
+ for i in range(world.shape[0]): |
|
| 60 |
+ for j in range(world.shape[1]): |
|
| 61 |
+ for k in range(world.shape[2]): |
|
| 62 |
+ if world[i, j, k] == 1: |
|
| 63 |
+ box.add_cube(1, [i, j, k]) |
|
| 64 |
+ cubes.append(np.array((i, j, k), dtype=np.uint8)) |
|
| 65 |
+ box.onclick = click_mesh |
|
| 30 | 66 |
return [box] |
| 31 | 67 |
|
| 32 | 68 |
def main(): |
| ... | ... |
@@ -0,0 +1,49 @@ |
| 1 |
+from libs import * |
|
| 2 |
+import entity |
|
| 3 |
+ |
|
| 4 |
+def cube_col(axis): |
|
| 5 |
+ return vec([ |
|
| 6 |
+ [0.0, 0.0, 0.0, 1.0], |
|
| 7 |
+ [1.0, 0.0, 0.0, 1.0], |
|
| 8 |
+ [0.0, 1.0, 0.0, 1.0], |
|
| 9 |
+ [0.0, 0.0, 1.0, 1.0] |
|
| 10 |
+ ][abs(axis)]) + 0.4 * np.sign(axis, dtype=FLOAT) |
|
| 11 |
+ |
|
| 12 |
+class SquareMesh(entity.Entity): |
|
| 13 |
+ def __init__(self): |
|
| 14 |
+ super().__init__( |
|
| 15 |
+ np.empty((0, 3), dtype=FLOAT), |
|
| 16 |
+ [0.0, 1.0, 0.0, 1.0], |
|
| 17 |
+ [0.0, 0.0, 0.0], |
|
| 18 |
+ GL_TRIANGLES |
|
| 19 |
+ ) |
|
| 20 |
+ self.faces = [] |
|
| 21 |
+ |
|
| 22 |
+ def add_sq(self, axis, width, pos): |
|
| 23 |
+ w = width / 2 |
|
| 24 |
+ sq = pos + np.roll(vec([ |
|
| 25 |
+ [w, w, 0], [-w, w, 0], [w, -w, 0], |
|
| 26 |
+ [-w, -w, 0], [w, -w, 0], [-w, w, 0] |
|
| 27 |
+ ]), abs(axis), 1) |
|
| 28 |
+ if axis < 0: |
|
| 29 |
+ sq = np.flip(sq, 0) |
|
| 30 |
+ self.verts = np.concatenate((self.verts, sq), dtype=FLOAT) |
|
| 31 |
+ for i in range(2): |
|
| 32 |
+ self.faces.append((axis, 1)) |
|
| 33 |
+ |
|
| 34 |
+ def add_cube(self, width, pos): |
|
| 35 |
+ offset = vec([width / 2, 0, 0]) |
|
| 36 |
+ for a in range(1, 4): |
|
| 37 |
+ self.add_sq(a, width, pos + offset) |
|
| 38 |
+ self.add_sq(-a, width, pos - offset) |
|
| 39 |
+ offset = np.roll(offset, 1, 0) |
|
| 40 |
+ return len(self.faces) - 12 |
|
| 41 |
+ |
|
| 42 |
+ def del_cube(self, ind): |
|
| 43 |
+ self.verts = np.delete(self.verts, np.s_[3 * ind:3 * (ind + 12)], 0) |
|
| 44 |
+ del self.faces[ind:ind + 12] |
|
| 45 |
+ self.update_attr(0) |
|
| 46 |
+ self.update_attr(1) |
|
| 47 |
+ |
|
| 48 |
+ def col_list(self): |
|
| 49 |
+ return np.repeat([cube_col(x[0]) for x in self.faces], 3, 0) |
| ... | ... |
@@ -55,8 +55,9 @@ class Player(camera.Camera): |
| 55 | 55 |
if ev.button == 1: |
| 56 | 56 |
self.set_focus(True) |
| 57 | 57 |
case pygame.MOUSEBUTTONDOWN: |
| 58 |
- t = self.target(scene) |
|
| 58 |
+ if self.get_focus(): |
|
| 59 |
+ t, n = self.target(scene) |
|
| 59 | 60 |
if t: |
| 60 |
- t.click(ev.button) |
|
| 61 |
+ t.click(ev.button, n) |
|
| 61 | 62 |
case pygame.WINDOWSIZECHANGED | pygame.WINDOWRESIZED: |
| 62 | 63 |
self.aspect = reshape(ev.x, ev.y) |
| 63 | 64 |