from libs import * import interactive import entity import mesh class Player(interactive.InteractiveCamera): def __init__(self, **kwargs): super().__init__(**kwargs) self.hud["fps"] = entity.Entity( [[0.0, 0.0, 0.0], [0.1, 0.0, 0.0], [0.0, -0.1, 0.0], [0.1, -0.1, 0.0]], YELLOW, [-1.0, 1.0, 0.0], mode=GL_TRIANGLE_STRIP, hud=True ) self.hud["skybox"] = mesh.SquareMesh() offset = [0, 0, VIEW_DIST] for d in range(3): roll_vec3(offset, 1) for s in range(2): self.hud["skybox"].add_sq((d + 1) * (-1) ** s, 2 * VIEW_DIST, (-1) ** s * vec(offset), 2) self.hud["sun"] = entity.Entity( [[0.0, 0.0, 0.0], *[[2 * np.cos(2 * np.pi * k), 0, 2 * np.sin(2 * np.pi * k)] for k in np.arange(0, 1.01, 0.05)]], [1.0, 1.0, 0.8, 1.0], normalise(LIGHT_POS) * VIEW_DIST, mode=GL_TRIANGLE_FAN ) h = mesh.SquareMesh(hud=True) self.hud["hand"] = h h.add_sq(1, 1, [0.5, 0, 0], 1) h.add_sq(2, 1, [0, 0.5, 0], 1) h.add_sq(3, 1, [0, 0, 0.5], 1) h.pos = [0.8, -0.8, 0.5] h.rotate(2, [0, 1, 0]) h.rotate(-0.1, [1, 0, 0]) h.orient[:3, :3] *= 0.2 self.hud["shl"] = mesh.SquareMesh() self.hud["shl"].draw_mode = GL_LINE_STRIP self.hud["shl"].add_sq(-2, 0.96, [0, 0, 0], 2) self.hud["shl"].verts[:] = self.hud["shl"].verts[[0, 1, 3, 2, 0, 3]] self.hand = 1 self.collides = True self.falls = True def update_motion(self, pk, mg): netv = [pk[a] - pk[b] for (a, b) in zip(ARROWS[::2], ARROWS[1::2])] if self.collides: for i in range(len(netv)): for s in range(2): o = (-1) ** s * self.vdof()[i] va = mg.voxel_at(self.pos + o) if va: netv[i] = (max if s else min)(netv[i], 0) elif self.falls and i == 1 and s == 1: netv[i] = self.rv[i] - GRAVITY / FPS self.rv = vec(netv) def set_hand(self, nh): nh = int(nh) self.hand = nh self.hud["hand"].faces = [(a, self.hand) for (a, _) in self.hud["hand"].faces] for i in range(1, 4, 2): update_attr(self.hud["hand"], i) def handle_event(self, ev, mg, scene): super().handle_event(ev, mg) match ev.type: case pygame.KEYUP: if ev.unicode == "\x1b": self.set_focus(False) elif "1" <= ev.unicode <= "9": self.set_hand(int(ev.unicode)) elif ev.unicode == "n": self.collides = not self.collides elif ev.unicode == "f": self.falls = not self.falls case pygame.MOUSEBUTTONUP if ev.button == 1: self.set_focus(True) case pygame.MOUSEBUTTONDOWN if self.get_focus(): t, n = self.target(scene) if t: cr = t.click(ev.button, n, self.hand) if cr is not None: cr(self) def draw_hud(self, wrs, perf): self.hud["skybox"].pos = self.pos c, ap = self.target(wrs) if c: self.hud["shl"].pos = c.pos + ap[1] + axis2offset(ap[0], 0.52) self.hud["shl"].orient[:3, :3] = np.sign(ap[0]) * np.roll(np.identity(3), abs(ap[0]) + 1, 0) else: self.hud["shl"].pos = vec([0, 0, 0]) self.hud["fps"].col = GREEN if 0.9 < perf < 1.1 else YELLOW if perf > 0.5 else RED update_attr(self.hud["fps"], "col") for ent in self.hud.values(): self.draw(ent)