From 071431133ac96f5f6eb01729547ef593f1ad89ab Mon Sep 17 00:00:00 2001 From: Simon Cross Date: Wed, 7 Sep 2016 23:29:41 +0200 Subject: [PATCH] Changing polys (badly). --- tabakrolletjie/rays.py | 87 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 12 deletions(-) diff --git a/tabakrolletjie/rays.py b/tabakrolletjie/rays.py index f7e69cc..f893828 100644 --- a/tabakrolletjie/rays.py +++ b/tabakrolletjie/rays.py @@ -1,5 +1,7 @@ """ Light ray manipulation. Pew. Pew. Pew. Wommmm. """ +import math + import pymunk import pymunk.autogeometry import pymunk.pygame_util @@ -26,8 +28,12 @@ def screen_rays(pos): yield pymunk.Vec2d(x, bottom) -@debug_timer("rays.calculate_ray_polys", True) +@debug_timer("rays.calculate_ray_polys") def calculate_ray_polys(space, position, light_filter): + """ Calculate a set of convex RayPolys that cover all the areas that light + can reach from the given position, taking into account the obstacles + present in the space. + """ position = pymunk.Vec2d(position) vertices = [position] start, end = None, None @@ -44,7 +50,8 @@ def calculate_ray_polys(space, position, light_filter): query_prev = trial_poly.point_query(end) query_pos = trial_poly.point_query(position) if query_prev.distance < -0.01 or query_pos.distance < -0.01: - ray_polys.append(RayPoly(start, end, vertices[:-1])) + ray_polys.append(RayPoly( + start - position, end - position, vertices[:-1])) start = vertices[-1] vertices = [position, start] else: @@ -55,26 +62,68 @@ def calculate_ray_polys(space, position, light_filter): return ray_polys +def to_pymunk_radians(deg): + """ Convert degrees in [0, 360] to radians in (-pi, pi]. + + Return None if degrees is None. + """ + if deg is None: + return None + deg = deg * math.pi / 180.0 + if deg > math.pi: + deg -= 2 * math.pi + return deg + + class RayPolyManager(object): def __init__(self, body, ray_filter): self._body = body self._ray_filter = ray_filter self._rays = [] + self._angle_limits = (None, None) + self._poly_cache = None + self._pygame_poly_cache = None def generate_rays(self, space, position): self._rays = calculate_ray_polys(space, position, self._ray_filter) + self._poly_cache = None + self._pygame_poly_cache = None + + def set_angle_limits(self, angle_limits): + start, end = angle_limits + self._angle_limits = ( + to_pymunk_radians(start), to_pymunk_radians(end)) + self._poly_cache = None + self._pygame_poly_cache = None def polys(self): - return [rp.poly(self._body, self._ray_filter) for rp in self._rays] + if self._poly_cache is None: + print "====" + self._poly_cache = [ + rp.poly(self._body, self._ray_filter) for rp in self._rays + if rp.within_limits(*self._angle_limits) + ] + print "====" + + return self._poly_cache def pygame_polys(self, surface): - return [rp.pygame_poly(surface) for rp in self._rays] + if self._pygame_poly_cache is None: + print "REGEN ...", self._angle_limits + self._pygame_poly_cache = [ + [ + pymunk.pygame_util.to_pygame(v, surface) + for v in poly.get_vertices() + ] + for poly in self.polys() + ] + return self._pygame_poly_cache class RayPoly(object): - def __init__(self, start, end, vertices): - self.start = start - self.end = end + def __init__(self, start_vec, end_vec, vertices): + self.start = start_vec # vector from position to first point + self.end = end_vec # vector from position to last point self.vertices = vertices def poly(self, body, filter): @@ -82,8 +131,22 @@ class RayPoly(object): shape.filter = filter return shape - def pygame_poly(self, surface): - return [ - pymunk.pygame_util.to_pygame(v, surface) - for v in self.vertices - ] + def within_limits(self, start_limit, end_limit): + if start_limit is None or end_limit is None: + return True + print "----" + print "LIM: ", start_limit, end_limit + print "ANG: ", self.start.angle, self.end.angle + n1 = self.start.normalized() + n2 = self.end.normalized() + s = pymunk.Vec2d(1, 0).rotated(start_limit) + e = pymunk.Vec2d(1, 0).rotated(end_limit) + n1bet = s.dot(e) < s.dot(n1) and s.dot(e) < s.dot(n1) + n2bet = s.dot(e) < e.dot(n2) and s.dot(e) < e.dot(n2) + print "DOTS n1: ", n1.dot(n2), n1.dot(s), n2.dot(s) + print "DOTS n2: ", n1.dot(n2), n1.dot(e), n2.dot(e) + print "BET: ", n1bet, n2bet + if n1bet: + print "TRUE\n----" + return True + return False -- 2.34.1