Esempio n. 1
0
 def to_b2vec(self, pt):
     pt = self.parent.to_world(pt)
     ptx, pty = pt
     ptx /= self.parent.ppm
     pty /= self.parent.ppm
     pt = box2d.b2Vec2(ptx, pty)
     return pt
Esempio n. 2
0
 def to_b2vec(self,pt):
     pt = self.parent.to_world(pt)
     ptx, pty = pt
     ptx /= self.parent.ppm
     pty /= self.parent.ppm
     pt = box2d.b2Vec2(ptx, pty)
     return pt    
Esempio n. 3
0
    def _rect(self, pos, width, height, angle=0, dynamic=True, density=1.0, restitution=0.16, friction=0.5):
        # Add a rect without correcting any settings
        # meaning, pos and vertices are in meters
        # angle is now in radians ((degrees * pi) / 180))
        x, y = pos
        bodyDef = box2d.b2BodyDef()
        bodyDef.position.Set(x, y)

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

        # Create the Body
        if not dynamic:
            density = 0

	bodyDef.sleepFlag = True

        body = self.parent.world.CreateBody(bodyDef)
                    
        self.parent.element_count += 1

        # Add a shape to the Body
        boxDef = box2d.b2PolygonDef()
        
        boxDef.SetAsBox(width, height, box2d.b2Vec2(0,0), angle)
        boxDef.density = density
        boxDef.restitution = restitution
        boxDef.friction = friction
        body.CreateShape(boxDef)
        
        body.SetMassFromShapes()
        
        return body
Esempio n. 4
0
    def _poly(self, pos, vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5):
        # add a centered poly at pos without correcting any settings
        # meaning, pos and vertices are in meters
        x, y = pos
        bodyDef = box2d.b2BodyDef()
        bodyDef.position.Set(x, y)
	bodyDef.sleepFlag = True
            
        userData = { 'color' : self.parent.get_color() }
        bodyDef.userData = userData

        # Create the Body
        if not dynamic:
            density = 0

        body = self.parent.world.CreateBody(bodyDef)
        
        self.parent.element_count += 1

        # Add a shape to the Body
        polyDef = box2d.b2PolygonDef()
        polyDef.vertexCount = len(vertices)
        for i in range(len(vertices)):
            vx, vy = vertices[i]
            polyDef.setVertex(i, box2d.b2Vec2(vx, vy))        
        
        polyDef.density = density
        polyDef.restitution = restitution
        polyDef.friction = friction

        body.CreateShape(polyDef)
        body.SetMassFromShapes()
                
        return body
Esempio n. 5
0
    def prismaticJoint(self,b1,b2,Axis=(0.0,1.0),lower=-2,upper=2):
        jointDef = box2d.b2PrismaticJointDef()
        worldAxis = box2d.b2Vec2(Axis[0],Axis[1])
        jointDef.Initialize(b1, b2, b1.GetWorldCenter(), worldAxis)
        jointDef.lowerTranslation = lower
        jointDef.upperTranslation = upper
        jointDef.enableLimit = True

        self.parent.world.CreateJoint(jointDef)
Esempio n. 6
0
    def prismaticJoint(self, b1, b2, Axis=(0.0, 1.0), lower=-2, upper=2):
        jointDef = box2d.b2PrismaticJointDef()
        worldAxis = box2d.b2Vec2(Axis[0], Axis[1])
        jointDef.Initialize(b1, b2, b1.GetWorldCenter(), worldAxis)
        jointDef.lowerTranslation = lower
        jointDef.upperTranslation = upper
        jointDef.enableLimit = True

        self.parent.world.CreateJoint(jointDef)
Esempio n. 7
0
def checkDef(pd):
    """Check the polygon definition for invalid vertices, etc.

       Return: True if valid, False if invalid
    """

    #    if pd.vertexCount < 3 or pd.vertexCount > box2d.b2_maxPolygonVertices:
    #raise ValueError, "Invalid vertexCount"

    threshold = FLT_EPSILON * FLT_EPSILON
    verts = pd.getVertices_b2Vec2()
    normals = []
    v0 = verts[0]
    for i in range(pd.vertexCount):
        if i == pd.vertexCount - 1:
            v1 = verts[0]
        else:
            v1 = verts[i + 1]
        edge = v1 - v0
        #        if edge.LengthSquared() < threshold:
        #           raise ValueError, "edge.LengthSquared < FLT_EPSILON**2"
        normals.append(box2d.b2Cross(edge, 1.0))
        normals[-1].Normalize()
        v0 = v1

    centroid = ComputeCentroid(pd)

    d = box2d.b2Vec2()
    for i in range(pd.vertexCount):
        i1 = i - 1
        if i1 < 0: i1 = pd.vertexCount - 1
        i2 = i
        n1 = normals[i1]
        n2 = normals[i2]
        v = verts[i] - centroid

        d.x = box2d.b2Dot(n1, v) - box2d.b2_toiSlop
        d.y = box2d.b2Dot(n2, v) - box2d.b2_toiSlop

        # Shifting the edge inward by b2_toiSlop should
        # not cause the plane to pass the centroid.

        # Your shape has a radius/extent less than b2_toiSlop.
        #        if d.x < 0.0 or d.y <= 0.0:
        #            raise ValueError, "Your shape has a radius/extent less than b2_toiSlop."

        A = box2d.b2Mat22()
        A.col1.x = n1.x
        A.col2.x = n1.y
        A.col1.y = n2.x
        A.col2.y = n2.y

#coreVertices[i] = A.Solve(d) + m_centroid

    return True
Esempio n. 8
0
def checkDef(pd):
    """Check the polygon definition for invalid vertices, etc.

       Return: True if valid, False if invalid
    """

    #    if pd.vertexCount < 3 or pd.vertexCount > box2d.b2_maxPolygonVertices:
    # raise ValueError, "Invalid vertexCount"

    threshold = FLT_EPSILON * FLT_EPSILON
    verts = pd.getVertices_b2Vec2()
    normals = []
    v0 = verts[0]
    for i in range(pd.vertexCount):
        if i == pd.vertexCount - 1:
            v1 = verts[0]
        else:
            v1 = verts[i + 1]
        edge = v1 - v0
        #        if edge.LengthSquared() < threshold:
        #           raise ValueError, "edge.LengthSquared < FLT_EPSILON**2"
        normals.append(box2d.b2Cross(edge, 1.0))
        normals[-1].Normalize()
        v0 = v1

    centroid = ComputeCentroid(pd)

    d = box2d.b2Vec2()
    for i in range(pd.vertexCount):
        i1 = i - 1
        if i1 < 0:
            i1 = pd.vertexCount - 1
        i2 = i
        n1 = normals[i1]
        n2 = normals[i2]
        v = verts[i] - centroid

        d.x = box2d.b2Dot(n1, v) - box2d.b2_toiSlop
        d.y = box2d.b2Dot(n2, v) - box2d.b2_toiSlop

        # Shifting the edge inward by b2_toiSlop should
        # not cause the plane to pass the centroid.

        # Your shape has a radius/extent less than b2_toiSlop.
        #        if d.x < 0.0 or d.y <= 0.0:
        #            raise ValueError, "Your shape has a radius/extent less than b2_toiSlop."

        A = box2d.b2Mat22()
        A.col1.x = n1.x
        A.col2.x = n1.y
        A.col1.y = n2.x
        A.col2.y = n2.y
        # coreVertices[i] = A.Solve(d) + m_centroid

    return True
Esempio n. 9
0
    def joint(self, *args):        
        print "* Add Joint:", args

        if len(args) == 4:
            # Distance Joint
            b1, b2, p1, p2 = args

            p1 = self.parent.to_world(p1)            
            p2 = self.parent.to_world(p2)            
            
            p1x, p1y = p1
            p2x, p2y = p2
            
            p1x /= self.parent.ppm
            p1y /= self.parent.ppm
            p2x /= self.parent.ppm
            p2y /= self.parent.ppm
            
            p1 = box2d.b2Vec2(p1x, p1y)
            p2 = box2d.b2Vec2(p2x, p2y)
            
            jointDef = box2d.b2DistanceJointDef()
            jointDef.Initialize(b1, b2, p1, p2)
            jointDef.collideConnected = True
            
            self.parent.world.CreateJoint(jointDef)           
             
        elif len(args) == 3:
            # Revolute Joint
            pass

        elif len(args) == 1:
            # Fixed Joint to the Background, assume the center of the body
            b1 = self.parent.world.GetGroundBody()
            b2 = args[0]
            p1 = b2.GetWorldCenter()
            
            jointDef = box2d.b2RevoluteJointDef()
            jointDef.Initialize(b1, b2, p1)
            
            self.parent.world.CreateJoint(jointDef)
Esempio n. 10
0
    def joint(self, *args):
        print "* Add Joint:", args

        if len(args) == 4:
            # Distance Joint
            b1, b2, p1, p2 = args

            p1 = self.parent.to_world(p1)
            p2 = self.parent.to_world(p2)

            p1x, p1y = p1
            p2x, p2y = p2

            p1x /= self.parent.ppm
            p1y /= self.parent.ppm
            p2x /= self.parent.ppm
            p2y /= self.parent.ppm

            p1 = box2d.b2Vec2(p1x, p1y)
            p2 = box2d.b2Vec2(p2x, p2y)

            jointDef = box2d.b2DistanceJointDef()
            jointDef.Initialize(b1, b2, p1, p2)
            jointDef.collideConnected = True

            self.parent.world.CreateJoint(jointDef)

        elif len(args) == 3:
            # Revolute Joint
            pass

        elif len(args) == 1:
            # Fixed Joint to the Background, assume the center of the body
            b1 = self.parent.world.GetGroundBody()
            b2 = args[0]
            p1 = b2.GetWorldCenter()

            jointDef = box2d.b2RevoluteJointDef()
            jointDef.Initialize(b1, b2, p1)

            self.parent.world.CreateJoint(jointDef)
Esempio n. 11
0
def ComputeCentroid(pd):
    count = pd.vertexCount

    if count < 3:
        return False

    c = box2d.b2Vec2(0, 0)
    area = 0.0

    # pRef is the reference point for forming triangles.
    # It's location doesn't change the result (except for rounding error).
    pRef = box2d.b2Vec2(0.0, 0.0)

    inv3 = 1.0 / 3.0

    for i in range(count):
        # Triangle vertices.
        p1 = pRef
        p2 = pd.getVertex(i)
        if i + 1 < count:
            p3 = pd.getVertex(i + 1)
        else:
            p3 = pd.getVertex(0)

        e1 = p2 - p1
        e2 = p3 - p1

        D = box2d.b2Cross(e1, e2)

        triangleArea = 0.5 * D
        area += triangleArea

        # Area weighted centroid
        c += triangleArea * inv3 * (p1 + p2 + p3)

    # Centroid
    #   if area < FLT_EPSILON:
    # raise ValueError, "ComputeCentroid: area < FLT_EPSILON"

    return c / area
Esempio n. 12
0
def ComputeCentroid(pd):
    count = pd.vertexCount

    if count < 3:
        return False

    c = box2d.b2Vec2(0, 0)
    area = 0.0

    # pRef is the reference point for forming triangles.
    # It's location doesn't change the result (except for rounding error).
    pRef = box2d.b2Vec2(0.0, 0.0)

    inv3 = 1.0 / 3.0

    for i in range(count):
        # Triangle vertices.
        p1 = pRef
        p2 = pd.getVertex(i)
        if i + 1 < count:
            p3 = pd.getVertex(i + 1)
        else:
            p3 = pd.getVertex(0)

        e1 = p2 - p1
        e2 = p3 - p1

        D = box2d.b2Cross(e1, e2)

        triangleArea = 0.5 * D
        area += triangleArea

        # Area weighted centroid
        c += triangleArea * inv3 * (p1 + p2 + p3)

# Centroid
#   if area < FLT_EPSILON:
#raise ValueError, "ComputeCentroid: area < FLT_EPSILON"

    return c / area
Esempio n. 13
0
    def mouseJoint(self, body, pos):
        pos = self.parent.to_world(pos)
        x, y = pos
        x /= self.parent.ppm
        y /= self.parent.ppm

        mj = box2d.b2MouseJointDef()
        mj.body1 = self.parent.world.GetGroundBody()
        mj.body2 = body
        mj.target = box2d.b2Vec2(x, y)
        mj.maxForce = 100.0 * body.GetMass() # give humans POWER!
        self.parent.mouseJoint = self.parent.world.CreateJoint(mj).getAsType()
        body.WakeUp()
Esempio n. 14
0
    def mouseJoint(self, body, pos):
        pos = self.parent.to_world(pos)
        x, y = pos
        x /= self.parent.ppm
        y /= self.parent.ppm

        mj = box2d.b2MouseJointDef()
        mj.body1 = self.parent.world.GetGroundBody()
        mj.body2 = body
        mj.target = box2d.b2Vec2(x, y)
        mj.maxForce = 100.0 * body.GetMass()  # give humans POWER!
        self.parent.mouseJoint = self.parent.world.CreateJoint(mj).getAsType()
        body.WakeUp()
Esempio n. 15
0
    def _rect(self,
              pos,
              width,
              height,
              angle=0,
              dynamic=True,
              density=1.0,
              restitution=0.16,
              friction=0.5):
        # Add a rect without correcting any settings
        # meaning, pos and vertices are in meters
        # angle is now in radians ((degrees * pi) / 180))
        x, y = pos
        bodyDef = box2d.b2BodyDef()
        bodyDef.position.Set(x, y)

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

        # Create the Body
        if not dynamic:
            density = 0

        bodyDef.sleepFlag = True

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

        self.parent.element_count += 1

        # Add a shape to the Body
        boxDef = box2d.b2PolygonDef()

        boxDef.SetAsBox(width, height, box2d.b2Vec2(0, 0), angle)
        boxDef.density = density
        boxDef.restitution = restitution
        boxDef.friction = friction
        body.CreateShape(boxDef)

        body.SetMassFromShapes()

        return body
Esempio n. 16
0
    def _poly(self,
              pos,
              vertices,
              dynamic=True,
              density=1.0,
              restitution=0.16,
              friction=0.5):
        # add a centered poly at pos without correcting any settings
        # meaning, pos and vertices are in meters
        x, y = pos
        bodyDef = box2d.b2BodyDef()
        bodyDef.position.Set(x, y)
        bodyDef.sleepFlag = True

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

        # Create the Body
        if not dynamic:
            density = 0

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

        self.parent.element_count += 1

        # Add a shape to the Body
        polyDef = box2d.b2PolygonDef()
        polyDef.vertexCount = len(vertices)
        for i in range(len(vertices)):
            vx, vy = vertices[i]
            polyDef.setVertex(i, box2d.b2Vec2(vx, vy))

        polyDef.density = density
        polyDef.restitution = restitution
        polyDef.friction = friction

        body.CreateShape(polyDef)
        body.SetMassFromShapes()

        return body
Esempio n. 17
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
Esempio n. 18
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