<commit_before>__docformat__ = "reStructuredText"

from weakref import WeakSet
import copy
    
from . import _chipmunk_cffi
cp = _chipmunk_cffi.lib
ffi = _chipmunk_cffi.ffi    
from .vec2d import Vec2d
from .arbiter import Arbiter
from ._pickle import PickleMixin

class Body(PickleMixin, object):
    """A rigid body

    * Use forces to modify the rigid bodies if possible. This is likely to be
      the most stable.
    * Modifying a body's velocity shouldn't necessarily be avoided, but
      applying large changes can cause strange results in the simulation.
      Experiment freely, but be warned.
    * Don't modify a body's position every step unless you really know what
      you are doing. Otherwise you're likely to get the position/velocity badly
      out of sync.

    A Body can be copied and pickled. Sleeping bodies that are copied will be 
    awake in the fresh copy. When a Body is copied any spaces, shapes or 
    constraints attached to the body will not be copied.
    """

    DYNAMIC = cp.CP_BODY_TYPE_DYNAMIC
    """Dynamic bodies are the default body type.

    They react to collisions,
    are affected by forces and gravity, and have a finite amount of mass.
    These are the type of bodies that you want the physics engine to
    simulate for you. Dynamic bodies interact with all types of bodies
    and can generate collision callbacks.
    """

    KINEMATIC = cp.CP_BODY_TYPE_KINEMATIC
    """Kinematic bodies are bodies that are controlled from your code
    instead of inside the physics engine.

    They arent affected by gravity and they have an infinite amount of mass
    so they don't react to collisions or forces with other bodies. Kinematic
    bodies are controlled by setting their velocity, which will cause them
    to move. Good examples of kinematic bodies might include things like
    moving platforms. Objects that are touching or jointed to a kinematic
    body are never allowed to fall asleep.
    """

    STATIC = cp.CP_BODY_TYPE_STATIC
    """Static bodies are bodies that never (or rarely) move.

    Using static bodies for things like terrain offers a big performance
    boost over other body types- because Chipmunk doesn't need to check for
    collisions between static objects and it never needs to update their
    collision information. Additionally, because static bodies don't
    move, Chipmunk knows it's safe to let objects that are touching or
    jointed to them fall asleep. Generally all of your level geometry
    will be attached to a static body except for things like moving
    platforms or doors. Every space provide a built-in static body for
    your convenience. Static bodies can be moved, but there is a
    performance penalty as the collision information is recalculated.
    There is no penalty for having multiple static bodies, and it can be
    useful for simplifying your code by allowing different parts of your
    static geometry to be initialized or moved separately.
    """

    _pickle_attrs_init = ['mass', 'moment', 'body_type']
    _pickle_attrs_general = ['force', 'angle', 'position', 'center_of_gravity', 
        'velocity',  'angular_velocity', 'torque']
    _pickle_attrs_skip = ['is_sleeping', '_velocity_func', '_position_func']

    def __init__(self, mass=0, moment=0, body_type=DYNAMIC):
        """Create a new Body

        Mass and moment are ignored when body_type is KINEMATIC or STATIC.

        Guessing the mass for a body is usually fine, but guessing a moment
        of inertia can lead to a very poor simulation so it's recommended to
        use Chipmunk's moment calculations to estimate the moment for you.

        There are two ways to set up a dynamic body. The easiest option is to
        create a body with a mass and moment of 0, and set the mass or
        density of each collision shape added to the body. Chipmunk will
        automatically calculate the mass, moment of inertia, and center of
        gravity for you. This is probably preferred in most cases. Note that 
        these will only be correctly calculated after the body and shape are 
        added to a space.

        The other option is to set the mass of the body when it's created,
        and leave the mass of the shapes added to it as 0.0. This approach is
        more flexible, but is not as easy to use. Don't set the mass of both
        the body and the shapes. If you do so, it will recalculate and
        overwrite your custom mass value when the shapes are added to the body.

        Examples of the different ways to set up the mass and moment:

        >>> import pymunk
        >>> radius = 2
        >>> mass = 3
        >>> density = 3
        >>> def print_mass_moment(b): 
        ...    print("mass={:.0f} moment={:.0f}".format(b.mass, b.moment))
        
        >>> # Using Shape.density
        >>> s = pymunk.Space()
        >>> b = pymunk.Body()
        >>> c = pymunk.Circle(b, radius)
        >>> c.density = density
        >>> print_mass_moment(b)
        mass=0 moment=0
        >>> s.add(b, c)
        >>> print_mass_moment(b)
        mass=38 moment=75

        >>> # Using Shape.mass
        >>> b = pymunk.Body()
        >>> c = pymunk.Circle(b, radius)
        >>> c.mass = mass
        >>> print_mass_moment(b)
        mass=0 moment=0
        >>> s.add(b, c)
        >>> print_mass_moment(b)
        mass=3 moment=6

        >>> # Using Body constructor
        >>> moment = pymunk.moment_for_circle(mass, 0, radius)
        >>> b = pymunk.Body()
        >>> c = pymunk.Circle(b, radius)
        >>> c.mass = mass
        >>> print_mass_moment(b)
        mass=0 moment=0
        >>> s.add(b, c)
        >>> print_mass_moment(b)
        mass=3 moment=6

        It becomes even more useful to use the mass or density properties of 
        the shape when you attach multiple shapes to one body, like in this 
        example with density:

        >>> # Using multiple Shape.density
        >>> b = pymunk.Body()
        >>> c1 = pymunk.Circle(b, radius, offset=(10,0))
        >>> c1.density = density
        >>> c2 = pymunk.Circle(b, radius, offset=(0,10))
        >>> c2.density = density
        >>> s.add(b, c1, c2)
        >>> print_mass_moment(b)
        mass=75 moment=3920

        """
        if body_type == Body.DYNAMIC:
            self._body = ffi.gc(cp.cpBodyNew(mass, moment), cp.cpBodyFree)
        elif body_type == Body.KINEMATIC:
            self._body = ffi.gc(cp.cpBodyNewKinematic(), cp.cpBodyFree)
        elif body_type == Body.STATIC:
            self._body = ffi.gc(cp.cpBodyNewStatic(), cp.cpBodyFree)

        self._init()

    def _init(self):
        self._position_func = None # To prevent the gc to collect the callbacks.
        self._velocity_func = None # To prevent the gc to collect the callbacks.
        self._position_func_base = None # For pickle
        self._velocity_func_base = None # For pickle

        self._space = None # Weak ref to the space holding this body (if any)<commit_msg>fix failing doctest for body<commit_after>__docformat__ = "reStructuredText"

from weakref import WeakSet
import copy
    
from . import _chipmunk_cffi
cp = _chipmunk_cffi.lib
ffi = _chipmunk_cffi.ffi    
from .vec2d import Vec2d
from .arbiter import Arbiter
from ._pickle import PickleMixin

class Body(PickleMixin, object):
    """A rigid body

    * Use forces to modify the rigid bodies if possible. This is likely to be
      the most stable.
    * Modifying a body's velocity shouldn't necessarily be avoided, but
      applying large changes can cause strange results in the simulation.
      Experiment freely, but be warned.
    * Don't modify a body's position every step unless you really know what
      you are doing. Otherwise you're likely to get the position/velocity badly
      out of sync.

    A Body can be copied and pickled. Sleeping bodies that are copied will be 
    awake in the fresh copy. When a Body is copied any spaces, shapes or 
    constraints attached to the body will not be copied.
    """

    DYNAMIC = cp.CP_BODY_TYPE_DYNAMIC
    """Dynamic bodies are the default body type.

    They react to collisions,
    are affected by forces and gravity, and have a finite amount of mass.
    These are the type of bodies that you want the physics engine to
    simulate for you. Dynamic bodies interact with all types of bodies
    and can generate collision callbacks.
    """

    KINEMATIC = cp.CP_BODY_TYPE_KINEMATIC
    """Kinematic bodies are bodies that are controlled from your code
    instead of inside the physics engine.

    They arent affected by gravity and they have an infinite amount of mass
    so they don't react to collisions or forces with other bodies. Kinematic
    bodies are controlled by setting their velocity, which will cause them
    to move. Good examples of kinematic bodies might include things like
    moving platforms. Objects that are touching or jointed to a kinematic
    body are never allowed to fall asleep.
    """

    STATIC = cp.CP_BODY_TYPE_STATIC
    """Static bodies are bodies that never (or rarely) move.

    Using static bodies for things like terrain offers a big performance
    boost over other body types- because Chipmunk doesn't need to check for
    collisions between static objects and it never needs to update their
    collision information. Additionally, because static bodies don't
    move, Chipmunk knows it's safe to let objects that are touching or
    jointed to them fall asleep. Generally all of your level geometry
    will be attached to a static body except for things like moving
    platforms or doors. Every space provide a built-in static body for
    your convenience. Static bodies can be moved, but there is a
    performance penalty as the collision information is recalculated.
    There is no penalty for having multiple static bodies, and it can be
    useful for simplifying your code by allowing different parts of your
    static geometry to be initialized or moved separately.
    """

    _pickle_attrs_init = ['mass', 'moment', 'body_type']
    _pickle_attrs_general = ['force', 'angle', 'position', 'center_of_gravity', 
        'velocity',  'angular_velocity', 'torque']
    _pickle_attrs_skip = ['is_sleeping', '_velocity_func', '_position_func']

    def __init__(self, mass=0, moment=0, body_type=DYNAMIC):
        """Create a new Body

        Mass and moment are ignored when body_type is KINEMATIC or STATIC.

        Guessing the mass for a body is usually fine, but guessing a moment
        of inertia can lead to a very poor simulation so it's recommended to
        use Chipmunk's moment calculations to estimate the moment for you.

        There are two ways to set up a dynamic body. The easiest option is to
        create a body with a mass and moment of 0, and set the mass or
        density of each collision shape added to the body. Chipmunk will
        automatically calculate the mass, moment of inertia, and center of
        gravity for you. This is probably preferred in most cases. Note that 
        these will only be correctly calculated after the body and shape are 
        added to a space.

        The other option is to set the mass of the body when it's created,
        and leave the mass of the shapes added to it as 0.0. This approach is
        more flexible, but is not as easy to use. Don't set the mass of both
        the body and the shapes. If you do so, it will recalculate and
        overwrite your custom mass value when the shapes are added to the body.

        Examples of the different ways to set up the mass and moment:

        >>> import pymunk
        >>> radius = 2
        >>> mass = 3
        >>> density = 3
        >>> def print_mass_moment(b): 
        ...    print("mass={:.0f} moment={:.0f}".format(b.mass, b.moment))
        
        >>> # Using Shape.density
        >>> s = pymunk.Space()
        >>> b = pymunk.Body()
        >>> c = pymunk.Circle(b, radius)
        >>> c.density = density
        >>> print_mass_moment(b)
        mass=0 moment=0
        >>> s.add(b, c)
        >>> print_mass_moment(b)
        mass=38 moment=75

        >>> # Using Shape.mass
        >>> b = pymunk.Body()
        >>> c = pymunk.Circle(b, radius)
        >>> c.mass = mass
        >>> print_mass_moment(b)
        mass=0 moment=0
        >>> s.add(b, c)
        >>> print_mass_moment(b)
        mass=3 moment=6

        >>> # Using Body constructor
        >>> moment = pymunk.moment_for_circle(mass, 0, radius)
        >>> b = pymunk.Body()
        >>> c = pymunk.Circle(b, radius)
        >>> c.mass = mass
        >>> print_mass_moment(b)
        mass=0 moment=0
        >>> s.add(b, c)
        >>> print_mass_moment(b)
        mass=3 moment=6

        It becomes even more useful to use the mass or density properties of 
        the shape when you attach multiple shapes to one body, like in this 
        example with density:

        >>> # Using multiple Shape.density
        >>> b = pymunk.Body()
        >>> c1 = pymunk.Circle(b, radius, offset=(10,0))
        >>> c1.density = density
        >>> c2 = pymunk.Circle(b, radius, offset=(0,10))
        >>> c2.density = density
        >>> s.add(b, c1, c2)
        >>> print_mass_moment(b)
        mass=75 moment=3921

        """
        if body_type == Body.DYNAMIC:
            self._body = ffi.gc(cp.cpBodyNew(mass, moment), cp.cpBodyFree)
        elif body_type == Body.KINEMATIC:
            self._body = ffi.gc(cp.cpBodyNewKinematic(), cp.cpBodyFree)
        elif body_type == Body.STATIC:
            self._body = ffi.gc(cp.cpBodyNewStatic(), cp.cpBodyFree)

        self._init()

    def _init(self):
        self._position_func = None # To prevent the gc to collect the callbacks.
        self._velocity_func = None # To prevent the gc to collect the callbacks.
        self._position_func_base = None # For pickle
        self._velocity_func_base = None # For pickle

        self._space = None # Weak ref to the space holding this body (if any)
{'fraction_non_alphanumeric': 0.07346530408061173, 'fraction_numerical': 0.006431787322232545, 'mean_word_length': 2.5726321164156243, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 219, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2431548', 'n_tokens_mistral': 3981, 'n_tokens_neox': 3782, 'n_words': 1687}