Refactor WorldRegion and add crosshair
dkl9

dkl9 commited on 2025-170 20:18:15
Showing 6 changed files, with 60 additions and 56 deletions.

... ...
@@ -54,6 +54,9 @@ class Camera:
54 54
         ])
55 55
 
56 56
     def mvp(self, ent):
57
+        if ent.hud:
58
+            return ent.translate() @ ent.orient
59
+        else:
57 60
             return self.persp_mat() @ self.view_mat() @ ent.translate() @ ent.orient
58 61
 
59 62
     def draw(self, ent, loc_mvp):
... ...
@@ -67,7 +70,9 @@ class Camera:
67 70
         l = self.looking()
68 71
         d, c, n = None, None, None
69 72
         for ent in scene:
70
-            if ent.draw_mode == GL_TRIANGLE_STRIP:
73
+            if ent.hud:
74
+                continue
75
+            elif ent.draw_mode == GL_TRIANGLE_STRIP:
71 76
                 tl = ((i, ent.verts[i:i + 3]) for i in range(len(ent.verts) - 2))
72 77
             elif ent.draw_mode == GL_TRIANGLES:
73 78
                 tl = ((i, ent.verts[3 * i:3 * (i + 1)]) for i in range(len(ent.verts) // 3))
... ...
@@ -1,11 +1,12 @@
1 1
 from libs import *
2 2
 
3 3
 class Entity:
4
-    def __init__(self, verts, col, pos, mode=GL_TRIANGLE_STRIP):
4
+    def __init__(self, verts, col, pos, **kwargs):
5 5
         self.verts = vec(verts)
6 6
         self.col = vec(col)
7 7
         self.pos = vec(pos)
8
-        self.draw_mode = mode
8
+        self.draw_mode = kwargs.get("mode", GL_TRIANGLE_STRIP)
9
+        self.hud = kwargs.get("hud", False)
9 10
         self.orient = np.identity(4, dtype=FLOAT)
10 11
         self.onclick = lambda s, b, n: print(f"clicked {s}:{n} with button {b}")
11 12
         self.vao = None
... ...
@@ -3,6 +3,7 @@ import numpy as np
3 3
 import pygame
4 4
 
5 5
 FLOAT = np.float32
6
+VOXEL_TYPE = np.uint8
6 7
 
7 8
 def vec(l):
8 9
     return np.array(l, dtype=FLOAT)
... ...
@@ -1,8 +1,8 @@
1 1
 from OpenGL.GL import shaders
2 2
 from libs import *
3
-from player import Player
4 3
 from entity import Entity
5
-from mesh import SquareMesh
4
+from player import Player
5
+from region import WorldRegion
6 6
 
7 7
 VS = """
8 8
 #version 120
... ...
@@ -24,46 +24,31 @@ void main() {
24 24
 }
25 25
 """
26 26
 
27
-WORLD_SIZE = 8
27
+def click_mesh(self, button, ind):
28
+    a, p = self.faces[ind]
29
+    match button:
30
+        case 1:
31
+            self.del_voxel(ind)
32
+        case 2:
33
+            print(f"face {a} of {p}")
34
+        case 3:
35
+            self.add_voxel(p + np.sign(a) * np.roll([0, 0, 1], abs(a)))
36
+    if button % 2 == 1:
37
+        self.update_attr(0)
38
+        self.update_attr(1)
28 39
 
29
-world = np.zeros((WORLD_SIZE, WORLD_SIZE, WORLD_SIZE), dtype=np.uint8)
40
+def build_scene():
41
+    box = WorldRegion()
30 42
     for i in range(2):
31 43
         for j in range(2):
32 44
             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
-
57
-def build_scene():
58
-    box = SquareMesh()
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))
45
+                box.add_voxel((-i % 16, -j % 16, -k % 16))
65 46
     box.onclick = click_mesh
66
-    return [box]
47
+    cross = Entity(
48
+        [[-0.05, 0.0, 0.0], [0.05, 0.0, 0.0], [0.0, -0.05, 0.0], [0.0, 0.05, 0.0]],
49
+        [0.9, 0.9, 0.9, 1.0], [0.0, 0.0, 0.0], mode=GL_LINES, hud=True
50
+    )
51
+    return [box, cross]
67 52
 
68 53
 def main():
69 54
     pygame.init()
... ...
@@ -15,11 +15,11 @@ class SquareMesh(entity.Entity):
15 15
             np.empty((0, 3), dtype=FLOAT),
16 16
             [0.0, 1.0, 0.0, 1.0],
17 17
             [0.0, 0.0, 0.0],
18
-            GL_TRIANGLES
18
+            mode=GL_TRIANGLES
19 19
         )
20 20
         self.faces = []
21 21
 
22
-    def add_sq(self, axis, width, pos):
22
+    def add_sq(self, axis, width, pos, fd=1):
23 23
         w = width / 2
24 24
         sq = pos + np.roll(vec([
25 25
             [w, w, 0], [-w, w, 0], [w, -w, 0],
... ...
@@ -29,21 +29,11 @@ class SquareMesh(entity.Entity):
29 29
             sq = np.flip(sq, 0)
30 30
         self.verts = np.concatenate((self.verts, sq), dtype=FLOAT)
31 31
         for i in range(2):
32
-            self.faces.append((axis, 1))
32
+            self.faces.append((axis, fd))
33 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)
34
+    def del_sq(self, ind):
35
+        self.verts = np.delete(self.verts, np.s_[3 * ind:3 * (ind + 2)], 0)
36
+        del self.faces[ind:ind + 2]
47 37
 
48 38
     def col_list(self):
49 39
         return np.repeat([cube_col(x[0]) for x in self.faces], 3, 0)
... ...
@@ -0,0 +1,22 @@
1
+from libs import *
2
+import mesh
3
+
4
+class WorldRegion(mesh.SquareMesh):
5
+    def __init__(self, size=16):
6
+        super().__init__()
7
+        self.grid = np.zeros((size, size, size), dtype=VOXEL_TYPE)
8
+
9
+    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
17
+
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)
0 23