Beispiel #1
0
    def convexPoly(
            self,
            vertices,
            dynamic=True,
            density=1.0,
            restitution=0.16,
            friction=0.5):
        """ Add a complex polygon with vertices in absolute positions (meters or pixels, according
            to INPUT_PIXELS or INPUT_METERS). This function does the reduction and convec hulling
            of the poly, and calls add_poly(...)

            Parameters:
              vertices .. absolute vertices positions
              other ..... see [physics parameters]

            Return: box2d.b2Body
        """
        # NOTE: Box2D has a maximum poly vertex count, defined in Common/box2d.b2Settings.h (box2d.b2_maxPolygonVertices)
        # We need to make sure, that we reach that by reducing the poly with increased tolerance
        # Reduce Polygon
        tolerance = 10  # 5
        v_new = vertices
        while len(v_new) > box2d.b2_maxPolygonVertices:
            tolerance += 1
            v_new = tools_poly.reduce_poly(vertices, tolerance)

        print "convexPoly: Polygon reduced from %i to %i vertices | tolerance: %i" % (len(vertices), len(v_new), tolerance)
        vertices = v_new

        # So poly should be alright now
        # Continue reducing the vertecs
        vertices_orig_reduced = vertices
        vertices = tools_poly.poly_center_vertices(vertices)

        vertices = tools_poly.convex_hull(vertices)

        if len(vertices) < 3:
            return

        # Define the body
        x, y = tools_poly.calc_center(vertices_orig_reduced)
        return self.poly((x, y), vertices, dynamic,
                         density, restitution, friction)
Beispiel #2
0
    def convexPoly(self,
                   vertices,
                   dynamic=True,
                   density=1.0,
                   restitution=0.16,
                   friction=0.5):
        """ Add a complex polygon with vertices in absolute positions (meters or pixels, according
            to INPUT_PIXELS or INPUT_METERS). This function does the reduction and convec hulling
            of the poly, and calls add_poly(...)

            Parameters:
              vertices .. absolute vertices positions
              other ..... see [physics parameters]

            Return: box2d.b2Body
        """
        # NOTE: Box2D has a maximum poly vertex count, defined in Common/box2d.b2Settings.h (box2d.b2_maxPolygonVertices)
        # We need to make sure, that we reach that by reducing the poly with increased tolerance
        # Reduce Polygon
        tolerance = 10  # 5
        v_new = vertices
        while len(v_new) > box2d.b2_maxPolygonVertices:
            tolerance += 1
            v_new = tools_poly.reduce_poly(vertices, tolerance)

        print "convexPoly: Polygon reduced from %i to %i vertices | tolerance: %i" % (
            len(vertices), len(v_new), tolerance)
        vertices = v_new

        # So poly should be alright now
        # Continue reducing the vertecs
        vertices_orig_reduced = vertices
        vertices = tools_poly.poly_center_vertices(vertices)

        vertices = tools_poly.convex_hull(vertices)

        if len(vertices) < 3:
            return

        # Define the body
        x, y = tools_poly.calc_center(vertices_orig_reduced)
        return self.poly((x, y), vertices, dynamic, density, restitution,
                         friction)
Beispiel #3
0
    def concavePoly(
            self,
            vertices,
            dynamic=True,
            density=1.0,
            restitution=0.16,
            friction=0.5,
            screenCoord=True):
        # 1. Step: Reduce
        # Detect if the polygon is closed or open
        if vertices[0] != vertices[-1]:
            is_closed = False
        else:
            is_closed = True

        # Continue reducing the vertecs
        x, y = c = tools_poly.calc_center(vertices)
        vertices = tools_poly.poly_center_vertices(vertices)

        # Bring coordinates into the world coordinate system (flip, camera
        # offset, ...)
        if screenCoord:
            x, y = self.parent.to_world(c)
        else:
            x, y = c

        # If required, translate pixel -> meters
        if self.parent.input == INPUT_PIXELS:
            # translate pixel -> meters
            x /= self.parent.ppm
            y /= self.parent.ppm

        # Let's add the body
        bodyDef = box2d.b2BodyDef()
        bodyDef.position = (x, y)

        userData = {'color': self.parent.get_color()}
        bodyDef.userData = userData

        # Create the Body
        if not dynamic:
            density = 0
        else:
            bodyDef.type = box2d.b2_dynamicBody

        body = self.parent.world.CreateBody(bodyDef)

        self.parent.element_count += 1

        # Create the reusable Box2D polygon and circle definitions
        polyDef = box2d.b2PolygonShape()
        polyDef.vertexCount = 4  # rectangle
        polyDef.density = density
        polyDef.restitution = restitution
        polyDef.friction = friction

        circleShape = box2d.b2CircleShape()
        circleShape.radius = radius
        circleDef = box2d.b2FixtureDef()
        circleDef.shape = circleShape
        circleDef.density = density
        circleDef.restitution = restitution
        circleDef.friction = friction

        # Set the scale factor
        factor = 8.0

        v2 = box2d.b2Vec2(*vertices[0])
        for v in vertices[1:]:
            v1 = v2.copy()
            v2 = box2d.b2Vec2(*v)

            vdir = v2 - v1  # (v2x-v1x, v2y-v1y)
            vdir.Normalize()

            # we need a little size for the end part
            vn = box2d.b2Vec2(-vdir.y * factor, vdir.x * factor)

            v = [v1 + vn, v1 - vn, v2 - vn, v2 + vn]

            # Create a line (rect) for each part of the polygon,
            # and attach it to the body
            polyDef.setVertices([vi / self.parent.ppm for vi in v])

            try:
                polyDef.checkValues()
            except ValueError:
                print "concavePoly: Created an invalid polygon!"
                return None

            body.CreateFixture(polyDef)

            # Now add a circle to the points between the rects
            # to avoid sharp edges and gaps
            if not is_closed and v2.tuple() == vertices[-1]:
                # Don't add a circle at the end
                break

            circleDef.localPosition = v2 / self.parent.ppm
            body.CreateFixture(circleDef)

        # Return hard and soft reduced vertices
        return body
Beispiel #4
0
    def concavePoly(self,
                    vertices,
                    dynamic=True,
                    density=1.0,
                    restitution=0.16,
                    friction=0.5,
                    screenCoord=True):
        # 1. Step: Reduce
        # Detect if the polygon is closed or open
        if vertices[0] != vertices[-1]:
            is_closed = False
        else:
            is_closed = True

        # Continue reducing the vertecs
        x, y = c = tools_poly.calc_center(vertices)
        vertices = tools_poly.poly_center_vertices(vertices)

        # Bring coordinates into the world coordinate system (flip, camera
        # offset, ...)
        if screenCoord:
            x, y = self.parent.to_world(c)
        else:
            x, y = c

        # If required, translate pixel -> meters
        if self.parent.input == INPUT_PIXELS:
            # translate pixel -> meters
            x /= self.parent.ppm
            y /= self.parent.ppm

        # Let's add the body
        bodyDef = box2d.b2BodyDef()
        bodyDef.position = (x, y)

        userData = {'color': self.parent.get_color()}
        bodyDef.userData = userData

        # Create the Body
        if not dynamic:
            density = 0
        else:
            bodyDef.type = box2d.b2_dynamicBody

        body = self.parent.world.CreateBody(bodyDef)

        self.parent.element_count += 1

        # Create the reusable Box2D polygon and circle definitions
        polyDef = box2d.b2PolygonShape()
        polyDef.vertexCount = 4  # rectangle
        polyDef.density = density
        polyDef.restitution = restitution
        polyDef.friction = friction

        circleShape = box2d.b2CircleShape()
        circleShape.radius = radius
        circleDef = box2d.b2FixtureDef()
        circleDef.shape = circleShape
        circleDef.density = density
        circleDef.restitution = restitution
        circleDef.friction = friction

        # Set the scale factor
        factor = 8.0

        v2 = box2d.b2Vec2(*vertices[0])
        for v in vertices[1:]:
            v1 = v2.copy()
            v2 = box2d.b2Vec2(*v)

            vdir = v2 - v1  # (v2x-v1x, v2y-v1y)
            vdir.Normalize()

            # we need a little size for the end part
            vn = box2d.b2Vec2(-vdir.y * factor, vdir.x * factor)

            v = [v1 + vn, v1 - vn, v2 - vn, v2 + vn]

            # Create a line (rect) for each part of the polygon,
            # and attach it to the body
            polyDef.setVertices([vi / self.parent.ppm for vi in v])

            try:
                polyDef.checkValues()
            except ValueError:
                print "concavePoly: Created an invalid polygon!"
                return None

            body.CreateFixture(polyDef)

            # Now add a circle to the points between the rects
            # to avoid sharp edges and gaps
            if not is_closed and v2.tuple() == vertices[-1]:
                # Don't add a circle at the end
                break

            circleDef.localPosition = v2 / self.parent.ppm
            body.CreateFixture(circleDef)

        # Return hard and soft reduced vertices
        return body