Karana.Collision
================

.. py:module:: Karana.Collision

.. autoapi-nested-parse::

   Models and classes for collision detection and contact force calculation.



Submodules
----------

.. toctree::
   :maxdepth: 1

   /generated/python_api/Karana/Collision/Collision_types/index


Classes
-------

.. autoapisummary::

   Karana.Collision.ContactForceBase
   Karana.Collision.ContactForceManager
   Karana.Collision.FrameCollider
   Karana.Collision.FrameContact
   Karana.Collision.HuntCrossley
   Karana.Collision.HuntCrossleyParams
   Karana.Collision.HuntCrossleyScratch


Package Contents
----------------

.. py:class:: ContactForceBase

   Bases: :py:obj:`Karana.Core.Base`


   .. py:method:: applyForce(contact: FrameContact, st: Karana.Dynamics.SubTree) -> tuple[Karana.Dynamics.Node, Karana.Dynamics.Node]

      Apply the contact force for the associated contact.

      This first calls computeForce to get the contact force. Then, it
      applies it to frames if those frames belong to a body.

      :param contact: The contact to apply the force for.
      :param st: The SubTree we are computing forces for.

      :returns: A pair of contact force nodes at which we applied the force.



   .. py:method:: toDS() -> Karana.Collision.Collision_types.ContactForceBaseDS

      Create a ContactForceBaseDS from this ContactForceBase model.

      :returns: * *ContactForceBaseDS*
                * *A ContactForceBaseDS instance with values set to match this model.*



.. py:class:: ContactForceManager(name: str)

   Bases: :py:obj:`ContactForceBase`


   .. py:method:: create(name: str) -> ContactForceManager
      :staticmethod:


      Create an instance of ContactForceManager.

      :param name: The name for the ContactForceManager instance.

      :returns: A ks_ptr to the newly created ContactForceManager.



   .. py:method:: clearDelegates() -> None

      Clear out all registered ContactForceBase instances



   .. py:method:: getDelegate(contact: FrameContact) -> ContactForceBase
                  getDelegate() -> ContactForceBase
                  getDelegate(frame1: Karana.Frame.Frame, frame2: Karana.Frame.Frame, strict: bool = False) -> ContactForceBase

      Get the most specific matching ContactForceBase

      :param contact: The contact to get the delegate for.

      :returns: The ContactForceBase (may be nullptr)



   .. py:method:: setDelegate(force: ContactForceBase = None) -> None
                  setDelegate(frame1: Karana.Frame.Frame, frame2: Karana.Frame.Frame, force: ContactForceBase = None) -> None

      Set the ContactForceBase used by default

      :param force: The ContactForceBase (may be nullptr)



.. py:class:: FrameCollider(proxy_scene: Karana.Scene.ProxyScene, collision_scene: Karana.Scene.CollisionScene)

   .. py:method:: clearIgnoredFramePairs() -> None

      Stop ignoring any frame-pair collisions



   .. py:method:: collide(col_func: collections.abc.Callable[[FrameContact], None], filter_func: collections.abc.Callable[[Karana.Scene.CollisionScenePart, Karana.Scene.CollisionScenePart], bool] = None) -> None

      Process all collisions

      Sweeps through all contacts between geometries attached to Frames,
      calling the collision handler for each unfiltered contact.

      :param collision_handler:
                                - Callback to handle a contact
      :param filter:
                     - Callback to skip potential collisions in the broadphase.



   .. py:method:: dump(prefix: str = '') -> None

      Print dumpString on std::cout.

      :param prefix: A string to use as prefix for each output line



   .. py:method:: dumpString(prefix: str = '') -> str

      Return information about the object.

      :param prefix: A string to use as prefix for each output line

      :returns: String with the information about the object.



   .. py:method:: getCollisionScene() -> Karana.Scene.CollisionScene

      Return the CollisionScene used by this FrameCollider.

      :returns: The CollisionScene used by this FrameCollider.



   .. py:method:: getProxyScene() -> Karana.Scene.ProxyScene

      Return the ProxyScene used by this FrameCollider.

      :returns: The ProxyScene used by this FrameCollider.



   .. py:method:: ignoreAllCurrentlyTouchingPairs() -> None

      Call ignoreFramePair for each pair with a collision



   .. py:method:: ignoreFramePair(frame1: Karana.Frame.Frame, frame2: Karana.Frame.Frame) -> None

      Ignore collisions between a pair of frames
      :param frame1: The first frame in the pair
      :param frame2: The second frame in the pair



   .. py:method:: lookupPartFrame(part: Karana.Scene.CollisionScenePart) -> Karana.Frame.Frame
                  lookupPartFrame(id: SupportsInt | SupportsIndex) -> Karana.Frame.Frame

      Get the Frame that a CollisionScenePart is attached to
      :param part:
                   - A CollisionScenePart managed by ProxyScene

      :returns: The ancestor Frame for the part.



   .. py:method:: toDS() -> Karana.Collision.Collision_types.FrameColliderDS

      Create a FrameColliderDS from this FrameCollider model.

      :returns: * *FrameColliderDS*
                * *A FrameColliderDS instance with values set to match this model.*



   .. py:method:: unignoreFramePair(frame1: Karana.Frame.Frame, frame2: Karana.Frame.Frame) -> None

      Stop ignoring collisions between a pair of frames
      :param frame1: The first frame in the pair
      :param frame2: The second frame in the pair



.. py:class:: FrameContact

   .. py:property:: frame_1
      :type: Karana.Frame.Frame


      The first Frame involved in the contact


   .. py:property:: frame_2
      :type: Karana.Frame.Frame


      The second Frame involved in the contact


   .. py:property:: location_1
      :type: Karana.Math.Ktyping.Length3


      Contact location on the first Frame relative to the first Frame and
      expressed in the first frame


   .. py:property:: location_2
      :type: Karana.Math.Ktyping.Length3


      Contact location on the second Frame relative to the second Frame and
      expressed in the second frame


   .. py:property:: normal_1
      :type: Annotated[numpy.typing.NDArray[numpy.float64], [3, 1]]


      Contact normal expressed first Frame


   .. py:property:: normal_2
      :type: Annotated[numpy.typing.NDArray[numpy.float64], [3, 1]]


      Contact normal expressed second Frame


   .. py:property:: penetration
      :type: Karana.Math.Ktyping.Length


      Maximum penetration distance


.. py:class:: HuntCrossley(name: str)

   Bases: :py:obj:`ContactForceBase`


   .. py:method:: create(name: str) -> HuntCrossley
      :staticmethod:


      Create an instance of the HuntCrossley contact force model.

      :param name: The name for the HuntCrossley instance.

      :returns: A ks_ptr to the newly created HuntCrossley contact force model.



   .. py:method:: toDS() -> Karana.Collision.Collision_types.HuntCrossleyDS

      Create a HuntCrossleyDS from this HuntCrossley model.

      :returns: * *HuntCrossleyDS*
                * *A HuntCrossleyDS instance with values set to match this model.*



   .. py:property:: params
      :type: HuntCrossleyParams


      Parameters used for the contact model.


   .. py:property:: scratch
      :type: HuntCrossleyScratch


      Scratch values


.. py:class:: HuntCrossleyParams

   .. py:property:: kc
      :type: float


      Normal penetration restitution/damping coefficient


   .. py:property:: kp
      :type: float


      Normal penetration stiffness coefficient


   .. py:property:: linear_region_tol
      :type: float


      Tolerance at which friction is linearly interpolated between the real
      value and 0.

      To avoid jittering for cases like rolling without friction, near zero,
      the friction force uses a linear interpolation between the full
      friction force and zero. This avoids rapid, large changes in the
      friction force as the velocity changes sign, and instead, smoothly,
      linearly interpolates between these large forces over a region of
      linear_region_tol * 2.


   .. py:property:: mu
      :type: float


      Friction coefficient


   .. py:property:: n
      :type: float


      Exponent


.. py:class:: HuntCrossleyScratch

   .. py:property:: f
      :type: Annotated[numpy.typing.NDArray[numpy.float64], [3, 1]]


      contact force


   .. py:property:: linvel
      :type: Annotated[numpy.typing.NDArray[numpy.float64], [3, 1]]


      contact linear velocity


   .. py:property:: penetration
      :type: float


      Normal penetration


