1 """ Light ray manipulation. Pew. Pew. Pew. Wommmm. """
4 import pymunk.autogeometry
5 import pymunk.pygame_util
7 from .constants import SCREEN_SIZE
8 from .utils import debug_timer
12 """ An iterable that returns ordered rays from pos to the edge of the
13 screen, starting with the edge point (0, 0) and continuing clockwise
14 in pymunk coordinates.
17 left, right, bottom, top = 0, w, 0, h
19 for y in range(0, h, step):
20 yield pymunk.Vec2d(left, y)
21 for x in range(0, w, step):
22 yield pymunk.Vec2d(x, top)
23 for y in range(top, -1, -step):
24 yield pymunk.Vec2d(right, y)
25 for x in range(right, -1, -step):
26 yield pymunk.Vec2d(x, bottom)
29 @debug_timer("rays.calculate_ray_polys", True)
30 def calculate_ray_polys(space, position, light_filter):
31 position = pymunk.Vec2d(position)
33 start, end = None, None
35 for ray in screen_rays(position):
36 info = space.segment_query_first(position, ray, 1, light_filter)
37 point = ray if info is None else info.point
38 vertices.append(point)
39 if len(vertices) == 2:
41 elif len(vertices) > 3:
42 trial_poly = pymunk.Poly(None, vertices)
43 trial_poly.update(pymunk.Transform.identity())
44 query_prev = trial_poly.point_query(end)
45 query_pos = trial_poly.point_query(position)
46 if query_prev.distance < -0.01 or query_pos.distance < -0.01:
47 ray_polys.append(RayPoly(start, end, vertices[:-1]))
49 vertices = [position, start]
51 vertices = trial_poly.get_vertices()
54 ray_polys.append(RayPoly(start, end, vertices))
58 class RayPolyManager(object):
59 def __init__(self, body, ray_filter):
61 self._ray_filter = ray_filter
64 def generate_rays(self, space, position):
65 self._rays = calculate_ray_polys(space, position, self._ray_filter)
68 return [rp.poly(self._body, self._ray_filter) for rp in self._rays]
70 def pygame_polys(self, surface):
71 return [rp.pygame_poly(surface) for rp in self._rays]
74 class RayPoly(object):
75 def __init__(self, start, end, vertices):
78 self.vertices = vertices
80 def poly(self, body, filter):
81 shape = pymunk.Poly(body, self.vertices)
85 def pygame_poly(self, surface):
87 pymunk.pygame_util.to_pygame(v, surface)
88 for v in self.vertices