World of Rigid Bodies (WoRB)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
CollisionResolver.h
Go to the documentation of this file.
00001 #ifndef _WORB_COLLISION_RESOLVER_H_INCLUDED
00002 #define _WORB_COLLISION_RESOLVER_H_INCLUDED
00003 
00004 /**
00005  *  @file      CollisionResolver.h
00006  *  @brief     Definitions for the CollisionResolver class which implements
00007  *             collision response algorithms for the system of rigid bodies.
00008  *  @author    Mikica Kocic
00009  *  @version   0.16
00010  *  @date      2012-05-02
00011  *  @copyright GNU Public License.
00012  */
00013 
00014 #include "Geometry.h"
00015 #include "Collision.h"
00016 
00017 namespace WoRB 
00018 {
00019     /** Encapsulates collision response framework.
00020      *
00021      * All collisions in the system, after detection, are registered in an
00022      * instance of the CollisionResolver class and then resolved using 
00023      * the impulse transfer and the position projections methods.
00024      *
00025      * The CollisionResolver instance may be shared between different WoRB systems.
00026      */
00027     class CollisionResolver
00028     {
00029         /////////////////////////////////////////////////////////////////////////////////
00030         /** @name Private properties                                                   */
00031                                                                                    /*@{*/
00032         /** Holds the maximum number of collisions the array can take.
00033          */
00034         unsigned MaxCollisionCount;
00035 
00036         /** Holds the parcel for the collision data.
00037          * Allocation of the parcel is left to the user (may be dynamic or static).
00038          */
00039         Collision* Collisions;
00040 
00041         /** Holds the next free place in the parcel.
00042          */
00043         Collision* NextFree;
00044 
00045         /** Holds the free space in allocation area.
00046          */
00047         unsigned FreeCount;
00048 
00049         /** Holds the current number of collisions found.
00050          */
00051         unsigned CollisionCount;
00052 
00053     public:
00054                                                                                    /*@}*/
00055         /////////////////////////////////////////////////////////////////////////////////
00056         /** @name Public properties                                                    */
00057                                                                                    /*@{*/
00058         /** Holds the restitution coefficient common for all collisions.
00059          */
00060         double Restitution;
00061 
00062         /** Holds the position projections coefficient common for all collisions.
00063          */
00064         double Relaxation;
00065 
00066         /** Holds the friction coefficient common for all collisions.
00067          */
00068         double Friction;
00069                                                                                    /*@}*/
00070         /////////////////////////////////////////////////////////////////////////////////
00071         /** @name Constructor                                                          */
00072                                                                                    /*@{*/
00073         /** Instantiates a collision detection framework in the given area.
00074          */
00075         CollisionResolver( Collision* allocationArea, unsigned length )
00076             : MaxCollisionCount( length )
00077             , Collisions( allocationArea )
00078             , NextFree( allocationArea )
00079             , FreeCount( length )
00080             , CollisionCount( 0 )
00081             , Restitution( 1.0 )
00082             , Relaxation( 0.2 )
00083             , Friction( 0.0 )
00084         {
00085         }
00086                                                                                    /*@}*/
00087         /////////////////////////////////////////////////////////////////////////////////
00088         /** @name Property getters and index operations                                */
00089                                                                                    /*@{*/
00090         /** Gets number of contats in the registry.
00091          */
00092         unsigned Count () const
00093         {
00094             return CollisionCount;
00095         }
00096 
00097         /** Checks if there is a free space available for more contact data.
00098          */
00099         bool HasSpaceForMoreContacts () const
00100         {
00101             return FreeCount > 0;
00102         }
00103 
00104         /** Gets collision data with the specified index.
00105          */
00106         const Collision& operator [] ( unsigned index ) const
00107         {
00108             return Collisions[ index ];
00109         }
00110                                                                                    /*@}*/
00111         /////////////////////////////////////////////////////////////////////////////////
00112         /** @name Collision detection methods                                          */
00113                                                                                    /*@{*/
00114         /** Clears the collision registry.
00115          */
00116         void Initialize ()
00117         {
00118             NextFree = Collisions;
00119             FreeCount = MaxCollisionCount;
00120             CollisionCount = 0;
00121         }
00122 
00123         /** Registers a new contact.
00124          * @return 1 if ok, 0 if failed to allocate space for the contact.
00125          */
00126         unsigned RegisterNewContact
00127         (
00128             RigidBody* body_A,           //!< The first body
00129             RigidBody* body_B,           //!< The second body; 0 in case of scenery
00130             const Quaternion& position,  //!< The position of the contact in world frame
00131             const Quaternion& normal,    //!< The contact normal in world frame
00132             double penetration           //!< The penetration depth
00133             )
00134         {
00135             if ( FreeCount <= 0 ) {
00136                 return 0;
00137             }
00138 
00139             // Add contact the list of maintained collisions.
00140             //
00141             NextFree->Body_A        = body_A;
00142             NextFree->Body_B        = body_B;
00143             NextFree->Position      = position;
00144             NextFree->Normal        = normal;
00145             NextFree->Penetration   = penetration;
00146             NextFree->Friction      = Friction;
00147             NextFree->Restitution   = Restitution;
00148 
00149             // Reduce the number of remainging contacts and advance the array forward.
00150             //
00151             ++NextFree; --FreeCount;
00152             ++CollisionCount;
00153 
00154             return 1;
00155         }
00156 
00157         /** Updates drived quantities (like contact velocity and axis info).
00158          */
00159         void UpdateDerivedQuantities( double timeStep )
00160         {
00161             for ( unsigned i = 0; i < CollisionCount; ++i )
00162             {
00163                 Collisions[i].UpdateDerivedQuantities( timeStep );
00164             }
00165         }
00166                                                                                    /*@}*/
00167         /////////////////////////////////////////////////////////////////////////////////
00168         /** @name Collision response methods                                           */
00169                                                                                    /*@{*/
00170         /** Resolves collisions using the impulse transfer method.
00171          */
00172         void ImpulseTransfers( double timeStep, 
00173             unsigned maxIterations = 0, double velocityEPS = 0.01 );
00174 
00175         /** Resolves collisions using the position projection method.
00176          */
00177         void PositionProjections(
00178             unsigned maxIterations = 0, double positionEPS = 0.01 );
00179                                                                                    /*@}*/
00180         /////////////////////////////////////////////////////////////////////////////////
00181         /** @name Miscellanous methods                                                 */
00182                                                                                    /*@{*/
00183         /** Displays information about all registered collisions on standard output.
00184          */
00185         public: void Dump( double currentTime ) const;
00186 
00187         /** Find a collision with the maximum bouncing velocity.
00188          */
00189         Collision* FindLargestBouncingVelocity( double eps )
00190         {
00191             Collision* contact = 0;
00192             for ( unsigned i = 0; i < CollisionCount; i++ )
00193             {
00194                 if ( Collisions[i].BouncingVelocity > eps )
00195                 {
00196                     eps = Collisions[i].BouncingVelocity;
00197                     contact = &Collisions[i];
00198                 }
00199             }
00200             return contact;
00201         }
00202 
00203         /** Finds a collision with the largest penetration.
00204          */
00205         Collision* FindLargestPenetration( double eps )
00206         {
00207             Collision* contact = 0;
00208             for ( unsigned i = 0; i < CollisionCount; ++i )
00209             {
00210                 if ( Collisions[i].Penetration > eps )
00211                 {
00212                     eps = Collisions[i].Penetration;
00213                     contact = &Collisions[i];
00214                 }
00215             }
00216             return contact;
00217         }
00218                                                                                    /*@}*/
00219         /////////////////////////////////////////////////////////////////////////////////
00220     };
00221 
00222 } // namespace WoRB
00223 
00224 #endif // _WORB_COLLISION_RESOLVER_H_INCLUDED